diff --git a/builtins.c b/builtins.c index 01a464b..10dabbf 100644 --- a/builtins.c +++ b/builtins.c @@ -38,14 +38,14 @@ func_arithmetic(lisp_function_gt_eq, >=); int lisp_function_println(Nodes *args, Scopes *scopes, Node *result) { if (args->count != 1) { printf("'+' expects one argument!\n"); - return 0; + return 1; } eval_one(args->items[0], scopes, result); node_print(*result); printf("\n"); - return 1; + return 0; } int lisp_function_list(Nodes *args, Scopes *scopes, Node *result) { diff --git a/lisp.c b/lisp.c index 826a6b2..7c8fb19 100644 --- a/lisp.c +++ b/lisp.c @@ -213,27 +213,49 @@ int parse_one(Tokens *tokens, Node *node) { node->as_symbol = tok.data; } break; default: { - UNREACHABLE(""); - } break; + return 1; + } } return 0; } -void parse(Tokens *tokens, Nodes *nodes) { - if (nodes == NULL) - return; +int parse(Tokens *tokens, Nodes *nodes) { + if (tokens == NULL || nodes == NULL) + return 1; + struct { + size_t *items; + size_t count; + size_t capacity; + } stack = {0}; + + size_t last_idx = 0; for (size_t i = 0; i < tokens->count; i++) { - if (tokens->items[i].kind == TOKEN_KIND_PAR_LEFT) { - size_t sub_size = tokens->count - i; + TokenKind kind = tokens->items[i].kind; + if (kind == TOKEN_KIND_PAR_LEFT) + nob_da_append(&stack, i); + else if (kind == TOKEN_KIND_PAR_RIGHT) + last_idx = nob_da_pop(&stack); + + if (stack.count == 0) { + size_t sub_size = tokens->count - last_idx; Tokens toks = {.count = sub_size, .capacity = sub_size, - .items = tokens->items + i}; + .items = tokens->items + last_idx}; + printf("Parsing:\n"); + nob_da_foreach(Token, token, &toks) { + printf(" %s\n", token_kind_name(token->kind)); + } + Node result = {0}; - parse_one(&toks, &result); + int ret = parse_one(&toks, &result); + if (ret != 0) { + return ret; + } nob_da_append(nodes, result); } } + return 0; } int eval_one(Node input, Scopes *scopes, Node *result) { @@ -268,14 +290,17 @@ int eval_one(Node input, Scopes *scopes, Node *result) { } Node condition = {0}; - eval_one(children->items[0 + 1], scopes, &condition); + int ret = eval_one(children->items[0 + 1], scopes, &condition); + if (ret != 0) { + return ret; + } if (node_is_true(condition)) { - eval_one(children->items[1 + 1], scopes, result); + ret = eval_one(children->items[1 + 1], scopes, result); } else { - eval_one(children->items[2 + 1], scopes, result); + ret = eval_one(children->items[2 + 1], scopes, result); } - return 0; + return ret; } if (nob_sv_eq(head.as_symbol, @@ -291,12 +316,15 @@ int eval_one(Node input, Scopes *scopes, Node *result) { } Node value = {0}; - eval_one(children->items[1 + 1], scopes, &value); + int ret = eval_one(children->items[1 + 1], scopes, &value); + if (ret != 0) { + return ret; + } nob_da_foreach(ScopeObject, scope_object, &globalScope) { if (nob_sv_eq(scope_object->name, name_node.as_symbol)) { scope_object->node = value; - result = &children->items[0 + 1]; + *result = children->items[0 + 1]; return 0; } } @@ -304,14 +332,17 @@ int eval_one(Node input, Scopes *scopes, Node *result) { ScopeObject obj = (ScopeObject){.name = name_node.as_symbol, .node = value}; nob_da_append(&globalScope, obj); - result = &children->items[0 + 1]; + *result = children->items[0 + 1]; return 0; } Nodes *args = malloc(sizeof(Nodes)); for (size_t i = 1; i < children->count; i++) { Node n = {0}; - eval_one(children->items[i], scopes, &n); + int ret = eval_one(children->items[i], scopes, &n); + if (ret != 0) { + return ret; + } nob_da_append(args, n); } @@ -332,16 +363,15 @@ int eval_one(Node input, Scopes *scopes, Node *result) { return 1; } default: - UNREACHABLE(""); + return 1; } - return 0; } -int eval(Nodes *inputs, Scopes *scopes, Nodes *results) { - nob_da_foreach(Node, input, inputs) { +int eval(Nodes inputs, Scopes *scopes, Nodes *results) { + nob_da_foreach(Node, input, &inputs) { Node result = {0}; - int ret = 0; - if ((ret = eval_one(*input, scopes, &result)) != 0) { + int ret = eval_one(*input, scopes, &result); + if (ret != 0) { return ret; } nob_da_append(results, result); diff --git a/lisp.h b/lisp.h index 873ef14..f7d7c92 100644 --- a/lisp.h +++ b/lisp.h @@ -78,10 +78,10 @@ void build_scopes(Scopes *scopes); void tokenize(Nob_String_View content, Tokens *tokens); int parse_one(Tokens *tokens, Node *node); -void parse(Tokens *tokens, Nodes *nodes); +int parse(Tokens *tokens, Nodes *nodes); int eval_one(Node input, Scopes *scopes, Node *result); -int eval(Nodes *inputs, Scopes *scopes, Nodes *results); +int eval(Nodes inputs, Scopes *scopes, Nodes *results); // builtins int lisp_function_add(Nodes *args, Scopes *scopes, Node *result); diff --git a/main.c b/main.c index 220c2f7..9d333ae 100644 --- a/main.c +++ b/main.c @@ -51,7 +51,11 @@ int main(int argc, char **argv) { #endif Nodes evaluated = {0}; - int ret = eval(&result, &scopes, &evaluated); + int ret = eval(result, &scopes, &evaluated); + if (ret != 0) { + return 1; + } + nob_da_foreach(Node, node, &evaluated) { node_print(*node); printf("\n");