From 891d8bf7eff6a43e7a89eb0ebb83caf437675a05 Mon Sep 17 00:00:00 2001 From: Jacob Signorovitch Date: Sat, 26 Oct 2024 10:07:33 -0400 Subject: [PATCH] Finished initial AST structures. Call and ints (nums). --- src/ast.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ src/include/ast.h | 19 +++++++++++++--- src/include/parser.h | 9 -------- src/include/util.h | 6 ++++- src/lexer.c | 15 ++++++++---- src/main.c | 1 - 6 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 src/ast.c diff --git a/src/ast.c b/src/ast.c new file mode 100644 index 0000000..9a44e0f --- /dev/null +++ b/src/ast.c @@ -0,0 +1,54 @@ +#include + +#include "include/ast.h" +#include "include/util.h" + +static char* asttype_names[] = { + [AST_TYPE_CALL] = "CALL", + [AST_TYPE_NUM] = "NUMBER", +}; + +ASTTypeNum* ast_type_num_init(int val) { + talloc(ASTTypeNum, num); + + num->val = val; + + return num; +} + +void ast_type_num_destroy(ASTTypeNum* num) { + free(num); +} + +ASTTypeCall* ast_type_call_init(char* to, size_t argc, AST** argv) { + talloc(ASTTypeCall, call); + + call->to = to; + call->argc = argc; + call->argv = argv; + + return call; +} + +void ast_type_call_destroy(ASTTypeCall* call) { + free(call->to); + for (size_t i = 0; i < call->argc; i++) free(call->argv[i]); + free(call); +} + +AST* ast_init(ASTType type, void* data) { + AST* ast = malloc(sizeof(AST)); + + ast->type = type; + ast->data = data; + + return ast; +} + +void ast_destroy(AST* ast) { + switch (ast->type) { + case AST_TYPE_NUM: ast_type_num_destroy(ast->data); break; + case AST_TYPE_CALL: ast_type_call_destroy(ast->data); break; + default: log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX); + } +} diff --git a/src/include/ast.h b/src/include/ast.h index 28a1ad5..02789c8 100644 --- a/src/include/ast.h +++ b/src/include/ast.h @@ -1,9 +1,12 @@ #ifndef AST_H #define AST_H +#include + typedef enum { AST_TYPE_NUM, - AST_TYPE,CALL + AST_TYPE_CALL, + AST_TYPE_MAX = AST_TYPE_CALL } ASTType; typedef struct { @@ -15,9 +18,19 @@ typedef struct { int val; } ASTTypeNum; +ASTTypeNum* ast_type_num_init(int val); +void ast_type_num_destroy(ASTTypeNum* num); + typedef struct { - char* to; - char** args; + char* to; // What the call's to. + size_t argc; // Argument count. + AST** argv; // Argument vector. } ASTTypeCall; +ASTTypeCall* ast_type_call_init(char* to, size_t argc, AST** argv); +void ast_type_call_destroy(ASTTypeCall* call); + +AST* ast_init(ASTType type, void* data); +void ast_destroy(AST* ast); + #endif diff --git a/src/include/parser.h b/src/include/parser.h index 53a77ff..bee509b 100644 --- a/src/include/parser.h +++ b/src/include/parser.h @@ -1,13 +1,4 @@ #ifndef PARSER_H #define PARSER_H -// Expression one of: -// - Operation -// - Number - -// Operation contains: -// - Type -// - Expression 1 -// - Expression 2 - #endif diff --git a/src/include/util.h b/src/include/util.h index d96ded8..645f5d1 100644 --- a/src/include/util.h +++ b/src/include/util.h @@ -34,12 +34,16 @@ // Print & indent a thing with a newline before the val. #define INDENT_FIELD_NL(FIELD, VAL, ...) \ - printf("%s " FIELD ":\n %s " VAL "\n", INDENT_spacing->buf, \ + printf("%s " FIELD ":\n %s " VAL "\n", INDENT_spacing->buf, \ INDENT_spacing->buf, __VA_ARGS__); // Print & indent a thing without any newline. #define INDENT_FIELD_NONL(FIELD) printf("%s " FIELD ": ", INDENT_spacing->buf); +// End an indent block. #define INDENT_END dstr_destroy(INDENT_spacing); +// Allocate a pointer with a type. +#define talloc(T, X) T* X = malloc(sizeof(T)); + #endif diff --git a/src/lexer.c b/src/lexer.c index 44c7598..42f245d 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -41,7 +41,10 @@ void lexer_lex(Lexer* lexer) { } void lexer_do_confused(Lexer* lexer) { - log_dbgf("lexer @ %p entered confused mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar); + log_dbgf("lexer @ %p entered confused mode @ char '%c' (%d)", lexer, + *lexer->cchar, (int)*lexer->cchar); + + if (isspace(*lexer->cchar)) lexer_inc(lexer); if (isdigit(*lexer->cchar)) { lexer->state = LEXER_STATE_NUM; @@ -53,7 +56,8 @@ void lexer_do_confused(Lexer* lexer) { } void lexer_do_number(Lexer* lexer) { - log_dbgf("lexer @ %p entered number mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar); + log_dbgf("lexer @ %p entered number mode @ char '%c' (%d)", lexer, + *lexer->cchar, (int)*lexer->cchar); // Length of the number string. size_t numln; @@ -73,7 +77,8 @@ void lexer_do_number(Lexer* lexer) { } void lexer_do_call(Lexer* lexer) { - log_dbgf("lexer @ %p entered call mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar); + log_dbgf("lexer @ %p entered call mode @ char '%c' (%d)", lexer, + *lexer->cchar, (int)*lexer->cchar); // Size of the call string. size_t callln; @@ -81,7 +86,9 @@ void lexer_do_call(Lexer* lexer) { // Where the call string starts. char* start = lexer->cchar; - for (callln = 0; *lexer->cchar && (!isdigit(*lexer->cchar)); callln++) + for (callln = 0; + *lexer->cchar && (!isdigit(*lexer->cchar) && !isspace(*lexer->cchar)); + callln++) lexer_inc(lexer); char* call = malloc(callln + 1); diff --git a/src/main.c b/src/main.c index 56fb5d4..c7ad97f 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,6 @@ #include #include "include/dstr.h" -#include "include/token.h" #include "include/util.h" #include "include/lexer.h"