#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; typedef Node *(*LispFunction)(Nodes *args, Scopes *scopes); 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); Node *parse(Tokens *tokens); Node *eval(Node *node, Scopes *scopes); // builtins Node *lisp_function_addition(Nodes *args, Scopes *scopes); Node *lisp_function_println(Nodes *args, Scopes *scopes); Node *lisp_function_list(Nodes *args, Scopes *scopes); Node *lisp_function_append(Nodes *args, Scopes *scopes); Node *lisp_function_length(Nodes *args, Scopes *scopes); Node *lisp_function_isnull(Nodes *args, Scopes *scopes); #endif // LISP_H