From 53a331bc8b2fc33bd2b7e25a23b4128f89ee0b52 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 7 Jun 2019 10:47:47 +0200 Subject: Add assignment, while, extern, function signature type, start on bytecode --- include/ast.h | 67 ++++++++++++++++++++++++++++++++++++++++++++++++---- include/binop_type.h | 3 ++- include/ssa/ssa.h | 28 ++++++++++++---------- include/std/misc.h | 6 ++--- include/tokenizer.h | 8 ++++++- 5 files changed, 91 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/include/ast.h b/include/ast.h index c40be22..34e62b8 100644 --- a/include/ast.h +++ b/include/ast.h @@ -17,16 +17,22 @@ #define AST_ERR -1 #define AST_ERR_DEF_DUP -20 +typedef struct FunctionSignature FunctionSignature; typedef struct FunctionCall FunctionCall; typedef struct StructDecl StructDecl; typedef struct StructField StructField; typedef struct LhsExpr LhsExpr; +typedef struct AssignmentExpr AssignmentExpr; typedef struct Import Import; typedef struct String String; typedef struct Variable Variable; typedef struct Number Number; typedef struct Binop Binop; +typedef struct IfStatement IfStatement; +typedef struct ElseIfStatement ElseIfStatement; +typedef struct WhileStatement WhileStatement; +/* TODO: Instead of using pointers, use the data directly */ typedef union { void *data; FunctionDecl *func_decl; @@ -34,11 +40,14 @@ typedef union { StructDecl *struct_decl; StructField *struct_field; LhsExpr *lhs_expr; + AssignmentExpr *assign_expr; Import *import; String *string; Number *number; Variable *variable; Binop *binop; + IfStatement *if_stmt; + WhileStatement *while_stmt; } AstValue; typedef enum { @@ -47,11 +56,14 @@ typedef enum { AST_STRUCT_DECL, AST_STRUCT_FIELD, AST_LHS, + AST_ASSIGN, AST_IMPORT, AST_STRING, AST_NUMBER, AST_VARIABLE, - AST_BINOP + AST_BINOP, + AST_IF_STATEMENT, + AST_WHILE_STATEMENT } AstType; typedef enum { @@ -88,9 +100,15 @@ struct FileScopeReference { struct Variable { BufferView name; + Ast *resolved_var; /* resolved_var will always be a LhsExpr after resolved */ +}; + +struct FunctionSignature { + int params; /* TODO: Implement signatures */ }; struct FunctionDecl { + FunctionSignature *signature; Scope body; SsaFuncIndex ssa_func_index; }; @@ -109,11 +127,25 @@ struct StructField { Variable type; }; +typedef struct { + enum { + VARIABLE_TYPE_NONE, + VARIABLE_TYPE_VARIABLE, + VARIABLE_TYPE_SIGNATURE + } type; + + union { + Variable *variable; + FunctionSignature *signature; + } value; +} VariableType; + struct LhsExpr { + bool is_extern; bool is_pub; bool is_const; BufferView var_name; - Variable type; + VariableType type; Ast *rhs_expr; /* TODO: Find a better way to store this. This most likely will use too much memory. @@ -121,6 +153,11 @@ struct LhsExpr { amal_mutex *mutex; }; +struct AssignmentExpr { + Ast *lhs_expr; + Ast *rhs_expr; +}; + struct Import { BufferView path; FileScopeReference *file_scope; @@ -147,6 +184,24 @@ struct Binop { bool grouped; }; +struct IfStatement { + Ast *condition; + Scope body; + ElseIfStatement *else_if_stmt; +}; + +/* ElseIfStatement where condition == NULL is an Else statement */ +struct ElseIfStatement { + Ast *condition; + Scope body; + ElseIfStatement *next_else_if_stmt; +}; + +struct WhileStatement { + Ast *condition; + Scope body; +}; + typedef struct { jmp_buf env; amal_compiler *compiler; @@ -156,16 +211,20 @@ typedef struct { CHECK_RESULT int ast_create(ScopedAllocator *allocator, void *value, AstType type, Ast **result); BufferView ast_get_name(Ast *self); -CHECK_RESULT int funcdecl_init(FunctionDecl *self, Scope *parent, ScopedAllocator *allocator); +CHECK_RESULT int funcdecl_init(FunctionDecl *self, FunctionSignature *signature, Scope *parent, ScopedAllocator *allocator); CHECK_RESULT int funccall_init(FunctionCall *self, BufferView name, ScopedAllocator *allocator); CHECK_RESULT int structdecl_init(StructDecl *self, Scope *parent, ScopedAllocator *allocator); void structfield_init(StructField *self, BufferView name, BufferView type_name); -CHECK_RESULT int lhsexpr_init(LhsExpr *self, bool is_pub, bool is_const, BufferView var_name, ScopedAllocator *allocator); +CHECK_RESULT int lhsexpr_init(LhsExpr *self, bool is_extern, bool is_pub, bool is_const, BufferView var_name, ScopedAllocator *allocator); +void assignmentexpr_init(AssignmentExpr *self, Ast *lhs_expr, Ast *rhs_expr); void import_init(Import *self, BufferView path); CHECK_RESULT int string_init(String *self, BufferView str); void number_init(Number *self, i64 value, bool is_integer, BufferView code_ref); void variable_init(Variable *self, BufferView name); void binop_init(Binop *self); +CHECK_RESULT int if_statement_init(IfStatement *self, Scope *parent, ScopedAllocator *allocator); +CHECK_RESULT int else_if_statement_init(ElseIfStatement *self, Scope *parent, ScopedAllocator *allocator); +CHECK_RESULT int while_statement_init(WhileStatement *self, Scope *parent, ScopedAllocator *allocator); CHECK_RESULT int scope_init(Scope *self, Scope *parent, ScopedAllocator *allocator); CHECK_RESULT int file_scope_reference_init(FileScopeReference *self, BufferView canonical_path, ScopedAllocator *allocator); diff --git a/include/binop_type.h b/include/binop_type.h index e747102..502392c 100644 --- a/include/binop_type.h +++ b/include/binop_type.h @@ -6,7 +6,8 @@ typedef enum { BINOP_SUB, BINOP_MUL, BINOP_DIV, - BINOP_DOT + BINOP_DOT, + BINOP_EQUALS } BinopType; #endif diff --git a/include/ssa/ssa.h b/include/ssa/ssa.h index e1e2d01..15a9f78 100644 --- a/include/ssa/ssa.h +++ b/include/ssa/ssa.h @@ -16,10 +16,13 @@ typedef enum { SSA_SUB, SSA_MUL, SSA_DIV, + SSA_EQUALS, SSA_FUNC_START, SSA_FUNC_END, SSA_PUSH, - SSA_CALL + SSA_CALL, + SSA_JUMP_ZERO, + SSA_JUMP } SsaInstruction; typedef enum { @@ -35,10 +38,11 @@ typedef struct { SsaNumberType type; } SsaNumber; +typedef i16 JumpOffset; typedef u16 SsaRegister; typedef u16 SsaIntermediateIndex; typedef u16 SsaStringIndex; -typedef usize SsaFuncIndex; +typedef u16 SsaFuncIndex; typedef struct { Buffer/*instruction data*/ instructions; @@ -73,6 +77,15 @@ typedef struct { FunctionDecl *func_decl; } SsaInsFuncCall; +typedef struct { + SsaRegister condition_reg; + JumpOffset jump_offset; +} SsaInsJumpZero; + +typedef struct { + JumpOffset jump_offset; +} SsaInsJump; + /* None of these functions are thread-safe */ SsaNumber create_ssa_integer(i64 value); SsaNumber create_ssa_float(f64 value); @@ -81,20 +94,11 @@ SsaNumber ssa_get_intermediate(Ssa *self, SsaIntermediateIndex index); BufferView ssa_get_string(Ssa *self, SsaStringIndex index); 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, SsaInstruction binop_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result); -CHECK_RESULT int ssa_ins_func_start(Ssa *self, u8 num_args, SsaFuncIndex *result); -CHECK_RESULT int ssa_ins_func_end(Ssa *self); -CHECK_RESULT int ssa_ins_push(Ssa *self, SsaRegister reg); -CHECK_RESULT int ssa_ins_call(Ssa *self, FunctionDecl *func_decl, SsaRegister *result); - typedef struct { jmp_buf env; Ssa *ssa; + amal_compiler *compiler; } SsaCompilerContext; /* longjump to context->env on failure */ diff --git a/include/std/misc.h b/include/std/misc.h index 2549c22..b1932d5 100644 --- a/include/std/misc.h +++ b/include/std/misc.h @@ -8,15 +8,15 @@ #ifdef AMAL_PEDANTIC #define throw_debug_msg do {} while(0) #else - #define throw_debug_msg do { amal_log_error("Throwing from %s:%d", __FUNCTION__, __LINE__); } while(0) + #define throw_debug_msg do { amal_log_error("Throwing from %s:%d", __FILE__, __LINE__); } while(0) #endif #ifdef AMAL_PEDANTIC #define return_if_debug_msg do {} while(0) #define cleanup_if_debug_msg do {} while(0) #else - #define return_if_debug_msg do { amal_log_error("Return from %s:%d", __FUNCTION__, __LINE__); } while(0) - #define cleanup_if_debug_msg do { amal_log_error("cleanup from %s:%d", __FUNCTION__, __LINE__); } while(0) + #define return_if_debug_msg do { amal_log_error("Return from %s:%d", __FILE__, __LINE__); } while(0) + #define cleanup_if_debug_msg do { amal_log_error("cleanup from %s:%d", __FILE__, __LINE__); } while(0) #endif #define return_if_error(result) \ diff --git a/include/tokenizer.h b/include/tokenizer.h index d10b789..4018e3a 100644 --- a/include/tokenizer.h +++ b/include/tokenizer.h @@ -6,6 +6,7 @@ #include "std/defs.h" #include "binop_type.h" #include "compiler_options.h" +#include #define TOKENIZER_OK 0 /* General error */ @@ -32,7 +33,11 @@ typedef enum { TOK_SEMICOLON, TOK_COLON, TOK_BINOP, - TOK_PUB + TOK_PUB, + TOK_IF, + TOK_ELSE, + TOK_WHILE, + TOK_EXTERN } Token; typedef struct { @@ -71,6 +76,7 @@ CHECK_RESULT int tokenizer_accept(Tokenizer *self, Token expected_token); otherwise @result is set to 1 */ CHECK_RESULT int tokenizer_consume_if(Tokenizer *self, Token expected_token, bool *result); +void tokenizer_print_error_args(Tokenizer *self, int index, const char *fmt, va_list args); void tokenizer_print_error(Tokenizer *self, int index, const char *fmt, ...); void tokenizer_print_error_object(Tokenizer *self, TokenizerError *error); TokenizerError tokenizer_create_error(Tokenizer *self, int index, const char *fmt, ...); -- cgit v1.2.3