diff options
-rwxr-xr-x | build.sh | 8 | ||||
-rw-r--r-- | include/ast.h | 2 | ||||
-rw-r--r-- | include/ssa/ssa.h | 7 | ||||
-rw-r--r-- | src/ast.c | 4 | ||||
-rw-r--r-- | src/compiler.c | 3 | ||||
-rw-r--r-- | src/parser.c | 13 | ||||
-rw-r--r-- | src/ssa/ssa.c | 58 |
7 files changed, 75 insertions, 20 deletions
@@ -20,11 +20,15 @@ fi CFLAGS+="-Wall -Wextra -Werror -g -O0 -DDEBUG -std=c89 -pedantic -D_GNU_SOURCE" LIBS+="-pthread" +BUILD_ARGS="$source_files $CFLAGS $LIBS -shared -fpic -o libamalgam.so" set -x -time "$CC" $source_files $CFLAGS $LIBS -shared -fpic -o libamalgam.so +time "$CC" $BUILD_ARGS +if [ ! -z "$SCAN_BUILD" ]; then + scan-build "$CC" $BUILD_ARGS +fi set +x if [ -z "$NO_TEST" ]; then source_files_tests=$(readlink -f $(find "$this_script_dir/tests" -name "*.c")) set -x time "$CC" $source_files_tests $CFLAGS $LIBS -o test "$this_script_dir/libamalgam.so" -fi
\ No newline at end of file +fi diff --git a/include/ast.h b/include/ast.h index b63dab5..ae9b6b3 100644 --- a/include/ast.h +++ b/include/ast.h @@ -8,6 +8,7 @@ #include "std/scoped_allocator.h" #include "std/hash_map.h" #include "binop_type.h" +#include "ssa/ssa.h" #include <setjmp.h> @@ -67,6 +68,7 @@ struct Scope { struct FunctionDecl { Scope body; + SsaFuncIndex ssa_func_index; }; struct FunctionCall { diff --git a/include/ssa/ssa.h b/include/ssa/ssa.h index 5411259..c374ffb 100644 --- a/include/ssa/ssa.h +++ b/include/ssa/ssa.h @@ -10,6 +10,7 @@ typedef enum { SSA_ASSIGN_INTER, + SSA_ASSIGN_STRING, SSA_ASSIGN_REG, SSA_ADD, SSA_SUB, @@ -36,12 +37,15 @@ typedef struct { typedef u16 SsaRegister; typedef u16 SsaIntermediateIndex; +typedef u16 SsaStringIndex; typedef u32 SsaFuncIndex; typedef struct { Buffer/*instruction data*/ instructions; - HashMap/*<SsaNumberType, IntermediateIndex>*/ intermediates; + HashMap/*<SsaNumberType, SsaIntermediateIndex>*/ intermediates; + HashMap/*<BufferView, SsaStringIndex>*/ strings; SsaIntermediateIndex intermediate_counter; + SsaStringIndex string_counter; SsaRegister reg_counter; SsaFuncIndex func_counter; } Ssa; @@ -53,6 +57,7 @@ SsaNumber create_ssa_float(f64 value); CHECK_RESULT int ssa_init(Ssa *self, ScopedAllocator *allocator); CHECK_RESULT int ssa_get_unique_reg(Ssa *self, SsaRegister *result); CHECK_RESULT int ssa_ins_assign_inter(Ssa *self, SsaRegister dest, SsaNumber number); +CHECK_RESULT int ssa_ins_assign_string(Ssa *self, SsaRegister dest, BufferView str); CHECK_RESULT int ssa_ins_assign_reg(Ssa *self, SsaRegister dest, SsaRegister src); CHECK_RESULT int ssa_ins_binop(Ssa *self, SsaInstructionType binop_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result); CHECK_RESULT int ssa_ins_func_start(Ssa *self, u8 num_args, SsaFuncIndex *result); @@ -54,6 +54,7 @@ BufferView ast_get_name(Ast *self) { } int funcdecl_init(FunctionDecl *self, ScopedAllocator *allocator) { + self->ssa_func_index = 0; return scope_init(&self->body, allocator); } @@ -223,5 +224,6 @@ void ast_resolve(Ast *self, AstCompilerContext *context) { binop_resolve(self->value.binop, context); break; } - /*self->resolve_status = AST_RESOLVED;*/ + /* TODO: See comment at the top of this function */ + self->resolve_status = AST_RESOLVED; } diff --git a/src/compiler.c b/src/compiler.c index 08d0225..4e097ce 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -54,8 +54,7 @@ int amal_compiler_init(amal_compiler *self) { return AMAL_COMPILER_OK; cleanup: - /* Ignore result */ - result = amal_compiler_deinit(self); + ignore_result_int(amal_compiler_deinit(self)); return AMAL_COMPILER_ERR; } diff --git a/src/parser.c b/src/parser.c index f531705..1e51af4 100644 --- a/src/parser.c +++ b/src/parser.c @@ -115,11 +115,12 @@ static THROWABLE parser_parse_var_type_def(Parser *self, BufferView *type_name) LHS = ('const' TOK_IDENTIFIER VAR_TYPE_DEF? '=') | ('var' TOK_IDENTIFIER VAR_TYPE_DEF? '='|';') */ -static THROWABLE parser_parse_lhs(Parser *self, LhsExpr **result, bool *assignment) { +static THROWABLE parser_parse_lhs(Parser *self, LhsExpr **result, bool *assignment_or_rhs) { bool is_const; bool match; BufferView var_name; *result = NULL; + *assignment_or_rhs = bool_true; throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_CONST, &is_const)); if(!is_const) { @@ -138,11 +139,11 @@ static THROWABLE parser_parse_lhs(Parser *self, LhsExpr **result, bool *assignme throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_EQUALS, &match)); if(match) { - *assignment = bool_true; + *assignment_or_rhs = bool_true; return PARSER_OK; } - *assignment = bool_false; + *assignment_or_rhs = bool_false; throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_SEMICOLON, &match)); if(match && is_const) { self->error = tokenizer_create_error(&self->tokenizer, @@ -426,13 +427,13 @@ BODY = LHS ';' | (RHS_START BODY_SEMICOLON) */ int parser_parse_body(Parser *self, Ast *ast) { - bool assignment; + bool assignment_or_rhs; LhsExpr *lhs_expr; Ast rhs_expr; rhs_expr = ast_none(); - try(parser_parse_lhs(self, &lhs_expr, &assignment)); - if(!assignment) { + try(parser_parse_lhs(self, &lhs_expr, &assignment_or_rhs)); + if(!assignment_or_rhs) { ast_init(ast, lhs_expr, AST_LHS); return PARSER_OK; } diff --git a/src/ssa/ssa.c b/src/ssa/ssa.c index 1b5ed3d..b8aa8b0 100644 --- a/src/ssa/ssa.c +++ b/src/ssa/ssa.c @@ -1,6 +1,7 @@ #include "../../include/ssa/ssa.h" #include "../../include/std/mem.h" #include "../../include/std/log.h" +#include "../../include/std/hash.h" #include "../../include/ast.h" #include <assert.h> @@ -47,7 +48,9 @@ SsaNumber create_ssa_float(f64 value) { int ssa_init(Ssa *self, ScopedAllocator *allocator) { return_if_error(buffer_init(&self->instructions, allocator)); return_if_error(hash_map_init(&self->intermediates, allocator, sizeof(SsaIntermediateIndex), compare_number, hash_number)); + return_if_error(hash_map_init(&self->strings, allocator, sizeof(SsaStringIndex), hash_compare_string, amal_hash_string)); self->intermediate_counter = 0; + self->string_counter = 0; self->reg_counter = 0; self->func_counter = 0; return 0; @@ -91,6 +94,24 @@ static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, SsaNumber number, Ss return hash_map_insert(&self->intermediates, key, result_index); } +static CHECK_RESULT int ssa_try_add_string(Ssa *self, BufferView str, SsaStringIndex *result_index) { + bool exists; + assert(result_index); + + exists = hash_map_get(&self->strings, str, result_index); + if(exists) + return 0; + + /* Overflow */ + if(self->string_counter + 1 < self->string_counter) + return -1; + + *result_index = self->string_counter; + ++self->string_counter; + amal_log_debug("s%u = \"%.*s\"", *result_index, str.size, str.data); + return hash_map_insert(&self->strings, str, result_index); +} + static CHECK_RESULT int ssa_add_ins_form1(Ssa *self, SsaInstructionType ins_type, SsaRegister lhs, u16 rhs) { usize index; index = self->instructions.size; @@ -128,6 +149,13 @@ int ssa_ins_assign_inter(Ssa *self, SsaRegister dest, SsaNumber number) { return ssa_add_ins_form1(self, SSA_ASSIGN_INTER, dest, index); } +int ssa_ins_assign_string(Ssa *self, SsaRegister dest, BufferView str) { + SsaStringIndex index; + return_if_error(ssa_try_add_string(self, str, &index)); + amal_log_debug("r%u = s%u", dest, index); + return ssa_add_ins_form1(self, SSA_ASSIGN_STRING, dest, index); +} + int ssa_ins_assign_reg(Ssa *self, SsaRegister dest, SsaRegister src) { amal_log_debug("r%u = r%u", dest, src); return ssa_add_ins_form1(self, SSA_ASSIGN_INTER, dest, src); @@ -208,30 +236,43 @@ static CHECK_RESULT SsaRegister number_generate_ssa(Number *self, SsaCompilerCon static CHECK_RESULT SsaRegister funcdecl_generate_ssa(FunctionDecl *self, SsaCompilerContext *context) { /* TODO: Implement */ + throw_if_error(ssa_ins_func_start(&context->ssa, 0, &self->ssa_func_index)); scope_generate_ssa(&self->body, context); + throw_if_error(ssa_ins_func_end(&context->ssa)); return 0; } static CHECK_RESULT SsaRegister funccall_generate_ssa(FunctionCall *self, SsaCompilerContext *context) { /* TODO: Implement */ - (void)self; - (void)context; - return 0; + Ast *ast; + Ast *ast_end; + SsaRegister reg; + + ast = buffer_start(&self->args); + ast_end = buffer_end(&self->args); + for(; ast != ast_end; ++ast) { + SsaRegister arg_reg; + arg_reg = ast_generate_ssa(ast, context); + throw_if_error(ssa_ins_push(&context->ssa, arg_reg)); + } + /* TODO: Use real func index */ + throw_if_error(ssa_ins_call(&context->ssa, 0, ®)); + return reg; } static CHECK_RESULT SsaRegister lhs_generate_ssa(LhsExpr *self, SsaCompilerContext *context) { /* TODO: Implement */ SsaRegister rhs_reg; - amal_log_debug("lhs_generate_ssa"); rhs_reg = ast_generate_ssa(&self->rhs_expr, context); + /* TODO: Is this correct? */ return rhs_reg; } static CHECK_RESULT SsaRegister string_generate_ssa(String *self, SsaCompilerContext *context) { - /* TODO: Implement */ - (void)self; - (void)context; - return 0; + SsaRegister reg; + throw_if_error(ssa_get_unique_reg(&context->ssa, ®)); + throw_if_error(ssa_ins_assign_string(&context->ssa, reg, self->str)); + return reg; } static CHECK_RESULT SsaRegister variable_generate_ssa(Variable *self, SsaCompilerContext *context) { @@ -269,6 +310,7 @@ static CHECK_RESULT SsaRegister binop_generate_ssa(Binop *self, SsaCompilerConte } CHECK_RESULT SsaRegister ast_generate_ssa(Ast *self, SsaCompilerContext *context) { + assert(self->resolve_status == AST_RESOLVED); switch(self->type) { case AST_NONE: return 0; |