impl scopes more or less properly
This commit is contained in:
@@ -1,16 +1,13 @@
|
||||
#include "lisp.h"
|
||||
|
||||
static LispFunction globalScope[] = {
|
||||
(LispFunction){.name = (Nob_String_View){.items = "+", .count = 1},
|
||||
.apply = lisp_function_addition}};
|
||||
static Scope globalScope = {0};
|
||||
|
||||
static Node *lisp_function_lookup(Nob_String_View name) {
|
||||
for (size_t i = 0; i < NOB_ARRAY_LEN(globalScope); i++) {
|
||||
if (nob_sv_eq(globalScope[i].name, name)) {
|
||||
Node *node = malloc(sizeof(Node));
|
||||
node->kind = NODE_KIND_FUNCTION;
|
||||
node->as_function = globalScope[i];
|
||||
return node;
|
||||
static Node *scope_lookup(Scopes *scopes, Nob_String_View name) {
|
||||
nob_da_foreach(Scope, scope, scopes) {
|
||||
nob_da_foreach(ScopeObject, scopeObject, scope) {
|
||||
if (nob_sv_eq(name, scopeObject->name)) {
|
||||
return &scopeObject->node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +15,44 @@ static Node *lisp_function_lookup(Nob_String_View name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void build_scopes(Scopes *scopes) {
|
||||
// clang-format off
|
||||
Nob_String_View obj_name = (Nob_String_View){
|
||||
.items = "+",
|
||||
.count = 1
|
||||
};
|
||||
ScopeObject obj = (ScopeObject){
|
||||
.name = obj_name,
|
||||
.node = (Node){
|
||||
.kind = NODE_KIND_FUNCTION,
|
||||
.as_function = {
|
||||
.name = obj_name,
|
||||
.apply = lisp_function_addition
|
||||
}
|
||||
}
|
||||
};
|
||||
nob_da_append(&globalScope, obj);
|
||||
|
||||
obj_name = (Nob_String_View){
|
||||
.items = "println",
|
||||
.count = 7
|
||||
};
|
||||
obj = (ScopeObject){
|
||||
.name = obj_name,
|
||||
.node = (Node){
|
||||
.kind = NODE_KIND_FUNCTION,
|
||||
.as_function = {
|
||||
.name = obj_name,
|
||||
.apply = lisp_function_println
|
||||
}
|
||||
}
|
||||
};
|
||||
nob_da_append(&globalScope, obj);
|
||||
// clang-format on
|
||||
|
||||
nob_da_append(scopes, globalScope);
|
||||
}
|
||||
|
||||
const char *token_kind_name(TokenKind kind) {
|
||||
switch (kind) {
|
||||
case TOKEN_KIND_PAR_LEFT:
|
||||
@@ -54,8 +89,8 @@ void node_print(Node node) {
|
||||
printf(")");
|
||||
} break;
|
||||
case NODE_KIND_FUNCTION: {
|
||||
LispFunction func = node.as_function;
|
||||
printf(SV_Fmt, SV_Arg(func.name));
|
||||
Nob_String_View func_name = node.as_function.name;
|
||||
printf(SV_Fmt, SV_Arg(func_name));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
@@ -180,15 +215,15 @@ Node *parse(Tokens *tokens) {
|
||||
return node;
|
||||
}
|
||||
|
||||
Node *eval(Node *node) {
|
||||
if (node == NULL)
|
||||
Node *eval(Node *node, Scopes *scopes) {
|
||||
if (node == NULL || scopes == NULL)
|
||||
return NULL;
|
||||
|
||||
switch (node->kind) {
|
||||
case NODE_KIND_NUMBER:
|
||||
return node;
|
||||
case NODE_KIND_SYMBOL: {
|
||||
return lisp_function_lookup(node->as_symbol);
|
||||
return scope_lookup(scopes, node->as_symbol);
|
||||
}
|
||||
case NODE_KIND_LIST: {
|
||||
Nodes *children = node->as_list;
|
||||
@@ -196,16 +231,15 @@ Node *eval(Node *node) {
|
||||
return node;
|
||||
|
||||
Node *head = &children->items[0];
|
||||
Node *func_node = eval(head);
|
||||
Node *func_node = eval(head, scopes);
|
||||
|
||||
Nodes *args = malloc(sizeof(Nodes));
|
||||
for (size_t i = 1; i < children->count; i++) {
|
||||
nob_da_append(args, *eval(&children->items[i]));
|
||||
nob_da_append(args, *eval(&children->items[i], scopes));
|
||||
}
|
||||
|
||||
if (func_node->kind == NODE_KIND_FUNCTION) {
|
||||
LispFunction func = func_node->as_function;
|
||||
return func.apply(args);
|
||||
return func_node->as_function.apply(args, scopes);
|
||||
}
|
||||
|
||||
printf("Not a function: '");
|
||||
|
||||
Reference in New Issue
Block a user