123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- #include <stdio.h>
- #include <stdlib.h>
- // TODO check internal functions considering the atoms admit tables now
- static unsigned interrupted = 0;
- #define ALLOC(s) alloc_mem(s)
- #define FREE(s) free_mem(s)
- typedef enum {
- NUM,
- SYMB,
- LIST,
- TABLE,
- LAMBDA
- } Type;
- typedef struct List {
- struct Atom *head;
- struct List *tail;
- } List;
- typedef struct Table {
- int *key;
- struct Atom *value;
- struct Table *next;
- } Table;
- typedef struct Atom {
- Type type;
- union {
- int num;
- int *symb;
- List *list;
- Table *table;
- };
- } Atom;
- typedef struct builtin_entry {
- int name[15];
- Atom *(*operation)(List*,Table**);
- } builtin_entry;
- // error and warning messages:
- #define EMPTY_STACK ": Empty stack"
- #define INSUFFICIENT_ARGS ": Insufficient arguments"
- #define INSUFFICIENT_ARGS_STK ": Insufficient arguments (stack)"
- #define INVALID_ARGS ": Invalid arguments"
- #define INVALID_ARGS_STK ": Invalid arguments (stack)"
- #define TOO_SHORT ": Too short"
- #define MUST_BE_INT ": Must be a integer"
- #define MUST_BE_SYM ": Must be a symbol"
- #define MUST_BE_LIST ": Must be a list"
- #define MUST_BE_SYMLIST ": Must be a symbol list"
- #define MUST_BE_TABLE ": Must be a table"
- #define MUST_BE_LAMBDA ": Must be a lambda"
- #define DUPLICATE_NULL ": Tried to duplicate a null"
- #define FREE_NULL ": Tried to free a null"
- #define EXTRA_PARENTHESIS ": Extra closing parenthesis"
- // basic input and output:
- int _getchar();
- Atom* _warning(char*);
- Atom* _error(char*);
- // printing:
- void print_symbol(int*);
- void print_expression(Atom*);
- // duplicating and freeing:
- Atom* duplicate_atom(Atom*);
- List* duplicate_list(List*);
- Table* duplicate_table(Table*);
- int* duplicate_symbol(int*);
- void free_atom(Atom*);
- void free_list(List*);
- void free_table(Table*);
- // creating objects:
- List* cons(Atom*, List*);
- Atom* create_atom(Type);
- Atom* create_int(int);
- Atom* create_symbol(int*);
- Atom* create_list(List*);
- Atom* create_lambda(List*);
- // stack manipulation:
- void stack_push(Atom*, List**);
- void stack_pop(int, List**);
- // type operations:
- int is_simple(Atom*);
- int is_list(Atom*);
- int is_symbol(Atom*);
- int valid_lambda(List*);
- unsigned is_symbol_list(List*);
- // parsing:
- int skip_whitespace();
- Atom* parse_list();
- Atom* parse_symbol(int);
- Atom* parse_int(int);
- Atom* parse();
- // table operations:
- unsigned symbols_are_equal(int*, int*);
- Table* table_lookup(Table*, int*);
- Table* table_set(Table**, int*, Atom*);
- void table_union(Table*, Table**);
- unsigned table_unset(Table**, int*);
- int table_size(Table*);
- // object comparation:
- unsigned equal(Atom*, Atom*);
- unsigned lists_are_equal(List*, List*);
- int list_size(List*);
- // expression evaluation:
- void* (builtin_lookup)(int*);
- Table* atom_lookup(int* name, Table* context);
- Atom* eval(Atom*, Table**);
- Atom* eval_symbol(int*, List*, Table**);
- Atom* eval_application(List*, Table**);
- Atom* eval_lambda(List*, List*, Table**);
- unsigned define_local_vars (List*, List*, Table**);
- void destroy_local_vars (List*, Table**);
- #define DECL_BUILTIN(x) \
- Atom* x (List*, Table**)
- #define BUILTIN(x) \
- Atom* x (List* li, Table** ctx)
- // TODO review language semantics as a whole
- // TODO add table instructions and adapt list instructions to include table semantics
- // builtin functions:
- // stack focused:
- DECL_BUILTIN(_dup); // dupplicates the stack top element
- DECL_BUILTIN(_drop); // excludes the stack top element
- DECL_BUILTIN(_clear); // clear the entire stack
- DECL_BUILTIN(_swap); // swap the 2 most recent stack elements
- DECL_BUILTIN(_over); // copies the 2nd most recent stack element to the top
- DECL_BUILTIN(_depth); // returns the number of elements at the stack
- DECL_BUILTIN(_pick); // copies an arbitrary stack element to the top, given its stack position
- // list/table focused:
- // NOTE symbols are casted to a list containing its characters as numbers
- // NOTE numbers are casted to a list by the list-creating functions
- // NOTE list/table indexing functions don't accept simple atoms as their first arguments
- DECL_BUILTIN(_head); // returns the first list/table element
- // (head (list 1 2 3)) -> 1
- // (head (table a 1 b 2 c 3)) -> 3
- DECL_BUILTIN(_tip); // returns the last list/table element
- // (tip (list 1 2 3)) -> 3
- // (tip (table a 1 b 2 c 3)) -> 3
- DECL_BUILTIN(_tail); // returns all but the first list/table element
- // (tail (list 1 2 3)) -> (list 2 3)
- // (tail (table a 1 b 2 c 3)) -> (table b 2 c 3)
- DECL_BUILTIN(_first); // returns a list/table containing the first list/table elements in the requested quantity
- // (first (list 1 2 3) 2) -> (list 1 2)
- // (first (table a 1 b 2 c 3) 2) -> (table a 1 b 2)
- DECL_BUILTIN(_last); // returns a list/table containing the last list/table elements in the requested quantity
- // (first (list 1 2 3) 2) -> (list 1 2)
- // (first (table a 1 b 2 c 3) 2) -> (table a 1 b 2)
- DECL_BUILTIN(_get); // gets a list/table element given its index (indexes counting from 1)
- // (get (list 1 2 3) 2) -> 2
- // (get (table a 1 b 2 c 3) b) -> 2
- DECL_BUILTIN(_put); // puts new elements at arbitrary positions in the list given its indexes
- // or adds new key/value pairs in a table
- // (put (list 1 2 3) 1 9 1 8) -> (list 8 9 1 2 3)
- // (put (table a 1 b 2 c 3) d 8 e 9) -> (table a 1 b 2 c 3 d 8 e 9)
- DECL_BUILTIN(_find); // finds elements positions/indexes in a list/table
- // (find (list 9 8 7 6 5) 4 8 7) -> (list 0 2 3)
- // (find (table a 9 b 8 c 7) 4 8 7) -> (list 0 b c)
- DECL_BUILTIN(_match); // matches sequences of sequentially elements at a list, returning its initial positions
- // (match (list 1 2 3 9 8 7) (list 9 8 7) (list 2 3 9)) -> (list 4 2)
- DECL_BUILTIN(_slice); // returns slices of a list, always requiring 2 indexes for each slice
- // (slice (list 1 2 3 9 8 7) 2 3 5 6) -> (list 2 3 8 7)
- DECL_BUILTIN(_concat); // concatenates lists
- // (concat (list 1 2 3) (list 9 8 7)) -> (list 1 2 3 9 8 7)
- DECL_BUILTIN(_append); // appends elements at the end of a list
- // (append (list 1) 2 3) -> (list 1 2 3)
- DECL_BUILTIN(_prepend); // appends elements at the start of a list
- // (prepend (list 1) 2 3) -> (list 2 3 1)
- // functional utilities:
- DECL_BUILTIN(_map); //
- DECL_BUILTIN(_apply); //
- DECL_BUILTIN(_reduce); //
- DECL_BUILTIN(_filter); //
- DECL_BUILTIN(_quote); //
- DECL_BUILTIN(_unquote); //
- // symbol utilities:
- DECL_BUILTIN(_hash);
- DECL_BUILTIN(_concat);
- DECL_BUILTIN(_split);
- // compound objects creation, or type coercion:
- DECL_BUILTIN(_list); // coerces a lambda or table to a list, creates a new list
- DECL_BUILTIN(_lambda); // coerces a list to a lambda, creates a new lambda
- DECL_BUILTIN(_table); // coerces a list to a table, creates a new table
- // basic numeric operations:
- DECL_BUILTIN(_sum); // "+"
- DECL_BUILTIN(_sub); // "-"
- DECL_BUILTIN(_mul); // "*"
- DECL_BUILTIN(_div); // "/"
- DECL_BUILTIN(_rem); // "%"
- DECL_BUILTIN(_power); // "^"
- // numeric comparisons:
- DECL_BUILTIN(_eq); // "="
- DECL_BUILTIN(_lt); // "<"
- DECL_BUILTIN(_le); // "<="
- DECL_BUILTIN(_gt); // ">"
- DECL_BUILTIN(_ge); // ">="
- // logic utilities:
- DECL_BUILTIN(_and);
- DECL_BUILTIN(_or);
- DECL_BUILTIN(_xor);
- DECL_BUILTIN(_not);
- // flow control:
- DECL_BUILTIN(_if);
- DECL_BUILTIN(_when);
- DECL_BUILTIN(_case);
- DECL_BUILTIN(_conds);
- DECL_BUILTIN(_for);
- DECL_BUILTIN(_while);
- DECL_BUILTIN(_recur);
- DECL_BUILTIN(_do);
- // generics:
- DECL_BUILTIN(_eval);
- DECL_BUILTIN(_print);
- DECL_BUILTIN(_equal);
- DECL_BUILTIN(_stack);
- DECL_BUILTIN(_help);
- DECL_BUILTIN(_catalog);
- // operational:
- DECL_BUILTIN(_user_error);
- DECL_BUILTIN(_user_warning);
- DECL_BUILTIN(_option);
- DECL_BUILTIN(_quit);
- DECL_BUILTIN(_trap);
|