参考

{% collapse title=”s_expressions.c” %}

  1. #include "mpc.h"
  2. #ifdef _WIN32
  3. static char buffer[2048];
  4. char* readline(char* prompt) {
  5. fputs(prompt, stdout);
  6. fgets(buffer, 2048, stdin);
  7. char* cpy = malloc(strlen(buffer)+1);
  8. strcpy(cpy, buffer);
  9. cpy[strlen(cpy)-1] = '\0';
  10. return cpy;
  11. }
  12. void add_history(char* unused) {}
  13. #else
  14. #include <editline/readline.h>
  15. #include <editline/history.h>
  16. #endif
  17. /* Add SYM and SEXPR as possible lval types */
  18. enum { LVAL_ERR, LVAL_NUM, LVAL_SYM, LVAL_SEXPR };
  19. typedef struct lval {
  20. int type;
  21. long num;
  22. /* Error and Symbol types have some string data */
  23. char* err;
  24. char* sym;
  25. /* Count and Pointer to a list of "lval*"; */
  26. int count;
  27. struct lval** cell;
  28. } lval;
  29. /* Construct a pointer to a new Number lval */
  30. lval* lval_num(long x) {
  31. lval* v = malloc(sizeof(lval));
  32. v->type = LVAL_NUM;
  33. v->num = x;
  34. return v;
  35. }
  36. /* Construct a pointer to a new Error lval */
  37. lval* lval_err(char* m) {
  38. lval* v = malloc(sizeof(lval));
  39. v->type = LVAL_ERR;
  40. v->err = malloc(strlen(m) + 1);
  41. strcpy(v->err, m);
  42. return v;
  43. }
  44. /* Construct a pointer to a new Symbol lval */
  45. lval* lval_sym(char* s) {
  46. lval* v = malloc(sizeof(lval));
  47. v->type = LVAL_SYM;
  48. v->sym = malloc(strlen(s) + 1);
  49. strcpy(v->sym, s);
  50. return v;
  51. }
  52. /* A pointer to a new empty Sexpr lval */
  53. lval* lval_sexpr(void) {
  54. lval* v = malloc(sizeof(lval));
  55. v->type = LVAL_SEXPR;
  56. v->count = 0;
  57. v->cell = NULL;
  58. return v;
  59. }
  60. void lval_del(lval* v) {
  61. switch (v->type) {
  62. /* Do nothing special for number type */
  63. case LVAL_NUM: break;
  64. /* For Err or Sym free the string data */
  65. case LVAL_ERR: free(v->err); break;
  66. case LVAL_SYM: free(v->sym); break;
  67. /* If Sexpr then delete all elements inside */
  68. case LVAL_SEXPR:
  69. for (int i = 0; i < v->count; i++) {
  70. lval_del(v->cell[i]);
  71. }
  72. /* Also free the memory allocated to contain the pointers */
  73. free(v->cell);
  74. break;
  75. }
  76. /* Free the memory allocated for the "lval" struct itself */
  77. free(v);
  78. }
  79. lval* lval_add(lval* v, lval* x) {
  80. v->count++;
  81. v->cell = realloc(v->cell, sizeof(lval*) * v->count);
  82. v->cell[v->count-1] = x;
  83. return v;
  84. }
  85. lval* lval_pop(lval* v, int i) {
  86. /* Find the item at "i" */
  87. lval* x = v->cell[i];
  88. /* Shift memory after the item at "i" over the top */
  89. memmove(&v->cell[i], &v->cell[i+1],
  90. sizeof(lval*) * (v->count-i-1));
  91. /* Decrease the count of items in the list */
  92. v->count--;
  93. /* Reallocate the memory used */
  94. v->cell = realloc(v->cell, sizeof(lval*) * v->count);
  95. return x;
  96. }
  97. lval* lval_take(lval* v, int i) {
  98. lval* x = lval_pop(v, i);
  99. lval_del(v);
  100. return x;
  101. }
  102. void lval_print(lval* v);
  103. void lval_expr_print(lval* v, char open, char close) {
  104. putchar(open);
  105. for (int i = 0; i < v->count; i++) {
  106. /* Print Value contained within */
  107. lval_print(v->cell[i]);
  108. /* Don't print trailing space if last element */
  109. if (i != (v->count-1)) {
  110. putchar(' ');
  111. }
  112. }
  113. putchar(close);
  114. }
  115. void lval_print(lval* v) {
  116. switch (v->type) {
  117. case LVAL_NUM: printf("%li", v->num); break;
  118. case LVAL_ERR: printf("Error: %s", v->err); break;
  119. case LVAL_SYM: printf("%s", v->sym); break;
  120. case LVAL_SEXPR: lval_expr_print(v, '(', ')'); break;
  121. }
  122. }
  123. void lval_println(lval* v) { lval_print(v); putchar('\n'); }
  124. lval* builtin_op(lval* a, char* op) {
  125. /* Ensure all arguments are numbers */
  126. for (int i = 0; i < a->count; i++) {
  127. if (a->cell[i]->type != LVAL_NUM) {
  128. lval_del(a);
  129. return lval_err("Cannot operate on non-number!");
  130. }
  131. }
  132. /* Pop the first element */
  133. lval* x = lval_pop(a, 0);
  134. /* If no arguments and sub then perform unary negation */
  135. if ((strcmp(op, "-") == 0) && a->count == 0) {
  136. x->num = -x->num;
  137. }
  138. /* While there are still elements remaining */
  139. while (a->count > 0) {
  140. /* Pop the next element */
  141. lval* y = lval_pop(a, 0);
  142. /* Perform operation */
  143. if (strcmp(op, "+") == 0) { x->num += y->num; }
  144. if (strcmp(op, "-") == 0) { x->num -= y->num; }
  145. if (strcmp(op, "*") == 0) { x->num *= y->num; }
  146. if (strcmp(op, "/") == 0) {
  147. if (y->num == 0) {
  148. lval_del(x); lval_del(y);
  149. x = lval_err("Division By Zero.");
  150. break;
  151. }
  152. x->num /= y->num;
  153. }
  154. /* Delete element now finished with */
  155. lval_del(y);
  156. }
  157. /* Delete input expression and return result */
  158. lval_del(a);
  159. return x;
  160. }
  161. lval* lval_eval(lval* v);
  162. lval* lval_eval_sexpr(lval* v) {
  163. /* Evaluate Children */
  164. for (int i = 0; i < v->count; i++) {
  165. v->cell[i] = lval_eval(v->cell[i]);
  166. }
  167. /* Error Checking */
  168. for (int i = 0; i < v->count; i++) {
  169. if (v->cell[i]->type == LVAL_ERR) { return lval_take(v, i); }
  170. }
  171. /* Empty Expression */
  172. if (v->count == 0) { return v; }
  173. /* Single Expression */
  174. if (v->count == 1) { return lval_take(v, 0); }
  175. /* Ensure First Element is Symbol */
  176. lval* f = lval_pop(v, 0);
  177. if (f->type != LVAL_SYM) {
  178. lval_del(f); lval_del(v);
  179. return lval_err("S-expression Does not start with symbol.");
  180. }
  181. /* Call builtin with operator */
  182. lval* result = builtin_op(v, f->sym);
  183. lval_del(f);
  184. return result;
  185. }
  186. lval* lval_eval(lval* v) {
  187. /* Evaluate Sexpressions */
  188. if (v->type == LVAL_SEXPR) { return lval_eval_sexpr(v); }
  189. /* All other lval types remain the same */
  190. return v;
  191. }
  192. lval* lval_read_num(mpc_ast_t* t) {
  193. errno = 0;
  194. long x = strtol(t->contents, NULL, 10);
  195. return errno != ERANGE ?
  196. lval_num(x) : lval_err("invalid number");
  197. }
  198. lval* lval_read(mpc_ast_t* t) {
  199. /* If Symbol or Number return conversion to that type */
  200. if (strstr(t->tag, "number")) { return lval_read_num(t); }
  201. if (strstr(t->tag, "symbol")) { return lval_sym(t->contents); }
  202. /* If root (>) or sexpr then create empty list */
  203. lval* x = NULL;
  204. if (strcmp(t->tag, ">") == 0) { x = lval_sexpr(); }
  205. if (strstr(t->tag, "sexpr")) { x = lval_sexpr(); }
  206. /* Fill this list with any valid expression contained within */
  207. for (int i = 0; i < t->children_num; i++) {
  208. if (strcmp(t->children[i]->contents, "(") == 0) { continue; }
  209. if (strcmp(t->children[i]->contents, ")") == 0) { continue; }
  210. if (strcmp(t->children[i]->contents, "}") == 0) { continue; }
  211. if (strcmp(t->children[i]->contents, "{") == 0) { continue; }
  212. if (strcmp(t->children[i]->tag, "regex") == 0) { continue; }
  213. x = lval_add(x, lval_read(t->children[i]));
  214. }
  215. return x;
  216. }
  217. int main(int argc, char** argv) {
  218. mpc_parser_t* Number = mpc_new("number");
  219. mpc_parser_t* Symbol = mpc_new("symbol");
  220. mpc_parser_t* Sexpr = mpc_new("sexpr");
  221. mpc_parser_t* Expr = mpc_new("expr");
  222. mpc_parser_t* Lispy = mpc_new("lispy");
  223. mpca_lang(MPCA_LANG_DEFAULT,
  224. " \
  225. number : /-?[0-9]+/ ; \
  226. symbol : '+' | '-' | '*' | '/' ; \
  227. sexpr : '(' <expr>* ')' ; \
  228. expr : <number> | <symbol> | <sexpr> ; \
  229. lispy : /^/ <expr>* /$/ ; \
  230. ",
  231. Number, Symbol, Sexpr, Expr, Lispy);
  232. puts("Lispy Version 0.0.0.0.5");
  233. puts("Press Ctrl+c to Exit\n");
  234. while (1) {
  235. char* input = readline("lispy> ");
  236. add_history(input);
  237. mpc_result_t r;
  238. if (mpc_parse("<stdin>", input, Lispy, &r)) {
  239. lval* x = lval_eval(lval_read(r.output));
  240. lval_println(x);
  241. lval_del(x);
  242. mpc_ast_delete(r.output);
  243. } else {
  244. mpc_err_print(r.error);
  245. mpc_err_delete(r.error);
  246. }
  247. free(input);
  248. }
  249. mpc_cleanup(5, Number, Symbol, Sexpr, Expr, Lispy);
  250. return 0;
  251. }

{% endcollapse %}