Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ast/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "ast/ast_stmts.h"
#include "ast/ast_const.h"
#include "ast/ast_struct.h"
#include "ast/ast_enum.h"
#include "ast/ast_var.h"
#include "ast/ast_expr.h"
#include "ast/ast_subr.h"
Expand Down Expand Up @@ -39,6 +40,11 @@ struct Namespace {
uint16_t count_includes;
char** includes;

// enum declarations
struct EnumDecl** enums;
uint16_t count_enums;
size_t capacity_enums;

//structs must be declared before the subroutines
struct StructDecl** structs;
uint16_t count_structs;
Expand Down
20 changes: 20 additions & 0 deletions ast/ast/ast_enum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include "../ast_declare.h"

struct EnumDecl {
struct ASTNode super;

// must be all uppercase (underscores are ok)
char* name;

struct EnumMember** members;
uint16_t count_members;
};

struct EnumMember {
struct ASTNode super;

char* name;
struct ConstValue* value;
};
2 changes: 2 additions & 0 deletions ast/ast/ast_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ enum TERM_KIND {
TERM_KIND_VAR,
TERM_KIND_STRINGCONST,
TERM_KIND_CONSTVALUE,
TERM_KIND_ENUM_VALUE,
};

struct Term {
Expand All @@ -92,6 +93,7 @@ struct Term {
struct Variable* var_term;
struct StringConst* stringconst_term;
struct ConstValue* constvalue_term;
char* enum_value_term;
} ptr;

enum TERM_KIND kind;
Expand Down
1 change: 1 addition & 0 deletions ast/ast_declare.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct AST;
struct Namespace;
struct Method;
struct StructDecl;
struct EnumDecl;
struct MethodDecl;
//---------------
struct StmtBlock;
Expand Down
17 changes: 16 additions & 1 deletion ast/util/free_ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ void free_namespace(struct Namespace* ns) {
free(ns->includes[i]);
}

for (int i = 0; i < ns->count_enums; i++) {
free_enum_decl(ns->enums[i]);
}

for (int i = 0; i < ns->count_methods; i++) {
free_method(ns->methods[i]);
}
Expand All @@ -74,6 +78,7 @@ void free_namespace(struct Namespace* ns) {

free(ns->methods);
free(ns->structs);
free(ns->enums);

free(ns->src_path);
free(ns->token_path);
Expand Down Expand Up @@ -101,6 +106,15 @@ void free_stmt_block(struct StmtBlock* block) {
free(block);
}

void free_enum_decl(struct EnumDecl* ed) {

for (int i = 0; i < ed->count_members; i++) {
free(ed->members[i]->name);
free(ed->members[i]);
}
free(ed);
}

void free_struct_decl(struct StructDecl* sd) {

free_simple_type(sd->type);
Expand All @@ -124,8 +138,9 @@ bool free_term(struct Term* t) {
case TERM_KIND_VAR: free_variable(t->ptr.var_term); break;
case TERM_KIND_STRINGCONST: free_string_const(t->ptr.stringconst_term); break;
case TERM_KIND_CONSTVALUE: free_const_value(t->ptr.constvalue_term); break;
case TERM_KIND_ENUM_VALUE: free(t->ptr.enum_value_term); break;
default:
fprintf(stderr, "Error in free_term(...)\n");
fprintf(stderr, "Error in free_term(...), unhandled case %d\n", t->kind);
free(t);
return false;
}
Expand Down
3 changes: 3 additions & 0 deletions ast/util/free_ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ void free_namespace(struct Namespace* ns);
void free_stmt_block(struct StmtBlock* block);
void free_range(struct Range* range);

// enum
void free_enum_decl(struct EnumDecl* ed);

//struct
void free_struct_decl(struct StructDecl* sd);
void free_struct_member(struct StructMember* sm);
Expand Down
36 changes: 36 additions & 0 deletions ast/visitor/visitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,18 @@ static bool visit_term(struct Term* t, VISITOR, ARG);
//const
static void visit_const_value(struct ConstValue* cv, VISITOR, ARG);
static void visit_string_const(struct StringConst* s, VISITOR, ARG);
static void visit_enum_value(char* s, VISITOR, ARG);

//var
// @returns false on error
static bool visit_variable(struct Variable* v, VISITOR, ARG);
// @returns false on error
static bool visit_simple_var(struct SimpleVar* v, VISITOR, ARG);

// enum
static bool visit_enum_decl(struct EnumDecl* ed, VISITOR, ARG);
static bool visit_enum_member(struct EnumMember* em, VISITOR, ARG);

bool visit_ast(struct AST* ast, VISITOR, void* arg) {

for (int i = 0; i < ast->count_namespaces; i++) {
Expand All @@ -78,6 +83,10 @@ bool visit_namespace(struct Namespace* n, VISITOR, void* arg) {
//we do not visit the passthrough include declarations as they
//are just a workaround for now

for (int i = 0; i < n->count_enums; i++) {
visit_enum_decl(n->enums[i], visitor, arg);
}

for (int i = 0; i < n->count_structs; i++) {
visit_struct_decl(n->structs[i], visitor, arg);
}
Expand All @@ -91,6 +100,25 @@ bool visit_namespace(struct Namespace* n, VISITOR, void* arg) {
return true;
}

static bool visit_enum_decl(struct EnumDecl* ed, VISITOR, ARG) {

visitor(ed, NODE_ENUM_DECL, arg);

for (int i = 0; i < ed->count_members; i++) {
if (!visit_enum_member(ed->members[i], visitor, arg)) {
return false;
}
}

return true;
}

static bool visit_enum_member(struct EnumMember* em, VISITOR, ARG) {

visitor(em, NODE_ENUM_MEMBER, arg);
return true;
}

void visit_struct_decl(struct StructDecl* s, VISITOR, void* arg) {

visitor(s, NODE_STRUCTDECL, arg);
Expand Down Expand Up @@ -346,6 +374,9 @@ static bool visit_term(struct Term* t, VISITOR, void* arg) {
case TERM_KIND_CONSTVALUE:
visit_const_value(t->ptr.constvalue_term, visitor, arg);
break;
case TERM_KIND_ENUM_VALUE:
visit_enum_value(t->ptr.enum_value_term, visitor, arg);
break;
default:
fprintf(stderr, "[Visitor][Error] Fatal(2)\n");
return false;
Expand All @@ -365,6 +396,11 @@ static void visit_string_const(struct StringConst* s, VISITOR, void* arg) {
visitor(s, NODE_STRINGCONST, arg);
}

static void visit_enum_value(char* s, VISITOR, ARG) {

visitor(s, NODE_ENUM_VALUE, arg);
}

static bool visit_variable(struct Variable* v, VISITOR, void* arg) {

visitor(v, NODE_VARIABLE, arg);
Expand Down
4 changes: 4 additions & 0 deletions ast/visitor/visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ enum NODE_TYPE {
NODE_AST,
NODE_NAMESPACE,

NODE_ENUM_DECL,
NODE_ENUM_MEMBER,
NODE_ENUM_VALUE,

NODE_STRUCTDECL,
NODE_STRUCTMEMBER,

Expand Down
4 changes: 3 additions & 1 deletion compiler/main/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ bool compile(struct Flags* flags) {

struct Ctx* ctx = ctx_ctor(flags, st_ctor());

fill_tables(ast, ctx);
if (!fill_tables(ast, ctx)) {
return false;
}

struct TCError* errors = typecheck_ast(ast, ctx, true);

Expand Down
12 changes: 0 additions & 12 deletions compiler/main/gen_tac/gen_tac.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,6 @@
#include "util/ctx.h"
#include "tac/tacbuffer.h"

int int_value_from_const(struct ConstValue* cv) {

switch (cv->kind) {
case 1: return (int)cv->ptr.m1_bool_const;
case 2: return (int)cv->ptr.m2_int_const;
case 3: return (int)cv->ptr.m3_char_const;
case 5: return (int)cv->ptr.m5_hex_const;
case 6: return (int)cv->ptr.m5_hex_const;
}
return -1;
}

void tac_method(struct TACBuffer* buffer, struct Method* m, struct Ctx* ctx) {

const uint32_t index = sst_index_of(ctx_tables(ctx)->sst, m->decl->name);
Expand Down
3 changes: 0 additions & 3 deletions compiler/main/gen_tac/gen_tac.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,3 @@ void tac_constvalue(struct TACBuffer* buffer, struct ConstValue* c);

// @returns false on error
bool tac_const_data(struct TACBuffer* buffer, struct StringConst* c, struct Ctx* ctx);

//----
int int_value_from_const(struct ConstValue* cv);
1 change: 1 addition & 0 deletions compiler/main/gen_tac/gen_tac_constvalue.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "tac/tac.h"
#include "tac/tacbuffer.h"
#include "gen_tac.h"
#include "tables/enum/enum_table.h"

void tac_constvalue(struct TACBuffer* buffer, struct ConstValue* c) {

Expand Down
32 changes: 32 additions & 0 deletions compiler/main/gen_tac/gen_tac_term.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,49 @@
#include <stdio.h>
#include <assert.h>

#include "tac/tacbuffer.h"
#include "tables/symtable/symtable.h"
#include "tables/enum/enum_table.h"

#include "gen_tac.h"

static bool tac_term_enum_value(struct TACBuffer* buffer, struct Term* t, struct Ctx* ctx) {

const struct ST* st = ctx_tables(ctx);
assert(st);

char* name = t->ptr.enum_value_term;
assert(name);

const int64_t value = enum_table_lookup(st->enum_table, name);

if (value < 0) {
fprintf(stderr, "could not find value for '%s' in enum table\n", name);

enum_table_print(st->enum_table);
return false;
}

tacbuffer_append(buffer, makeTACConst(make_temp(), value));

return true;
}

bool tac_term(struct TACBuffer* buffer, struct Term* t, struct Ctx* ctx) {

assert(buffer);
assert(t);
assert(ctx);

switch (t->kind) {
case TERM_KIND_CALL: tac_call(buffer, t->ptr.call_term, ctx); break;
case TERM_KIND_EXPR: tac_expr(buffer, t->ptr.expr_term, ctx); break;
case TERM_KIND_VAR: tac_variable(buffer, t->ptr.var_term, ctx); break;
case TERM_KIND_STRINGCONST: return tac_const_data(buffer, t->ptr.stringconst_term, ctx);
case TERM_KIND_CONSTVALUE: tac_constvalue(buffer, t->ptr.constvalue_term); break;
case TERM_KIND_ENUM_VALUE:
return tac_term_enum_value(buffer, t, ctx);
break;
default:
fprintf(stderr, "%s: unsupported: %d\n", __func__, t->kind);
return false;
Expand Down
1 change: 1 addition & 0 deletions compiler/main/typechecker/tc_term.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ bool tc_term(struct Term* term, struct TCCtx* tcctx) {
case TERM_KIND_STRINGCONST: return true;

case TERM_KIND_CONSTVALUE: return tc_constvalue(term->ptr.constvalue_term);
case TERM_KIND_ENUM_VALUE: return true;

default:
fprintf(stderr, "%s:%s: unhandled case: %d\n", __FILE__, __func__, term->kind);
Expand Down
1 change: 1 addition & 0 deletions compiler/main/typeinference/typeinfer_term.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct Type* infer_type_term(struct ST* st, struct Term* t) {
case TERM_KIND_VAR: return infer_type_variable(st, t->ptr.var_term);
case TERM_KIND_STRINGCONST: return typeFromStrArray(st, "char");
case TERM_KIND_CONSTVALUE: return infer_type_constvalue(st, t->ptr.constvalue_term);
case TERM_KIND_ENUM_VALUE: return typeFromStrPrimitive(st, "uint64");

default:
fprintf(stderr, "[Typeinference][Error] Fatal. (in typeinfer_term.c).\n");
Expand Down
13 changes: 11 additions & 2 deletions compiler/main/util/fill_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@
#include <tables/stst/stst.h>
#include <tables/stst/stst_print.h>
#include "tables/symtable/symtable.h"
#include <tables/enum/enum_table.h>

#include "compiler/main/util/ctx.h"
#include "cli/flags/flags.h"

#include "fill_tables.h"

void fill_tables(struct AST* ast, struct Ctx* ctx) {
bool fill_tables(struct AST* ast, struct Ctx* ctx) {

if (flags_debug(ctx_flags(ctx))) {
const bool debug = flags_debug(ctx_flags(ctx));

if (debug) {
printf("[debug] filling SST, STST tables...\n");
}

Expand All @@ -24,10 +27,16 @@ void fill_tables(struct AST* ast, struct Ctx* ctx) {

sst_fill(ctx_tables(ctx), ctx_tables(ctx)->sst, ns);
stst_fill(ctx_tables(ctx)->stst, ns);

if (!enum_table_fill(ctx_tables(ctx)->enum_table, ns, debug)) {
return false;
}
}

if (flags_debug(ctx_flags(ctx))) {
sst_print(ctx_tables(ctx)->sst);
stst_print(ctx_tables(ctx)->stst);
}

return true;
}
4 changes: 3 additions & 1 deletion compiler/main/util/fill_tables.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once

#include <stdbool.h>

struct AST;
struct Ctx;

void fill_tables(struct AST* ast, struct Ctx* ctx);
bool fill_tables(struct AST* ast, struct Ctx* ctx);
2 changes: 1 addition & 1 deletion compiler/test/gen_tac/test_gen_tac_assignstmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void test_gen_tac_assignstmt_case_local_struct() {
const int8_t value = 0x23;

char snippet[200];
sprintf(snippet, "struct A {int x;} fn main() -> int { local A m; m.x = %d; return m.x; }", value);
sprintf(snippet, "struct Astruct {int x;} fn main() -> int { local Astruct m; m.x = %d; return m.x; }", value);

vmcu_system_t* system = prepare_vmcu_system_from_code_snippet(snippet);

Expand Down
4 changes: 2 additions & 2 deletions compiler/test/gen_tac/test_gen_tac_structdecl.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ void test_gen_tac_structdecl_case_read_struct() {
const uint8_t value = 0xc7;

char snippet[200];
char* template = "struct A{int8 c; int8 a; int8 b;} fn main() -> int { local A x; x.b = %d; return x.b; }";
char* template = "struct Astruct {int8 c; int8 a; int8 b;} fn main() -> int { local Astruct x; x.b = %d; return x.b; }";
sprintf(snippet, template, value);

vmcu_system_t* system = prepare_vmcu_system_from_code_snippet(snippet);
Expand All @@ -35,7 +35,7 @@ void test_gen_tac_structdecl_case_write_struct() {
const uint8_t value = 0xc4;

char snippet[200];
char* template = "struct A{int8 a; int8 b;} fn main() -> int { local A x; x.b = %d; return x.b; }";
char* template = "struct Astruct {int8 a; int8 b;} fn main() -> int { local Astruct x; x.b = %d; return x.b; }";
sprintf(snippet, template, value);

vmcu_system_t* system = prepare_vmcu_system_from_code_snippet(snippet);
Expand Down
Loading