#ifndef LISP_H #define LISP_H #include "nob.h" typedef enum e_TokenKind { TOKEN_KIND_PAR_LEFT, TOKEN_KIND_PAR_RIGHT, TOKEN_KIND_NUMBER, TOKEN_KIND_SYMBOL, } TokenKind; typedef struct s_Token { TokenKind kind; Nob_String_View data; } Token; typedef struct s_Tokens { Token *items; size_t count; size_t capacity; } Tokens; typedef enum e_NodeKind { NODE_KIND_SYMBOL, NODE_KIND_LIST, NODE_KIND_NUMBER, NODE_KIND_FUNCTION, } NodeKind; typedef struct s_Node Node; typedef struct s_Nodes Nodes; typedef struct s_Scopes Scopes; // args is specifically not a pointer, // functions shouldn't be able to mess with their arguments typedef int (*LispFunction)(Nodes args, Scopes *scopes, Node *result); struct s_Node { NodeKind kind; union { Nob_String_View as_symbol; Nodes *as_list; long long as_number; struct { Nob_String_View name; LispFunction apply; } as_function; }; }; struct s_Nodes { Node *items; size_t count; size_t capacity; }; typedef struct s_ScopeObject { Nob_String_View name; Node node; } ScopeObject; // TODO: use hashtable typedef struct s_Scope { ScopeObject *items; size_t count; size_t capacity; } Scope; struct s_Scopes { Scope **items; size_t count; size_t capacity; }; const char *token_kind_name(TokenKind kind); void node_print(Node node); void build_scopes(Scopes *scopes); void tokenize(Nob_String_View content, Tokens *tokens); int parse_one(Tokens *tokens, Node *node); int parse(Tokens *tokens, Nodes *nodes); int eval_one(Node input, Scopes *scopes, Node *result); int eval(Nodes inputs, Scopes *scopes, Nodes *results); // builtins int lisp_function_add(Nodes args, Scopes *scopes, Node *result); int lisp_function_sub(Nodes args, Scopes *scope, Node *result); int lisp_function_div(Nodes args, Scopes *scope, Node *result); int lisp_function_mul(Nodes args, Scopes *scope, Node *result); int lisp_function_mod(Nodes args, Scopes *scope, Node *result); int lisp_function_eq(Nodes args, Scopes *scope, Node *result); int lisp_function_lt(Nodes args, Scopes *scope, Node *result); int lisp_function_gt(Nodes args, Scopes *scope, Node *result); int lisp_function_lt_eq(Nodes args, Scopes *scope, Node *result); int lisp_function_gt_eq(Nodes args, Scopes *scope, Node *result); int lisp_function_println(Nodes args, Scopes *scopes, Node *result); int lisp_function_list(Nodes args, Scopes *scopes, Node *result); int lisp_function_append(Nodes args, Scopes *scope, Node *result); int lisp_function_length(Nodes args, Scopes *scope, Node *result); int lisp_function_isnull(Nodes args, Scopes *scope, Node *result); int lisp_function_builtins(Nodes args, Scopes *scopes, Node *result); #endif // LISP_H