Files
lisp/lisp.h
T
2026-07-25 22:18:07 +02:00

135 lines
3.5 KiB
C

#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,
NODE_KIND_LAMBDA,
} 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 (*LispFunctionPtr)(Nodes args, Scopes *scopes, Node *result);
typedef struct s_LispFunction {
Nob_String_View name;
LispFunctionPtr apply;
} LispFunction;
struct s_Node {
NodeKind kind;
union {
Nob_String_View as_symbol;
Nodes *as_list;
double as_number;
LispFunction as_function;
struct {
Nodes *params;
Node *body;
} as_lambda;
};
};
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);
int 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);
/*
special forms and builtins follow the function signature defined by
LispFunctionPtr
The arguments for builtins will be evaluated before calling them,
that is not the case for special forms.
*/
// special forms
int special_form_if(Nodes args, Scopes *scopes, Node *result);
int special_form_define(Nodes args, Scopes *scopes, Node *result);
int special_form_let(Nodes args, Scopes *scopes, Node *result);
int special_form_lambda(Nodes args, Scopes *scopes, Node *result);
int special_form_quote(Nodes args, Scopes *scopes, Node *result);
// builtins
int builtin_add(Nodes args, Scopes *scopes, Node *result);
int builtin_sub(Nodes args, Scopes *scopes, Node *result);
int builtin_div(Nodes args, Scopes *scopes, Node *result);
int builtin_mul(Nodes args, Scopes *scopes, Node *result);
int builtin_floor(Nodes args, Scopes *scopes, Node *result);
int builtin_ceil(Nodes args, Scopes *scopes, Node *result);
int builtin_eq(Nodes args, Scopes *scopes, Node *result);
int builtin_lt(Nodes args, Scopes *scopes, Node *result);
int builtin_gt(Nodes args, Scopes *scopes, Node *result);
int builtin_lt_eq(Nodes args, Scopes *scopes, Node *result);
int builtin_gt_eq(Nodes args, Scopes *scopes, Node *result);
int builtin_list(Nodes args, Scopes *scopes, Node *result);
int builtin_append(Nodes args, Scopes *scopes, Node *result);
int builtin_length(Nodes args, Scopes *scopes, Node *result);
int builtin_isnull(Nodes args, Scopes *scopes, Node *result);
int builtin_nth(Nodes args, Scopes *scopes, Node *result);
int builtin_println(Nodes args, Scopes *scopes, Node *result);
int builtin_builtins(Nodes args, Scopes *scopes, Node *result);
#endif // LISP_H