|
|
#include <string>
#include <iostream>
#include <regex>
#include <string>
#include <iostream>
#include <stdexcept>
#include <sstream>
#include <stdio.h> /* printf, NULL */
#include <stdlib.h>
#include <cassert>
#include "fr.h"
typedef void (*Func1)(PFrElement, PFrElement); typedef void (*Func2)(PFrElement, PFrElement, PFrElement); typedef void *FuncAny;
typedef struct { FuncAny fn; int nOps; } FunctionSpec;
std::map<std::string, FunctionSpec> functions; std::vector<FrElement> stack;
void addFunction(std::string name, FuncAny f, int nOps) { FunctionSpec fs; fs.fn = f; fs.nOps = nOps; functions[name] = fs; }
void fillMap() { addFunction("add", (FuncAny)Fr_add, 2); addFunction("sub", (FuncAny)Fr_sub, 2); addFunction("neg", (FuncAny)Fr_neg, 1); addFunction("mul", (FuncAny)Fr_mul, 2); addFunction("square", (FuncAny)Fr_square, 1); addFunction("idiv", (FuncAny)Fr_idiv, 2); addFunction("inv", (FuncAny)Fr_inv, 1); addFunction("div", (FuncAny)Fr_div, 2); addFunction("band", (FuncAny)Fr_band, 2); addFunction("bor", (FuncAny)Fr_bor, 2); addFunction("bxor", (FuncAny)Fr_bxor, 2); addFunction("bnot", (FuncAny)Fr_bnot, 1); addFunction("eq", (FuncAny)Fr_eq, 2); addFunction("neq", (FuncAny)Fr_neq, 2); addFunction("lt", (FuncAny)Fr_lt, 2); addFunction("gt", (FuncAny)Fr_gt, 2); addFunction("leq", (FuncAny)Fr_leq, 2); addFunction("geq", (FuncAny)Fr_geq, 2); addFunction("land", (FuncAny)Fr_land, 2); addFunction("lor", (FuncAny)Fr_lor, 2); addFunction("lnot", (FuncAny)Fr_lnot, 1); }
u_int64_t readInt(std::string &s) { if (s.rfind("0x", 0) == 0) { return std::stoull(s.substr(2), 0, 16); } else { return std::stoull(s, 0, 10); } }
void pushNumber(std::vector<std::string> &v) { u_int64_t a; if ((v.size()<1) || (v.size() > (Fr_N64+1))) { printf("Invalid Size: %d - %d \n", v.size(), Fr_N64); throw std::runtime_error("Invalid number of parameters for number"); } FrElement e; a = readInt(v[0]); *(u_int64_t *)(&e) = a; for (int i=0; i<Fr_N64; i++) { if (i+1 < v.size()) { a = readInt(v[i+1]); } else { a = 0; } e.longVal[i] = a; } stack.push_back(e); }
void callFunction(FunctionSpec fs) { if (stack.size() < fs.nOps) { throw new std::runtime_error("Not enough elements in stack"); } if (fs.nOps == 1) { FrElement a = stack.back(); stack.pop_back(); FrElement c; (*(Func1)fs.fn)(&c, &a); stack.push_back(c); } else if (fs.nOps == 2) { FrElement b = stack.back(); stack.pop_back(); FrElement a = stack.back(); stack.pop_back(); FrElement c; (*(Func2)fs.fn)(&c, &a, &b); stack.push_back(c); } else { assert(false); } }
void processLine(std::string &line) { std::regex re("(\\s*[,;]\\s*)|\\s+"); // whitespace
std::sregex_token_iterator begin( line.begin(), line.end(), re ,-1); std::sregex_token_iterator end; std::vector<std::string> tokens;
std::copy(begin, end, std::back_inserter(tokens));
// Remove initial empty tokens
while ((tokens.size() > 0)&&(tokens[0] == "")) { tokens.erase(tokens.begin()); }
// Empty lines are valid but are not processed
if (tokens.size() == 0) return;
auto search = functions.find(tokens[0]); if (search == functions.end()) { pushNumber(tokens); } else { if (tokens.size() != 1) { throw std::runtime_error("Functions does not accept parameters"); } callFunction(search->second); } }
int main(void) { fillMap(); std::string line; int i=0; while (std::getline(std::cin, line)) { processLine(line); // if (i%1000 == 0) printf("%d\n", i);
// printf("%d\n", i);
i++; } // Print the elements in the stack
//
for (int i=0; i<stack.size(); i++) { char *s; s = Fr_element2str(&stack[i]); printf("%s\n", s); free(s); } return EXIT_SUCCESS; }
/*
#include <stdlib.h>
#include <string.h>
#include "fr.h"
typedef void (*Func2)(PFrElement, PFrElement, PFrElement);
typedef struct { const char *fnName; Func2 fn; } FN;
#define NFN 2
FN fns[NFN] = { {"add", Fr_add}, {"mul", Fr_mul}, };
int main(int argc, char **argv) {
if (argc <= 1) { fprintf( stderr, "invalid number of parameters"); return 1; }
for (int i=0; i< NFN;i++) { if (strcmp(argv[1], fns[i].fnName) == 0) { if (argc != 4) { fprintf( stderr, "invalid number of parameters"); return 1; } FrElement a; FrElement b;
Fr_str2element(&a, argv[2]); Fr_str2element(&b, argv[3]); FrElement c; fns[i].fn(&c, &a, &b);
char *s; s = Fr_element2str(&c); printf("%s", s); free(s); return 0; } } fprintf( stderr, "invalid operation %s", argv[1]); return 1; }
*/
|