Skip to content

Commit e1f9a1b

Browse files
committed
compiler: initial support for enums
Simple way to create named values. Enum member names and enum names have to be all uppercase. This separates them from other type names like structs.
1 parent e1b03ea commit e1f9a1b

40 files changed

+608
-44
lines changed

ast/ast.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "ast/ast_stmts.h"
1111
#include "ast/ast_const.h"
1212
#include "ast/ast_struct.h"
13+
#include "ast/ast_enum.h"
1314
#include "ast/ast_var.h"
1415
#include "ast/ast_expr.h"
1516
#include "ast/ast_subr.h"
@@ -39,6 +40,11 @@ struct Namespace {
3940
uint16_t count_includes;
4041
char** includes;
4142

43+
// enum declarations
44+
struct EnumDecl** enums;
45+
uint16_t count_enums;
46+
size_t capacity_enums;
47+
4248
//structs must be declared before the subroutines
4349
struct StructDecl** structs;
4450
uint16_t count_structs;

ast/ast/ast_enum.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
#include "../ast_declare.h"
4+
5+
struct EnumDecl {
6+
struct ASTNode super;
7+
8+
// must be all uppercase (underscores are ok)
9+
char* name;
10+
11+
struct EnumMember** members;
12+
uint16_t count_members;
13+
};
14+
15+
struct EnumMember {
16+
struct ASTNode super;
17+
18+
char* name;
19+
struct ConstValue* value;
20+
};

ast/ast/ast_expr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ enum TERM_KIND {
7878
TERM_KIND_VAR,
7979
TERM_KIND_STRINGCONST,
8080
TERM_KIND_CONSTVALUE,
81+
TERM_KIND_ENUM_VALUE,
8182
};
8283

8384
struct Term {
@@ -92,6 +93,7 @@ struct Term {
9293
struct Variable* var_term;
9394
struct StringConst* stringconst_term;
9495
struct ConstValue* constvalue_term;
96+
char* enum_value_term;
9597
} ptr;
9698

9799
enum TERM_KIND kind;

ast/ast_declare.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ struct AST;
1111
struct Namespace;
1212
struct Method;
1313
struct StructDecl;
14+
struct EnumDecl;
1415
struct MethodDecl;
1516
//---------------
1617
struct StmtBlock;

ast/util/free_ast.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ void free_namespace(struct Namespace* ns) {
6262
free(ns->includes[i]);
6363
}
6464

65+
for (int i = 0; i < ns->count_enums; i++) {
66+
free_enum_decl(ns->enums[i]);
67+
}
68+
6569
for (int i = 0; i < ns->count_methods; i++) {
6670
free_method(ns->methods[i]);
6771
}
@@ -101,6 +105,15 @@ void free_stmt_block(struct StmtBlock* block) {
101105
free(block);
102106
}
103107

108+
void free_enum_decl(struct EnumDecl* ed) {
109+
110+
for (int i = 0; i < ed->count_members; i++) {
111+
free(ed->members[i]->name);
112+
free(ed->members[i]);
113+
}
114+
free(ed);
115+
}
116+
104117
void free_struct_decl(struct StructDecl* sd) {
105118

106119
free_simple_type(sd->type);
@@ -124,8 +137,9 @@ bool free_term(struct Term* t) {
124137
case TERM_KIND_VAR: free_variable(t->ptr.var_term); break;
125138
case TERM_KIND_STRINGCONST: free_string_const(t->ptr.stringconst_term); break;
126139
case TERM_KIND_CONSTVALUE: free_const_value(t->ptr.constvalue_term); break;
140+
case TERM_KIND_ENUM_VALUE: free(t->ptr.enum_value_term); break;
127141
default:
128-
fprintf(stderr, "Error in free_term(...)\n");
142+
fprintf(stderr, "Error in free_term(...), unhandled case %d\n", t->kind);
129143
free(t);
130144
return false;
131145
}

ast/util/free_ast.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ void free_namespace(struct Namespace* ns);
2828
void free_stmt_block(struct StmtBlock* block);
2929
void free_range(struct Range* range);
3030

31+
// enum
32+
void free_enum_decl(struct EnumDecl* ed);
33+
3134
//struct
3235
void free_struct_decl(struct StructDecl* sd);
3336
void free_struct_member(struct StructMember* sm);

ast/visitor/visitor.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,18 @@ static bool visit_term(struct Term* t, VISITOR, ARG);
5353
//const
5454
static void visit_const_value(struct ConstValue* cv, VISITOR, ARG);
5555
static void visit_string_const(struct StringConst* s, VISITOR, ARG);
56+
static void visit_enum_value(char* s, VISITOR, ARG);
5657

5758
//var
5859
// @returns false on error
5960
static bool visit_variable(struct Variable* v, VISITOR, ARG);
6061
// @returns false on error
6162
static bool visit_simple_var(struct SimpleVar* v, VISITOR, ARG);
6263

64+
// enum
65+
static bool visit_enum_decl(struct EnumDecl* ed, VISITOR, ARG);
66+
static bool visit_enum_member(struct EnumMember* em, VISITOR, ARG);
67+
6368
bool visit_ast(struct AST* ast, VISITOR, void* arg) {
6469

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

86+
for (int i = 0; i < n->count_enums; i++) {
87+
visit_enum_decl(n->enums[i], visitor, arg);
88+
}
89+
8190
for (int i = 0; i < n->count_structs; i++) {
8291
visit_struct_decl(n->structs[i], visitor, arg);
8392
}
@@ -91,6 +100,25 @@ bool visit_namespace(struct Namespace* n, VISITOR, void* arg) {
91100
return true;
92101
}
93102

103+
static bool visit_enum_decl(struct EnumDecl* ed, VISITOR, ARG) {
104+
105+
visitor(ed, NODE_ENUM_DECL, arg);
106+
107+
for (int i = 0; i < ed->count_members; i++) {
108+
if (!visit_enum_member(ed->members[i], visitor, arg)) {
109+
return false;
110+
}
111+
}
112+
113+
return true;
114+
}
115+
116+
static bool visit_enum_member(struct EnumMember* em, VISITOR, ARG) {
117+
118+
visitor(em, NODE_ENUM_MEMBER, arg);
119+
return true;
120+
}
121+
94122
void visit_struct_decl(struct StructDecl* s, VISITOR, void* arg) {
95123

96124
visitor(s, NODE_STRUCTDECL, arg);
@@ -346,6 +374,9 @@ static bool visit_term(struct Term* t, VISITOR, void* arg) {
346374
case TERM_KIND_CONSTVALUE:
347375
visit_const_value(t->ptr.constvalue_term, visitor, arg);
348376
break;
377+
case TERM_KIND_ENUM_VALUE:
378+
visit_enum_value(t->ptr.enum_value_term, visitor, arg);
379+
break;
349380
default:
350381
fprintf(stderr, "[Visitor][Error] Fatal(2)\n");
351382
return false;
@@ -365,6 +396,11 @@ static void visit_string_const(struct StringConst* s, VISITOR, void* arg) {
365396
visitor(s, NODE_STRINGCONST, arg);
366397
}
367398

399+
static void visit_enum_value(char* s, VISITOR, ARG) {
400+
401+
visitor(s, NODE_ENUM_VALUE, arg);
402+
}
403+
368404
static bool visit_variable(struct Variable* v, VISITOR, void* arg) {
369405

370406
visitor(v, NODE_VARIABLE, arg);

ast/visitor/visitor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ enum NODE_TYPE {
2424
NODE_AST,
2525
NODE_NAMESPACE,
2626

27+
NODE_ENUM_DECL,
28+
NODE_ENUM_MEMBER,
29+
NODE_ENUM_VALUE,
30+
2731
NODE_STRUCTDECL,
2832
NODE_STRUCTMEMBER,
2933

compiler/main/compiler.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ bool compile(struct Flags* flags) {
116116

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

119-
fill_tables(ast, ctx);
119+
if (!fill_tables(ast, ctx)) {
120+
return false;
121+
}
120122

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

compiler/main/gen_tac/gen_tac.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,6 @@
99
#include "util/ctx.h"
1010
#include "tac/tacbuffer.h"
1111

12-
int int_value_from_const(struct ConstValue* cv) {
13-
14-
switch (cv->kind) {
15-
case 1: return (int)cv->ptr.m1_bool_const;
16-
case 2: return (int)cv->ptr.m2_int_const;
17-
case 3: return (int)cv->ptr.m3_char_const;
18-
case 5: return (int)cv->ptr.m5_hex_const;
19-
case 6: return (int)cv->ptr.m5_hex_const;
20-
}
21-
return -1;
22-
}
23-
2412
void tac_method(struct TACBuffer* buffer, struct Method* m, struct Ctx* ctx) {
2513

2614
const uint32_t index = sst_index_of(ctx_tables(ctx)->sst, m->decl->name);

0 commit comments

Comments
 (0)