erpl.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. // TODO check internal functions considering the atoms admit tables now
  4. static unsigned interrupted = 0;
  5. #define ALLOC(s) alloc_mem(s)
  6. #define FREE(s) free_mem(s)
  7. typedef enum {
  8. NUM,
  9. SYMB,
  10. LIST,
  11. TABLE,
  12. LAMBDA
  13. } Type;
  14. typedef struct List {
  15. struct Atom *head;
  16. struct List *tail;
  17. } List;
  18. typedef struct Table {
  19. int *key;
  20. struct Atom *value;
  21. struct Table *next;
  22. } Table;
  23. typedef struct Atom {
  24. Type type;
  25. union {
  26. int num;
  27. int *symb;
  28. List *list;
  29. Table *table;
  30. };
  31. } Atom;
  32. typedef struct builtin_entry {
  33. int name[15];
  34. Atom *(*operation)(List*,Table**);
  35. } builtin_entry;
  36. // error and warning messages:
  37. #define EMPTY_STACK ": Empty stack"
  38. #define INSUFFICIENT_ARGS ": Insufficient arguments"
  39. #define INSUFFICIENT_ARGS_STK ": Insufficient arguments (stack)"
  40. #define INVALID_ARGS ": Invalid arguments"
  41. #define INVALID_ARGS_STK ": Invalid arguments (stack)"
  42. #define TOO_SHORT ": Too short"
  43. #define MUST_BE_INT ": Must be a integer"
  44. #define MUST_BE_SYM ": Must be a symbol"
  45. #define MUST_BE_LIST ": Must be a list"
  46. #define MUST_BE_SYMLIST ": Must be a symbol list"
  47. #define MUST_BE_TABLE ": Must be a table"
  48. #define MUST_BE_LAMBDA ": Must be a lambda"
  49. #define DUPLICATE_NULL ": Tried to duplicate a null"
  50. #define FREE_NULL ": Tried to free a null"
  51. #define EXTRA_PARENTHESIS ": Extra closing parenthesis"
  52. // basic input and output:
  53. int _getchar();
  54. Atom* _warning(char*);
  55. Atom* _error(char*);
  56. // printing:
  57. void print_symbol(int*);
  58. void print_expression(Atom*);
  59. // duplicating and freeing:
  60. Atom* duplicate_atom(Atom*);
  61. List* duplicate_list(List*);
  62. Table* duplicate_table(Table*);
  63. int* duplicate_symbol(int*);
  64. void free_atom(Atom*);
  65. void free_list(List*);
  66. void free_table(Table*);
  67. // creating objects:
  68. List* cons(Atom*, List*);
  69. Atom* create_atom(Type);
  70. Atom* create_int(int);
  71. Atom* create_symbol(int*);
  72. Atom* create_list(List*);
  73. Atom* create_lambda(List*);
  74. // stack manipulation:
  75. void stack_push(Atom*, List**);
  76. void stack_pop(int, List**);
  77. // type operations:
  78. int is_simple(Atom*);
  79. int is_list(Atom*);
  80. int is_symbol(Atom*);
  81. int valid_lambda(List*);
  82. unsigned is_symbol_list(List*);
  83. // parsing:
  84. int skip_whitespace();
  85. Atom* parse_list();
  86. Atom* parse_symbol(int);
  87. Atom* parse_int(int);
  88. Atom* parse();
  89. // table operations:
  90. unsigned symbols_are_equal(int*, int*);
  91. Table* table_lookup(Table*, int*);
  92. Table* table_set(Table**, int*, Atom*);
  93. void table_union(Table*, Table**);
  94. unsigned table_unset(Table**, int*);
  95. int table_size(Table*);
  96. // object comparation:
  97. unsigned equal(Atom*, Atom*);
  98. unsigned lists_are_equal(List*, List*);
  99. int list_size(List*);
  100. // expression evaluation:
  101. void* (builtin_lookup)(int*);
  102. Table* atom_lookup(int* name, Table* context);
  103. Atom* eval(Atom*, Table**);
  104. Atom* eval_symbol(int*, List*, Table**);
  105. Atom* eval_application(List*, Table**);
  106. Atom* eval_lambda(List*, List*, Table**);
  107. unsigned define_local_vars (List*, List*, Table**);
  108. void destroy_local_vars (List*, Table**);
  109. #define DECL_BUILTIN(x) \
  110. Atom* x (List*, Table**)
  111. #define BUILTIN(x) \
  112. Atom* x (List* li, Table** ctx)
  113. // TODO review language semantics as a whole
  114. // TODO add table instructions and adapt list instructions to include table semantics
  115. // builtin functions:
  116. // stack focused:
  117. DECL_BUILTIN(_dup); // dupplicates the stack top element
  118. DECL_BUILTIN(_drop); // excludes the stack top element
  119. DECL_BUILTIN(_clear); // clear the entire stack
  120. DECL_BUILTIN(_swap); // swap the 2 most recent stack elements
  121. DECL_BUILTIN(_over); // copies the 2nd most recent stack element to the top
  122. DECL_BUILTIN(_depth); // returns the number of elements at the stack
  123. DECL_BUILTIN(_pick); // copies an arbitrary stack element to the top, given its stack position
  124. // list/table focused:
  125. // NOTE symbols are casted to a list containing its characters as numbers
  126. // NOTE numbers are casted to a list by the list-creating functions
  127. // NOTE list/table indexing functions don't accept simple atoms as their first arguments
  128. DECL_BUILTIN(_head); // returns the first list/table element
  129. // (head (list 1 2 3)) -> 1
  130. // (head (table a 1 b 2 c 3)) -> 3
  131. DECL_BUILTIN(_tip); // returns the last list/table element
  132. // (tip (list 1 2 3)) -> 3
  133. // (tip (table a 1 b 2 c 3)) -> 3
  134. DECL_BUILTIN(_tail); // returns all but the first list/table element
  135. // (tail (list 1 2 3)) -> (list 2 3)
  136. // (tail (table a 1 b 2 c 3)) -> (table b 2 c 3)
  137. DECL_BUILTIN(_first); // returns a list/table containing the first list/table elements in the requested quantity
  138. // (first (list 1 2 3) 2) -> (list 1 2)
  139. // (first (table a 1 b 2 c 3) 2) -> (table a 1 b 2)
  140. DECL_BUILTIN(_last); // returns a list/table containing the last list/table elements in the requested quantity
  141. // (first (list 1 2 3) 2) -> (list 1 2)
  142. // (first (table a 1 b 2 c 3) 2) -> (table a 1 b 2)
  143. DECL_BUILTIN(_get); // gets a list/table element given its index (indexes counting from 1)
  144. // (get (list 1 2 3) 2) -> 2
  145. // (get (table a 1 b 2 c 3) b) -> 2
  146. DECL_BUILTIN(_put); // puts new elements at arbitrary positions in the list given its indexes
  147. // or adds new key/value pairs in a table
  148. // (put (list 1 2 3) 1 9 1 8) -> (list 8 9 1 2 3)
  149. // (put (table a 1 b 2 c 3) d 8 e 9) -> (table a 1 b 2 c 3 d 8 e 9)
  150. DECL_BUILTIN(_find); // finds elements positions/indexes in a list/table
  151. // (find (list 9 8 7 6 5) 4 8 7) -> (list 0 2 3)
  152. // (find (table a 9 b 8 c 7) 4 8 7) -> (list 0 b c)
  153. DECL_BUILTIN(_match); // matches sequences of sequentially elements at a list, returning its initial positions
  154. // (match (list 1 2 3 9 8 7) (list 9 8 7) (list 2 3 9)) -> (list 4 2)
  155. DECL_BUILTIN(_slice); // returns slices of a list, always requiring 2 indexes for each slice
  156. // (slice (list 1 2 3 9 8 7) 2 3 5 6) -> (list 2 3 8 7)
  157. DECL_BUILTIN(_concat); // concatenates lists
  158. // (concat (list 1 2 3) (list 9 8 7)) -> (list 1 2 3 9 8 7)
  159. DECL_BUILTIN(_append); // appends elements at the end of a list
  160. // (append (list 1) 2 3) -> (list 1 2 3)
  161. DECL_BUILTIN(_prepend); // appends elements at the start of a list
  162. // (prepend (list 1) 2 3) -> (list 2 3 1)
  163. // functional utilities:
  164. DECL_BUILTIN(_map); //
  165. DECL_BUILTIN(_apply); //
  166. DECL_BUILTIN(_reduce); //
  167. DECL_BUILTIN(_filter); //
  168. DECL_BUILTIN(_quote); //
  169. DECL_BUILTIN(_unquote); //
  170. // symbol utilities:
  171. DECL_BUILTIN(_hash);
  172. DECL_BUILTIN(_concat);
  173. DECL_BUILTIN(_split);
  174. // compound objects creation, or type coercion:
  175. DECL_BUILTIN(_list); // coerces a lambda or table to a list, creates a new list
  176. DECL_BUILTIN(_lambda); // coerces a list to a lambda, creates a new lambda
  177. DECL_BUILTIN(_table); // coerces a list to a table, creates a new table
  178. // basic numeric operations:
  179. DECL_BUILTIN(_sum); // "+"
  180. DECL_BUILTIN(_sub); // "-"
  181. DECL_BUILTIN(_mul); // "*"
  182. DECL_BUILTIN(_div); // "/"
  183. DECL_BUILTIN(_rem); // "%"
  184. DECL_BUILTIN(_power); // "^"
  185. // numeric comparisons:
  186. DECL_BUILTIN(_eq); // "="
  187. DECL_BUILTIN(_lt); // "<"
  188. DECL_BUILTIN(_le); // "<="
  189. DECL_BUILTIN(_gt); // ">"
  190. DECL_BUILTIN(_ge); // ">="
  191. // logic utilities:
  192. DECL_BUILTIN(_and);
  193. DECL_BUILTIN(_or);
  194. DECL_BUILTIN(_xor);
  195. DECL_BUILTIN(_not);
  196. // flow control:
  197. DECL_BUILTIN(_if);
  198. DECL_BUILTIN(_when);
  199. DECL_BUILTIN(_case);
  200. DECL_BUILTIN(_conds);
  201. DECL_BUILTIN(_for);
  202. DECL_BUILTIN(_while);
  203. DECL_BUILTIN(_recur);
  204. DECL_BUILTIN(_do);
  205. // generics:
  206. DECL_BUILTIN(_eval);
  207. DECL_BUILTIN(_print);
  208. DECL_BUILTIN(_equal);
  209. DECL_BUILTIN(_stack);
  210. DECL_BUILTIN(_help);
  211. DECL_BUILTIN(_catalog);
  212. // operational:
  213. DECL_BUILTIN(_user_error);
  214. DECL_BUILTIN(_user_warning);
  215. DECL_BUILTIN(_option);
  216. DECL_BUILTIN(_quit);
  217. DECL_BUILTIN(_trap);