You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
5.1 KiB

  1. #include <string>
  2. #include <iostream>
  3. #include <regex>
  4. #include <string>
  5. #include <iostream>
  6. #include <stdexcept>
  7. #include <sstream>
  8. #include <stdio.h> /* printf, NULL */
  9. #include <stdlib.h>
  10. #include <cassert>
  11. #include "fr.h"
  12. typedef void (*Func1)(PFrElement, PFrElement);
  13. typedef void (*Func2)(PFrElement, PFrElement, PFrElement);
  14. typedef void *FuncAny;
  15. typedef struct {
  16. FuncAny fn;
  17. int nOps;
  18. } FunctionSpec;
  19. std::map<std::string, FunctionSpec> functions;
  20. std::vector<FrElement> stack;
  21. void addFunction(std::string name, FuncAny f, int nOps) {
  22. FunctionSpec fs;
  23. fs.fn = f;
  24. fs.nOps = nOps;
  25. functions[name] = fs;
  26. }
  27. void fillMap() {
  28. addFunction("add", (FuncAny)Fr_add, 2);
  29. addFunction("sub", (FuncAny)Fr_sub, 2);
  30. addFunction("neg", (FuncAny)Fr_neg, 1);
  31. addFunction("mul", (FuncAny)Fr_mul, 2);
  32. addFunction("square", (FuncAny)Fr_square, 1);
  33. addFunction("idiv", (FuncAny)Fr_idiv, 2);
  34. addFunction("inv", (FuncAny)Fr_inv, 1);
  35. addFunction("div", (FuncAny)Fr_div, 2);
  36. addFunction("band", (FuncAny)Fr_band, 2);
  37. addFunction("bor", (FuncAny)Fr_bor, 2);
  38. addFunction("bxor", (FuncAny)Fr_bxor, 2);
  39. addFunction("bnot", (FuncAny)Fr_bnot, 1);
  40. addFunction("eq", (FuncAny)Fr_eq, 2);
  41. addFunction("neq", (FuncAny)Fr_neq, 2);
  42. addFunction("lt", (FuncAny)Fr_lt, 2);
  43. addFunction("gt", (FuncAny)Fr_gt, 2);
  44. addFunction("leq", (FuncAny)Fr_leq, 2);
  45. addFunction("geq", (FuncAny)Fr_geq, 2);
  46. addFunction("land", (FuncAny)Fr_land, 2);
  47. addFunction("lor", (FuncAny)Fr_lor, 2);
  48. addFunction("lnot", (FuncAny)Fr_lnot, 1);
  49. }
  50. u_int64_t readInt(std::string &s) {
  51. if (s.rfind("0x", 0) == 0) {
  52. return std::stoull(s.substr(2), 0, 16);
  53. } else {
  54. return std::stoull(s, 0, 10);
  55. }
  56. }
  57. void pushNumber(std::vector<std::string> &v) {
  58. u_int64_t a;
  59. if ((v.size()<1) || (v.size() > (Fr_N64+1))) {
  60. printf("Invalid Size: %d - %d \n", v.size(), Fr_N64);
  61. throw std::runtime_error("Invalid number of parameters for number");
  62. }
  63. FrElement e;
  64. a = readInt(v[0]);
  65. *(u_int64_t *)(&e) = a;
  66. for (int i=0; i<Fr_N64; i++) {
  67. if (i+1 < v.size()) {
  68. a = readInt(v[i+1]);
  69. } else {
  70. a = 0;
  71. }
  72. e.longVal[i] = a;
  73. }
  74. stack.push_back(e);
  75. }
  76. void callFunction(FunctionSpec fs) {
  77. if (stack.size() < fs.nOps) {
  78. throw new std::runtime_error("Not enough elements in stack");
  79. }
  80. if (fs.nOps == 1) {
  81. FrElement a = stack.back();
  82. stack.pop_back();
  83. FrElement c;
  84. (*(Func1)fs.fn)(&c, &a);
  85. stack.push_back(c);
  86. } else if (fs.nOps == 2) {
  87. FrElement b = stack.back();
  88. stack.pop_back();
  89. FrElement a = stack.back();
  90. stack.pop_back();
  91. FrElement c;
  92. (*(Func2)fs.fn)(&c, &a, &b);
  93. stack.push_back(c);
  94. } else {
  95. assert(false);
  96. }
  97. }
  98. void processLine(std::string &line) {
  99. std::regex re("(\\s*[,;]\\s*)|\\s+"); // whitespace
  100. std::sregex_token_iterator begin( line.begin(), line.end(), re ,-1);
  101. std::sregex_token_iterator end;
  102. std::vector<std::string> tokens;
  103. std::copy(begin, end, std::back_inserter(tokens));
  104. // Remove initial empty tokens
  105. while ((tokens.size() > 0)&&(tokens[0] == "")) {
  106. tokens.erase(tokens.begin());
  107. }
  108. // Empty lines are valid but are not processed
  109. if (tokens.size() == 0) return;
  110. auto search = functions.find(tokens[0]);
  111. if (search == functions.end()) {
  112. pushNumber(tokens);
  113. } else {
  114. if (tokens.size() != 1) {
  115. throw std::runtime_error("Functions does not accept parameters");
  116. }
  117. callFunction(search->second);
  118. }
  119. }
  120. int main(void)
  121. {
  122. Fr_init();
  123. fillMap();
  124. std::string line;
  125. int i=0;
  126. while (std::getline(std::cin, line)) {
  127. processLine(line);
  128. // if (i%1000 == 0) printf("%d\n", i);
  129. // printf("%d\n", i);
  130. i++;
  131. }
  132. // Print the elements in the stack
  133. //
  134. for (int i=0; i<stack.size(); i++) {
  135. char *s;
  136. s = Fr_element2str(&stack[i]);
  137. printf("%s\n", s);
  138. free(s);
  139. }
  140. return EXIT_SUCCESS;
  141. }
  142. /*
  143. #include <stdlib.h>
  144. #include <string.h>
  145. #include "fr.h"
  146. typedef void (*Func2)(PFrElement, PFrElement, PFrElement);
  147. typedef struct {
  148. const char *fnName;
  149. Func2 fn;
  150. } FN;
  151. #define NFN 2
  152. FN fns[NFN] = {
  153. {"add", Fr_add},
  154. {"mul", Fr_mul},
  155. };
  156. int main(int argc, char **argv) {
  157. if (argc <= 1) {
  158. fprintf( stderr, "invalid number of parameters");
  159. return 1;
  160. }
  161. for (int i=0; i< NFN;i++) {
  162. if (strcmp(argv[1], fns[i].fnName) == 0) {
  163. if (argc != 4) {
  164. fprintf( stderr, "invalid number of parameters");
  165. return 1;
  166. }
  167. FrElement a;
  168. FrElement b;
  169. Fr_str2element(&a, argv[2]);
  170. Fr_str2element(&b, argv[3]);
  171. FrElement c;
  172. fns[i].fn(&c, &a, &b);
  173. char *s;
  174. s = Fr_element2str(&c);
  175. printf("%s", s);
  176. free(s);
  177. return 0;
  178. }
  179. }
  180. fprintf( stderr, "invalid operation %s", argv[1]);
  181. return 1;
  182. }
  183. */