aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-06-07 10:47:47 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:36:46 +0200
commit53a331bc8b2fc33bd2b7e25a23b4128f89ee0b52 (patch)
tree2e5c0f4cda85b2afdb6142145fa7ded61d100f02 /include
parent1b68fdcf5aebf2bc53bbd9234c77aea243c0decd (diff)
Add assignment, while, extern, function signature type, start on bytecode
Diffstat (limited to 'include')
-rw-r--r--include/ast.h67
-rw-r--r--include/binop_type.h3
-rw-r--r--include/ssa/ssa.h28
-rw-r--r--include/std/misc.h6
-rw-r--r--include/tokenizer.h8
5 files changed, 91 insertions, 21 deletions
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 <stdarg.h>
#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, ...);