From 81c5f8e750fcda6a2451fb54604130431434f88f Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 17 Aug 2019 02:57:08 +0200 Subject: Implement more instructions, implement function parameters and arguments --- include/ast.h | 108 +++++++++++++++++++++++++++++++++++--------- include/bytecode/bytecode.h | 2 +- include/compiler.h | 2 + include/nullable.h | 2 - include/program.h | 7 ++- include/ssa/ssa.h | 4 +- include/std/buffer_view.h | 1 + include/std/misc.h | 9 ---- include/std/types.h | 9 ++++ include/tokenizer.h | 3 +- 10 files changed, 109 insertions(+), 38 deletions(-) (limited to 'include') diff --git a/include/ast.h b/include/ast.h index d89d099..1198a98 100644 --- a/include/ast.h +++ b/include/ast.h @@ -19,6 +19,7 @@ #define AST_ERR_DEF_DUP -20 typedef struct Ast Ast; +typedef struct FunctionParameter FunctionParameter; typedef struct FunctionSignature FunctionSignature; typedef struct FunctionCall FunctionCall; typedef struct StructDecl StructDecl; @@ -33,6 +34,7 @@ typedef struct Binop Binop; typedef struct IfStatement IfStatement; typedef struct ElseIfStatement ElseIfStatement; typedef struct WhileStatement WhileStatement; +typedef struct ReturnExpr ReturnExpr; /* TODO: Instead of using pointers, use the data directly */ typedef union { @@ -50,6 +52,7 @@ typedef union { Binop *binop; IfStatement *if_stmt; WhileStatement *while_stmt; + ReturnExpr *return_expr; } AstValue; typedef enum { @@ -65,7 +68,8 @@ typedef enum { AST_VARIABLE, AST_BINOP, AST_IF_STATEMENT, - AST_WHILE_STATEMENT + AST_WHILE_STATEMENT, + AST_RETURN } AstType; typedef enum { @@ -75,17 +79,50 @@ typedef enum { AST_SSA_RESOLVED } AstResolveStatus; +typedef enum { + RESOLVED_TYPE_NONE, + RESOLVED_TYPE_LHS_EXPR, + RESOLVED_TYPE_FUNC_SIG +} AstResolvedTypeEnum; + typedef struct { - LhsExpr *type; + union { + LhsExpr *lhs_expr; + FunctionSignature *func_sig; + } value; + AstResolvedTypeEnum type; +} AstResolvedType; + +typedef struct { + AstResolvedType type; AstResolveStatus status; - Parser *parser; /* Borrowed. This is the parser that is currently parsing the expression */ + SsaRegister ssa_reg; } AstResolveData; +typedef enum { + NAMED_OBJECT_NONE, + NAMED_OBJECT_LHS_EXPR, + NAMED_OBJECT_FUNC_PARAM +} ScopeNamedObjectType; + +typedef struct { + union { + LhsExpr *lhs_expr; + FunctionParameter *func_param; + } value; + ScopeNamedObjectType type; + AstResolveData *resolve_data; /* Borrowed from @value.func_param or from the Ast @value.lhs_expr belongs to */ +} ScopeNamedObject; + struct Ast { AstValue value; AstType type; AstResolveData resolve_data; - SsaRegister ssa_reg; + /* + Borrowed. This is the parser (thread) that is currently parsing the expression. + TODO: Move this to LhsExpr + */ + Parser *parser; }; struct Scope { @@ -94,8 +131,22 @@ struct Scope { Scope *parent; /* Is null unless the scope is a file scope, in which case this is the parser that owns the scope */ Parser *parser; + FunctionSignature *function_signature; /* Borrowed from FunctionDecl. Only used if the scope belongs to FunctionDecl */ }; +typedef struct { + enum { + VARIABLE_TYPE_NONE, + VARIABLE_TYPE_VARIABLE, + VARIABLE_TYPE_SIGNATURE + } type; + + union { + Variable *variable; + FunctionSignature *signature; + } value; +} VariableType; + struct FileScopeReference { Parser *parser; Buffer canonical_path; @@ -103,15 +154,30 @@ struct FileScopeReference { struct Variable { BufferView name; - Ast *resolved_var; /* resolved_var will always be a LhsExpr after resolved */ + ScopeNamedObject resolved_var; +}; + +struct FunctionParameter { + BufferView name; + VariableType type; + AstResolveData resolve_data; }; +typedef struct { + VariableType type; + AstResolvedType resolved_type; +} FunctionReturnType; + struct FunctionSignature { - int params; /* TODO: Implement signatures */ + Buffer/*FunctionParameter*/ parameters; + Buffer/*FunctionReturnType*/ return_types; + /* Borrowed from the FunctionDecl the function signature belongs to. This is used to access the scope the function signature belongs to */ + FunctionDecl *func_decl; bool resolved; }; struct FunctionDecl { + LhsExpr *lhs_expr; /* Borrowed from the LhsExpr that owns this FunctionDecl if it exists, otherwise NULL */ FunctionSignature *signature; Scope body; SsaFuncIndex ssa_func_index; @@ -128,22 +194,9 @@ struct StructDecl { struct StructField { BufferView name; - Variable type; + VariableType type; }; -typedef struct { - enum { - VARIABLE_TYPE_NONE, - VARIABLE_TYPE_VARIABLE, - VARIABLE_TYPE_SIGNATURE - } type; - - union { - Variable *variable; - FunctionSignature *signature; - } value; -} VariableType; - typedef enum { DECL_FLAG_NONE = 0, DECL_FLAG_EXTERN = 1 << 0, @@ -221,6 +274,10 @@ struct WhileStatement { Scope body; }; +struct ReturnExpr { + Ast *rhs_expr; +}; + typedef struct { jmp_buf env; amal_compiler *compiler; /* Borrowed */ @@ -235,12 +292,18 @@ typedef struct { CHECK_RESULT int ast_create(ArenaAllocator *allocator, void *value, AstType type, Ast **result); BufferView ast_get_name(Ast *self); -void function_signature_init(FunctionSignature *self); +CHECK_RESULT int function_signature_init(FunctionSignature *self, ArenaAllocator *allocator); +/* Adds a copy of @param to the function signature parameter list */ +CHECK_RESULT int function_signature_add_parameter(FunctionSignature *self, const FunctionParameter *param); +/* Adds a copy of @return_type to the function signature return type list */ +CHECK_RESULT int function_signature_add_return_type(FunctionSignature *self, const VariableType *return_type); +void function_parameter_init(FunctionParameter *self); CHECK_RESULT int funcdecl_init(FunctionDecl *self, FunctionSignature *signature, Scope *parent, ArenaAllocator *allocator); CHECK_RESULT int funccall_init(FunctionCall *self, BufferView name, ArenaAllocator *allocator); CHECK_RESULT int structdecl_init(StructDecl *self, Scope *parent, ArenaAllocator *allocator); LhsExpr* structdecl_get_field_by_name(StructDecl *self, BufferView field_name); -void structfield_init(StructField *self, BufferView name, BufferView type_name); +/* Copies @type */ +void structfield_init(StructField *self, BufferView name, VariableType *type); void lhsexpr_init(LhsExpr *self, DeclFlag decl_flag, BufferView var_name); void assignmentexpr_init(AssignmentExpr *self, Ast *lhs_expr, Ast *rhs_expr); void import_init(Import *self, BufferView path); @@ -251,6 +314,7 @@ void binop_init(Binop *self); CHECK_RESULT int if_statement_init(IfStatement *self, Scope *parent, ArenaAllocator *allocator); CHECK_RESULT int else_if_statement_init(ElseIfStatement *self, Scope *parent, ArenaAllocator *allocator); CHECK_RESULT int while_statement_init(WhileStatement *self, Scope *parent, ArenaAllocator *allocator); +void return_expr_init(ReturnExpr *self, Ast *rhs_expr); CHECK_RESULT int scope_init(Scope *self, Scope *parent, ArenaAllocator *allocator); CHECK_RESULT int file_scope_reference_init(FileScopeReference *self, BufferView canonical_path, ArenaAllocator *allocator); diff --git a/include/bytecode/bytecode.h b/include/bytecode/bytecode.h index 4c54fbd..adad291 100644 --- a/include/bytecode/bytecode.h +++ b/include/bytecode/bytecode.h @@ -48,7 +48,7 @@ typedef enum { AMAL_OP_CMP, /* cmp dst, reg1, reg2 - Set dst to 1 if reg1 equals reg2, otherwise set it to 0 */ AMAL_OP_JZ, /* jz reg, offset - Jump to offset if reg is zero. offset is i16 */ AMAL_OP_JMP, /* jmp offset - Unconditional jump to offset. offset is i16 */ - AMAL_OP_RET, /* ret - Return from the function */ + AMAL_OP_RET, /* ret reg - Return from the function with reg result */ AMAL_OP_FUNC_START, /* func_start num_reg - Start of a function which has num_reg registers allocated. num_reg is a u16 */ AMAL_OP_FUNC_END /* func_end - End of a function. Implementation should do a ret here */ } AmalOpcode; diff --git a/include/compiler.h b/include/compiler.h index 83dde63..08b74b8 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -13,6 +13,7 @@ #define AMAL_COMPILER_OK 0 /* General error */ #define AMAL_COMPILER_ERR -1 +#define AMAL_COMPILER_WORK_FAIL_ABORT -2 #define NUM_ARITHMETIC_TYPES 10 @@ -53,6 +54,7 @@ struct amal_compiler { ParserThreadData *threads; int usable_thread_count; bool started; + bool work_failed; amal_mutex mutex; int generic_work_object_index; }; diff --git a/include/nullable.h b/include/nullable.h index f38fb37..961b210 100644 --- a/include/nullable.h +++ b/include/nullable.h @@ -1,8 +1,6 @@ #ifndef AMAL_NULLABLE_H #define AMAL_NULLABLE_H -struct __nullable_type_dummy{ int _; }; - /* Used by static analysis tool to find null-pointer dereference errors */ #define nullable __attribute__((annotate("nullable"))) diff --git a/include/program.h b/include/program.h index b98c0a6..6603c63 100644 --- a/include/program.h +++ b/include/program.h @@ -6,7 +6,8 @@ #include "../executor/executor.h" #define AMAL_PROGRAM_OK 0 -#define AMAL_PROGRAM_INVALID_HEADER -1 +#define AMAL_PROGRAM_ERR -1 +#define AMAL_PROGRAM_INVALID_HEADER -16 #define AMAL_PROGRAM_INVALID_MAGIC_NUMBER -2 #define AMAL_PROGRAM_INCOMPATIBLE -3 #define AMAL_PROGRAM_INVALID_INTERMEDIATES -4 @@ -21,6 +22,7 @@ #define AMAL_PROGRAM_INSTRUCTION_STACK_OVERFLOW -13 #define AMAL_PROGRAM_INSTRUCTION_STACK_OOM -14 #define AMAL_PROGRAM_INSTRUCTION_ILLEGAL_JUMP_TARGET -15 +#define AMAL_PROGRAM_INVALID_FUNCTIONS -16 #define AMAL_PROGRAM_MAGIC_NUMBER (u32)0xdec05eba #define AMAL_PROGRAM_MAJOR_VERSION 1 @@ -36,8 +38,9 @@ typedef struct { char *strings_start; /* Reference inside @data */ usize read_index; - u16 num_strings; u16 num_intermediates; + u16 num_strings; + u16 num_functions; } amal_program; CHECK_RESULT int amal_program_init(amal_program *self); diff --git a/include/ssa/ssa.h b/include/ssa/ssa.h index 016acc8..21d7f40 100644 --- a/include/ssa/ssa.h +++ b/include/ssa/ssa.h @@ -24,7 +24,8 @@ typedef enum { SSA_PUSH, SSA_CALL, SSA_JUMP_ZERO, - SSA_JUMP + SSA_JUMP, + SSA_RET } SsaInstruction; typedef enum { @@ -75,6 +76,7 @@ typedef struct { } SsaInsFuncStart; typedef struct { + u8 num_args; SsaRegister result; FunctionDecl *func_decl; } SsaInsFuncCall; diff --git a/include/std/buffer_view.h b/include/std/buffer_view.h index 4993dc2..59a97d3 100644 --- a/include/std/buffer_view.h +++ b/include/std/buffer_view.h @@ -10,5 +10,6 @@ typedef struct { BufferView create_buffer_view_null(); BufferView create_buffer_view(const char *data, usize size); +bool buffer_view_equals(const BufferView *self, const BufferView *other); #endif diff --git a/include/std/misc.h b/include/std/misc.h index 2fbe92c..e89f1eb 100644 --- a/include/std/misc.h +++ b/include/std/misc.h @@ -41,13 +41,4 @@ #define ignore_result_int(expr) (void)((expr)+1) -typedef enum { - bool_false, - bool_true -} bool; - -#ifndef NULL -#define NULL ((void*)0) -#endif - #endif diff --git a/include/std/types.h b/include/std/types.h index a8a44fd..bbf31c5 100644 --- a/include/std/types.h +++ b/include/std/types.h @@ -20,4 +20,13 @@ typedef size_t usize; typedef float f32; typedef double f64; +typedef enum { + bool_false, + bool_true +} bool; + +#ifndef NULL +#define NULL ((void*)0) +#endif + #endif diff --git a/include/tokenizer.h b/include/tokenizer.h index f624816..16123cc 100644 --- a/include/tokenizer.h +++ b/include/tokenizer.h @@ -37,7 +37,8 @@ typedef enum { TOK_IF, TOK_ELSE, TOK_WHILE, - TOK_EXTERN + TOK_EXTERN, + TOK_RETURN } Token; typedef struct { -- cgit v1.2.3