diff --git a/src/exec.c b/src/exec.c index f1d208c..ce1c5de 100644 --- a/src/exec.c +++ b/src/exec.c @@ -39,10 +39,11 @@ AST* exec_exp(AST* ast, Scope* parent) { return ast_init( AST_TYPE_NUM, ast_num_data_init(*(ASTNumData*)ast->data) ); - case AST_TYPE_VREF: return exec_vref(ast, parent); - case AST_TYPE_VDEF: return exec_vdef(ast, parent); - case AST_TYPE_FDEF: return exec_fdef(ast, parent); - default: printf("what\n"); exit(1); + case AST_TYPE_VREF: return exec_vref(ast, parent); + case AST_TYPE_VDEF: return exec_vdef(ast, parent); + case AST_TYPE_FDEF: return exec_fdef(ast, parent); + case AST_TYPE_LAMBDA: return exec_lambda(ast, parent); + default: printf("what\n"); exit(1); } } @@ -79,7 +80,8 @@ AST* exec_call(AST* ast, Scope* parent) { case AST_TYPE_BIF: ASTBIFData bifdata = fdef->data; return bifdata(argc, argv, parent); - case AST_TYPE_FDEF: return exec_cf(fdef, argc, argv); + case AST_TYPE_FDEF: return exec_cf(fdef, argc, argv); + case AST_TYPE_LAMBDA: return exec_lambda_call(fdef, argc, argv); default: return ast_init(AST_TYPE_EXC, ast_exc_data_init("Good job!", NULL)); } @@ -132,14 +134,29 @@ AST* exec_vref(AST* ast, Scope* parent) { AST* exec_fdef(AST* ast, Scope* parent) { ast->scope = scope_init(parent); ASTFDefData* fdef = (ASTFDefData*)ast->data; - log_dbgf("IS THIS SUSPICIOUS??? %i", fdef->body->type); AST* val = ast; char* key = fdef->name; scope_add(parent, key, val); - // TODO: Create lambda functions. return fdef->body; // Function definitions return function body. } +AST* exec_lambda(AST* ast, Scope* parent) { + // Executing a lambda on its own with no arguments returns itself. + return ast; +} + +AST* exec_lambda_call(AST* ast, size_t argc, AST** argv) { + Scope* callscope = scope_init(ast->scope); + ASTFDefData* lambda = (ASTFDefData*)ast->data; + for (int i = 0; i < argc; i++) { + char* key = ((ASTArgData*)lambda->argv[i]->data)->name; + AST* val = argv[i]; + scope_add(callscope, key, val); + } + + return exec_exp(lambda->body, callscope); +} + void exec_print(double n) { printf("= %lf\n", n); } inline void exec_new_scope(AST* ast, Scope* inherit) { diff --git a/src/grammar.y b/src/grammar.y index 4eb1508..973efe0 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -142,6 +142,15 @@ exp: $$ = ast_init(AST_TYPE_LAMBDA, ast_lambda_data_init(argc, argv, $5)); } + /* + // Inline call. + | exp GROUPS arg GROUPE { + size_t argc = $3->ln; + AST** argv = $3->buf; + argarr_destroypsv($3); + $$ = ast_init(AST_TYPE_CALL, ($1, argc, argv)); + } + */ | BLOCKS block BLOCKE { $$ = ast_init(AST_TYPE_BLOCK, ast_block_data_init((AST**) $2->buf, $2->ln)); diff --git a/src/include/ast.h b/src/include/ast.h index 9f2239d..ea6de51 100644 --- a/src/include/ast.h +++ b/src/include/ast.h @@ -86,13 +86,6 @@ ASTBIFData* ast_bif_data_init(AST* fn(size_t, AST**, Scope*)); // Destroy an `ASTBIFData`. void ast_bif_data_destroy(ASTBIFData* bif); -/* - * // A list of arguments. -typedef struct { - size_t argc; - AST** argv; -} Args; -*/ // A call (to a function). typedef struct { char* to; // What the call's to. diff --git a/src/include/exec.h b/src/include/exec.h index 8836e21..bd7ddc1 100644 --- a/src/include/exec.h +++ b/src/include/exec.h @@ -20,6 +20,10 @@ AST* exec_vdef(AST* ast, Scope* parent); AST* exec_vref(AST* ast, Scope* parent); // Execute a function definition. AST* exec_fdef(AST* ast, Scope* parent); +// Execute a lambda expression. +AST* exec_lambda(AST* ast, Scope* parent); +// Execute a lambda call. +AST* exec_lambda_call(AST* ast, size_t argc, AST** argv); // Print the result of an execution. void exec_print(double n);