Added lambda parsing.

This commit is contained in:
Jacob Signorovitch 2025-06-28 11:15:21 -04:00
parent 67aafb3ead
commit 289243de38
4 changed files with 94 additions and 43 deletions

View File

@ -17,7 +17,9 @@ static char* asttype_names[] = {
[AST_TYPE_BLOCK] = "BLOCK",
[AST_TYPE_EXC] = "EXCEPTION",
[AST_TYPE_FDEF] = "FUNCTION DEFINITION",
[AST_TYPE_ARG] = "DEFINITION ARGUMENT"
[AST_TYPE_ARG] = "DEFINITION ARGUMENT",
[AST_TYPE_LAMBDA] = "LAMBDA EXPRESSION"
};
AST* ast_init(ASTType type, void* data) {
@ -58,6 +60,7 @@ void ast_destroy(AST* ast) {
case AST_TYPE_BLOCK: ast_block_data_destroy(ast->data); break;
case AST_TYPE_FDEF: ast_fdef_data_destroy(ast->data); break;
case AST_TYPE_ARG: ast_arg_data_destroy(ast->data); break;
case AST_TYPE_LAMBDA: ast_lambda_data_destroy(ast->data); break;
default:
log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX);
}
@ -81,6 +84,7 @@ void ast_destroy_psv(AST* ast) {
case AST_TYPE_ARG: ast_arg_data_destroy(ast->data); break;
case AST_TYPE_BIF: ast_bif_data_destroy(ast->data); break;
case AST_TYPE_EXC: ast_exc_data_destroy(ast->data); break;
case AST_TYPE_LAMBDA: ast_lambda_data_destroy(ast->data); break;
default:
log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX);
}
@ -111,6 +115,7 @@ void ast_print_i(AST* ast, int i) {
case AST_TYPE_BLOCK: ast_block_print(ast->data, i + 2); break;
case AST_TYPE_FDEF: ast_fdef_print(ast->data, i + 2); break;
case AST_TYPE_ARG: ast_arg_print(ast->data, i + 2); break;
case AST_TYPE_LAMBDA: ast_lambda_print(ast->data, i + 2); break;
default: exit(1);
}
INDENT_FIELD_NONL_END;
@ -344,6 +349,32 @@ void ast_arg_print(ASTArgData* arg, int i) {
INDENT_END;
}
ASTLambdaData* ast_lambda_data_init(size_t argc, AST** argv, AST* body) {
talloc(ASTLambdaData, lambda);
lambda->argc = argc;
lambda->argv = argv;
lambda->body = body;
return lambda;
}
void ast_lambda_data_destroy(ASTLambdaData* lambda) {
free(lambda->argv);
free(lambda);
}
void ast_lambda_print(ASTLambdaData* lambda, int i) {
INDENT_BEGIN(i)
INDENT_TITLE("ASTLambdaData", lambda);
INDENT_FIELD("argc", "%ld", lambda->argc);
INDENT_FIELD_LIST("argv", lambda->argv, lambda->argc, ast_print_i);
INDENT_FIELD_EXT_NONL_START("body");
ast_print_i(lambda->body, i + 2);
INDENT_FIELD_NONL_END;
INDENT_END;
}
AST* ast_find(Scope* scope, char* name) {
while (scope) {
AST* gotten = htab_get(scope->here, name);

View File

@ -47,6 +47,8 @@
%token NL // Newline.
%token BACKSLASH
%left ADD SUB
%left MUL DIV
%precedence NEG
@ -132,6 +134,15 @@ exp:
$$ = ast_init(AST_TYPE_FDEF, ast_fdef_data_init($1, argc, argv, $5));
}
// Lambda definitions.
| BACKSLASH GROUPS arg GROUPE exp {
size_t argc = $3->ln;
AST** argv = $3->buf;
argarr_destroypsv($3);
$$ = ast_init(AST_TYPE_LAMBDA, ast_lambda_data_init(argc, argv, $5));
}
| BLOCKS block BLOCKE {
$$ = ast_init(AST_TYPE_BLOCK, ast_block_data_init((AST**) $2->buf, $2->ln));
}

View File

@ -24,6 +24,7 @@ typedef enum {
AST_TYPE_VREF, // A variable reference.
AST_TYPE_BLOCK, // A block of code (scope).
AST_TYPE_FDEF, // A function definition.
AST_TYPE_LAMBDA, // An anonymous function definition.
AST_TYPE_ARG, // A definition argument.
AST_TYPE_MAX = AST_TYPE_ARG,
} ASTType;
@ -71,7 +72,11 @@ void ast_exc_data_destroy(ASTExcData* exc);
void ast_exc_print(ASTExcData*, int i);
// arguments list as anonymous struct
#define ARGS struct { size_t argc; AST** argv; }
#define ARGS \
struct { \
size_t argc; \
AST** argv; \
}
// A built-in function.
typedef AST* (*ASTBIFData)(size_t argc, AST** argv, Scope* scope);
@ -99,7 +104,7 @@ ASTCallData* ast_call_data_init(char* to, size_t argc, AST** argv);
// Destroy an `ASTCallData` recursively.
void ast_call_data_destroy(ASTCallData* call);
// Destroy an `ASTCallData`.
void ast_call_data_destroy_psv(ASTCallData *call);
void ast_call_data_destroy_psv(ASTCallData* call);
// Print an `ASTCallData`.
void ast_call_print(ASTCallData*, int i);
@ -141,7 +146,7 @@ ASTBlockData* ast_block_data_init(AST** inside, size_t ln);
// Destroy an `ASTBlockData`, recursively.
void ast_block_data_destroy(ASTBlockData* block);
// Destroy an `ASTBlockData`.
void ast_block_data_destroy_psv(ASTBlockData *block);
void ast_block_data_destroy_psv(ASTBlockData* block);
// Print an `ASTBlockData`.
void ast_block_print(ASTBlockData*, int i);
@ -179,7 +184,10 @@ typedef struct {
// Creates a new `ASTLambdaData`.
ASTLambdaData* ast_lambda_data_init(size_t argc, AST** argv, AST* body);
// Destroy an `AST
// Destroy an `ASTLambdaData`.
void ast_lambda_data_destroy(ASTLambdaData*);
// Print an `ASTLambdaData`.
void ast_lambda_print(ASTLambdaData* arg, int i);
// Find a name in the scope.
AST* ast_find(Scope* scope, char* name);

View File

@ -116,6 +116,7 @@ int yylex() {
case '{': return BLOCKS;
case '}': return BLOCKE;
case '=': return EQ;
case '\\': return BACKSLASH;
default: fprintf(stderr, "Unexpected character: %c\n", c);
}