diff --git a/lisp.c b/lisp.c index 8dcbdd2..e5beb2c 100644 --- a/lisp.c +++ b/lisp.c @@ -34,16 +34,8 @@ typedef enum e_NodeKind { NODE_KIND_FUNCTION, } NodeKind; -typedef struct s_Node { - NodeKind kind; - void *data; -} Node; - -typedef struct s_Nodes { - Node *items; - size_t count; - size_t capacity; -} Nodes; +typedef struct s_Node Node; +typedef struct s_Nodes Nodes; typedef Node *(*lisp_function_ptr)(Nodes *args); typedef struct s_LispFunction { @@ -51,6 +43,22 @@ typedef struct s_LispFunction { lisp_function_ptr apply; } LispFunction; +typedef struct s_Node { + NodeKind kind; + union { + Nob_String_View as_symbol; + Nodes *as_list; + long long as_number; + LispFunction as_function; + }; +} Node; + +struct s_Nodes { + Node *items; + size_t count; + size_t capacity; +}; + Node *lisp_function_addition(Nodes *args) { if (args->count != 2) { printf("'+' expects two arguments!\n"); @@ -66,13 +74,9 @@ Node *lisp_function_addition(Nodes *args) { Node *node = malloc(sizeof(Node)); node->kind = NODE_KIND_NUMBER; - long long *num = malloc(sizeof(long long)); - // trust me, this is safe :) - long long a = *((long long *)args->items[0].data); - long long b = *((long long *)args->items[1].data); - *num = a + b; - - node->data = num; + intptr_t a = args->items[0].as_number; + intptr_t b = args->items[1].as_number; + node->as_number = a + b; return node; } @@ -85,9 +89,7 @@ Node *lisp_function_lookup(Nob_String_View name) { if (nob_sv_eq(globalScope[i].name, name)) { Node *node = malloc(sizeof(Node)); node->kind = NODE_KIND_FUNCTION; - // taking the reference should be fine because globalScope is in the - // static memory - node->data = &globalScope[i]; + node->as_function = globalScope[i]; return node; } } @@ -200,7 +202,7 @@ Node *parse(Tokens *tokens) { } node->kind = NODE_KIND_LIST; - node->data = nodes; + node->as_list = nodes; return node; } @@ -211,18 +213,17 @@ Node *parse(Tokens *tokens) { switch (tok.kind) { case TOKEN_KIND_NUMBER: { - long long *num = malloc(sizeof(long long)); - *num = strtoll(tok.data.data, NULL, 10); + long long num = strtoll(tok.data.data, NULL, 10); + // TODO: + // - error checking + // - double support node->kind = NODE_KIND_NUMBER; - node->data = num; + node->as_number = num; } break; case TOKEN_KIND_SYMBOL: { - Nob_String_View *dat = malloc(sizeof(Nob_String_View)); - *dat = tok.data; - node->kind = NODE_KIND_SYMBOL; - node->data = dat; + node->as_symbol = tok.data; } break; default: { UNREACHABLE(""); @@ -234,27 +235,25 @@ Node *parse(Tokens *tokens) { void node_print(Node node) { switch (node.kind) { case NODE_KIND_NUMBER: { - long long num = *((long long *)node.data); - printf("%lld", num); + printf("%lld", node.as_number); } break; case NODE_KIND_SYMBOL: { - Nob_String_View sv = *((Nob_String_View *)node.data); - printf(SV_Fmt, SV_Arg(sv)); + printf(SV_Fmt, SV_Arg(node.as_symbol)); } break; case NODE_KIND_LIST: { - Nodes nodes = *((Nodes *)node.data); + Nodes *children = node.as_list; printf("("); - for (size_t i = 0; i < nodes.count; i++) { - Node node = nodes.items[i]; + for (size_t i = 0; i < children->count; i++) { + Node node = children->items[i]; node_print(node); - if (i != nodes.count - 1) { + if (i != children->count - 1) { printf(" "); } } printf(")"); } break; case NODE_KIND_FUNCTION: { - LispFunction func = *((LispFunction *)node.data); + LispFunction func = node.as_function; printf(SV_Fmt, SV_Arg(func.name)); } break; } @@ -268,30 +267,28 @@ Node *eval(Node *node) { case NODE_KIND_NUMBER: return node; case NODE_KIND_SYMBOL: { - // trust me, this is safe :) - Nob_String_View sv = *((Nob_String_View *)node->data); - return lisp_function_lookup(sv); + return lisp_function_lookup(node->as_symbol); } case NODE_KIND_LIST: { - Nodes children = *((Nodes *)node->data); - if (children.count == 0) + Nodes *children = node->as_list; + if (children->count == 0) return node; - Node *head = &children.items[0]; - Node *function = eval(head); + Node *head = &children->items[0]; + Node *func_node = eval(head); Nodes *args = malloc(sizeof(Nodes)); - for (size_t i = 1; i < children.count; i++) { - nob_da_append(args, *eval(&children.items[i])); + for (size_t i = 1; i < children->count; i++) { + nob_da_append(args, *eval(&children->items[i])); } - if (function->kind == NODE_KIND_FUNCTION) { - LispFunction func = *((LispFunction *)function->data); + if (func_node->kind == NODE_KIND_FUNCTION) { + LispFunction func = func_node->as_function; return func.apply(args); } printf("Not a function: '"); - node_print(*function); + node_print(*func_node); printf("'\n"); return NULL; }