diff --git a/src/ast.c b/src/ast.c index 9a44e0f..418b4a7 100644 --- a/src/ast.c +++ b/src/ast.c @@ -17,6 +17,8 @@ ASTTypeNum* ast_type_num_init(int val) { } void ast_type_num_destroy(ASTTypeNum* num) { + if (!num) return + free(num); } @@ -31,6 +33,8 @@ ASTTypeCall* ast_type_call_init(char* to, size_t argc, AST** argv) { } void ast_type_call_destroy(ASTTypeCall* call) { + if (!call) return + free(call->to); for (size_t i = 0; i < call->argc; i++) free(call->argv[i]); free(call); @@ -46,6 +50,8 @@ AST* ast_init(ASTType type, void* data) { } void ast_destroy(AST* ast) { + if (!ast) return; + 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; diff --git a/src/include/parser.h b/src/include/parser.h index bee509b..708f3c3 100644 --- a/src/include/parser.h +++ b/src/include/parser.h @@ -1,4 +1,19 @@ #ifndef PARSER_H #define PARSER_H +#include "token.h" +#include "ast.h" + +typedef struct { + size_t tokenc; // Number of tokens in tokenv; + Token* ctoken; // The current token. + Token** tokenv; // Token vector. + AST* ast; // Abstract syntax tree. +} Parser; + +Parser* parser_init(size_t tokenc, Token** tokenv); +void parser_destroy(Parser* parser); + +void parser_inc(Parser* parser); + #endif diff --git a/src/include/stack.h b/src/include/stack.h new file mode 100644 index 0000000..d0776c0 --- /dev/null +++ b/src/include/stack.h @@ -0,0 +1,20 @@ +#ifndef STACK_H +#define STACK_H + +#include + +#define STACK_MAX 64 + +typedef struct { + size_t i; + void* val[STACK_MAX]; +} Stack; + +Stack* stack_init(); +// stack->i must be 0. +void stack_destroy(Stack* stack); + +void stack_push(Stack* stack, void* val); +void* stack_pop(Stack* stack); + +#endif diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..fa6b0e1 --- /dev/null +++ b/src/parser.c @@ -0,0 +1,24 @@ +#include "include/util.h" +#include "include/parser.h" + +Parser* parser_init(size_t tokenc, Token** tokenv) { + talloc(Parser, parser); + + parser->tokenc = tokenc; + parser->ctoken = *tokenv; + parser->tokenv = tokenv; + parser->ast = NULL; + + return parser; +} + +void parser_destroy(Parser* parser) { + if (!parser) return; + + // Also frees parser->ctoken. + for (int i = 0; i < parser->tokenc; i++) token_destroy(parser->tokenv[i]); + + ast_destroy(parser->ast); +} + + diff --git a/src/stack.c b/src/stack.c new file mode 100644 index 0000000..b84f6de --- /dev/null +++ b/src/stack.c @@ -0,0 +1,40 @@ +#include +#include +#include + +#include "include/util.h" +#include "include/stack.h" + +Stack* stack_init() { + talloc(Stack, stack); + + memset(stack->val, 0, sizeof(void*) * STACK_MAX); + stack->i = 0; + + return stack; +} + +void stack_destroy(Stack* stack) { + // Can only free an empty stack. + assert(stack->i == 0); + free(stack); +} + +void stack_push(Stack* stack, void* val) { + if (stack->i >= STACK_MAX) { + log_dbgf("Ran out of stack (max: %d)", STACK_MAX); + return; + } + + stack->val[stack->i] = val; + stack->i++; +} + +void* stack_pop(Stack* stack) { + if (stack->i <= 0) { + log_dbg("Can't pop empty stack."); + return (void*)-1; + } + + return stack->val[--stack->i]; +}