aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler.c1781
-rw-r--r--src/lexer.c152
-rw-r--r--src/main.c132
-rw-r--r--src/parser.c743
-rw-r--r--src/semantic.c843
-rw-r--r--src/vm.c255
6 files changed, 2795 insertions, 1111 deletions
diff --git a/src/compiler.c b/src/compiler.c
index 9b6a458..65429b0 100644
--- a/src/compiler.c
+++ b/src/compiler.c
@@ -5,21 +5,58 @@
5 5
6#include "parser.c" 6#include "parser.c"
7 7
8typedef struct Type {
9 Str name;
10 Str unique_name;
11 // Size of the type in bytes or 0 if it's target dependant.
12 sz size;
13} Type;
14
8typedef struct Variable { 15typedef struct Variable {
9 Str name; 16 Str name;
10 Str type; 17 Str type_name;
11 sz size; 18 sz size;
12 sz offset; 19 sz offset;
13 sz idx; 20 sz idx;
21 Type type;
14} Variable; 22} Variable;
15 23
24#define WORD_SIZE 8
25
26Type builtin_types[] = {
27 // Nil.
28 {cstr("nil"), cstr("nil"), 0},
29
30 // Architecture dependant.
31 {cstr("Int"), cstr("Int"), 8},
32 {cstr("UInt"), cstr("UInt"), 8},
33 {cstr("Ptr"), cstr("Ptr"), 8},
34 {cstr("Str"), cstr("Str"), 16},
35
36 // Fixed integer types.
37 {cstr("Bool"), cstr("Bool"), 1},
38 {cstr("U8"), cstr("U8"), 1},
39 {cstr("S8"), cstr("S8"), 1},
40 {cstr("U16"), cstr("U16"), 2},
41 {cstr("S16"), cstr("S16"), 2},
42 {cstr("U32"), cstr("U32"), 4},
43 {cstr("S32"), cstr("S32"), 4},
44 {cstr("U64"), cstr("U64"), 8},
45 {cstr("S64"), cstr("S64"), 8},
46
47 // Fixed float types.
48 {cstr("F32"), cstr("F32"), 4},
49 {cstr("F64"), cstr("F64"), 8},
50};
51
16MAPDEF(StrVarMap, varmap, Str, Variable, str_hash, str_eq) 52MAPDEF(StrVarMap, varmap, Str, Variable, str_hash, str_eq)
53MAPDEF(StrTypeMap, strtype, Str, Type, str_hash, str_eq)
17 54
18typedef struct Instruction { 55typedef struct Instruction {
19 u8 dst; 56 u16 dst;
20 u8 a; 57 u16 a;
21 u8 b; 58 u16 b;
22 u8 op; 59 u16 op;
23} Instruction; 60} Instruction;
24 61
25typedef union Constant { 62typedef union Constant {
@@ -49,8 +86,7 @@ typedef struct Chunk {
49 struct Chunk *parent; 86 struct Chunk *parent;
50 87
51 Instruction *code; 88 Instruction *code;
52 IntIntMap *labels; // label -> chunk_index 89 IntIntMap *labels; // label -> chunk_index
53 IntIntMap *labels_rev; // chunk_index -> label
54 sz labels_idx; 90 sz labels_idx;
55 91
56 // Constant values that fit in 64 bits. 92 // Constant values that fit in 64 bits.
@@ -67,6 +103,7 @@ typedef struct Chunk {
67 Variable *vars; 103 Variable *vars;
68 StrVarMap *varmap; 104 StrVarMap *varmap;
69 sz var_off; 105 sz var_off;
106 sz param_off;
70 107
71 // Number of registers currently used in this chunk. 108 // Number of registers currently used in this chunk.
72 sz reg_idx; 109 sz reg_idx;
@@ -82,6 +119,24 @@ typedef struct Chunk {
82 LineCol *linecol; 119 LineCol *linecol;
83} Chunk; 120} Chunk;
84 121
122typedef struct Compiler {
123 Chunk main_chunk;
124 Str file_name;
125 Arena *storage;
126
127 // Tables.
128 StrSet *integer_types;
129 StrSet *signed_ints;
130 StrSet *unsigned_ints;
131 StrSet *float_types;
132 StrSet *numeric_types;
133 StrTypeMap *type_map;
134
135 // Destinations.
136 sz lab_pre;
137 sz lab_post;
138} Compiler;
139
85typedef enum OpCode { 140typedef enum OpCode {
86 // OP DST A B 141 // OP DST A B
87 // --------------------------------------------------------------- 142 // ---------------------------------------------------------------
@@ -92,8 +147,14 @@ typedef enum OpCode {
92 OP_STGVAR, // stgvar vx, ra 147 OP_STGVAR, // stgvar vx, ra
93 OP_LDGVAR, // ldgvar rx, va 148 OP_LDGVAR, // ldgvar rx, va
94 OP_LDGADDR, // ldgaddr rx, va 149 OP_LDGADDR, // ldgaddr rx, va
150 OP_STLVARI, // stlvari vx, ca
151 OP_STLVAR, // stlvar vx, ra
152 OP_LDLVAR, // ldlvar rx, va
153 OP_LDLADDR, // ldladdr rx, va
154 OP_LDSTR, // ldstr rx, sa ; Stores the address of the string sa into rx
95 // Functions. 155 // Functions.
96 OP_CALL, // call fx ; Bumps the stack pointer by cx 156 OP_CALL, // call fx ; Call the function fx
157 OP_RECUR, // recur ; Jump to the beginning of the function.
97 OP_RET, // ret ; Returns from current function 158 OP_RET, // ret ; Returns from current function
98 OP_RESERVE, // reserve cx ; Increments the stack pointer by cx bytes 159 OP_RESERVE, // reserve cx ; Increments the stack pointer by cx bytes
99 OP_POP, // pop rx ; Pops the last value of the stack into rx. 160 OP_POP, // pop rx ; Pops the last value of the stack into rx.
@@ -102,32 +163,56 @@ typedef enum OpCode {
102 OP_PUTRET, // putret rx ; Put rx into the return value memory. 163 OP_PUTRET, // putret rx ; Put rx into the return value memory.
103 OP_PUTRETI, // putreti cx ; Put cx into the return value memory. 164 OP_PUTRETI, // putreti cx ; Put cx into the return value memory.
104 // Printing values with builtin print/println functions. 165 // Printing values with builtin print/println functions.
105 OP_PRINTSTR, // p rx 166 OP_PRINTSTR, // p rx
106 OP_PRINTS64, // p rx 167 OP_PRINTSTRI, // p cx
107 OP_PRINTF64, // p rx 168 OP_PRINTS8, // p rx
108 OP_PRINTS64I, // p cx 169 OP_PRINTS8I, // p cx
109 OP_PRINTF64I, // p cx 170 OP_PRINTS16, // p rx
171 OP_PRINTS16I, // p cx
172 OP_PRINTS32, // p rx
173 OP_PRINTS32I, // p cx
174 OP_PRINTS64, // p rx
175 OP_PRINTS64I, // p cx
176 OP_PRINTU8, // p rx
177 OP_PRINTU8I, // p cx
178 OP_PRINTU16, // p rx
179 OP_PRINTU16I, // p cx
180 OP_PRINTU32, // p rx
181 OP_PRINTU32I, // p cx
182 OP_PRINTU64, // p rx
183 OP_PRINTU64I, // p cx
184 OP_PRINTF64, // p rx
185 OP_PRINTF64I, // p cx
186 OP_PRINTF32, // p cx
187 OP_PRINTF32I, // p cx
188 OP_PRINTBOOL, // p rx
189 OP_PRINTBOOLI, // p cx
110 // Load/Store instructions. 190 // Load/Store instructions.
111 OP_LD8K, // ld8k rx, ca -> u8 rx = ca 191 OP_LDCONST, // ldconst rx, ca -> u64 rx = ca
112 OP_LD16K, // ld16k rx, ca -> u16 rx = ca 192 OP_LD8K, // ld8k rx, ra -> u8 *p = ra; rx = *p
113 OP_LD32K, // ld32k rx, ca -> u32 rx = ca 193 OP_LD16K, // ld16k rx, ra -> u16 *p = ra; rx = *p
114 OP_LD64K, // ld64k rx, ca -> u64 rx = ca 194 OP_LD32K, // ld32k rx, ra -> u32 *p = ra; rx = *p
115 OP_LD8I, // ld8i rx, ra, cb -> u8 *p = ra; rx = p[cb] 195 OP_LD64K, // ld64k rx, ra -> u64 *p = ra; rx = *p
116 OP_LD16I, // ld16i rx, ra, cb -> u16 *p = ra; rx = p[cb] 196 OP_ST8K, // ld8k rx, ra -> u8 *p = ra; *p = rx
117 OP_LD32I, // ld32i rx, ra, cb -> u32 *p = ra; rx = p[cb] 197 OP_ST16K, // ld16k rx, ra -> u16 *p = ra; *p = rx
118 OP_LD64I, // ld64i rx, ra, cb -> u64 *p = ra; rx = p[cb] 198 OP_ST32K, // ld32k rx, ra -> u32 *p = ra; *p = rx
119 OP_LD8, // ld8 rx, ra, rb -> u8 *p = ra; rx = p[rb] 199 OP_ST64K, // ld64k rx, ra -> u64 *p = ra; *p = rx
120 OP_LD16, // ld16 rx, ra, rb -> u16 *p = ra; rx = p[rb] 200 OP_LD8I, // ld8i rx, ra, cb -> u8 *p = ra; rx = p[cb]
121 OP_LD32, // ld32 rx, ra, rb -> u32 *p = ra; rx = p[rb] 201 OP_LD16I, // ld16i rx, ra, cb -> u16 *p = ra; rx = p[cb]
122 OP_LD64, // ld64 rx, ra, rb -> u64 *p = ra; rx = p[rb] 202 OP_LD32I, // ld32i rx, ra, cb -> u32 *p = ra; rx = p[cb]
123 OP_ST8I, // st8i rx, ra, cb -> u8 *p = ra; p[cb] = rx 203 OP_LD64I, // ld64i rx, ra, cb -> u64 *p = ra; rx = p[cb]
124 OP_ST16I, // st16i rx, ra, cb -> u16 *p = ra; p[cb] = rx 204 OP_LD8, // ld8 rx, ra, rb -> u8 *p = ra; rx = p[rb]
125 OP_ST32I, // st32i rx, ra, cb -> u32 *p = ra; p[cb] = rx 205 OP_LD16, // ld16 rx, ra, rb -> u16 *p = ra; rx = p[rb]
126 OP_ST64I, // st64i rx, ra, cb -> u64 *p = ra; p[cb] = rx 206 OP_LD32, // ld32 rx, ra, rb -> u32 *p = ra; rx = p[rb]
127 OP_ST8, // st8 rx, ra, rb -> u8 *p = ra; p[rb] = rx 207 OP_LD64, // ld64 rx, ra, rb -> u64 *p = ra; rx = p[rb]
128 OP_ST16, // st16 rx, ra, rb -> u16 *p = ra; p[rb] = rx 208 OP_ST8I, // st8i rx, ra, cb -> u8 *p = ra; p[cb] = rx
129 OP_ST32, // st32 rx, ra, rb -> u32 *p = ra; p[rb] = rx 209 OP_ST16I, // st16i rx, ra, cb -> u16 *p = ra; p[cb] = rx
130 OP_ST64, // st64 rx, ra, rb -> u64 *p = ra; p[rb] = rx 210 OP_ST32I, // st32i rx, ra, cb -> u32 *p = ra; p[cb] = rx
211 OP_ST64I, // st64i rx, ra, cb -> u64 *p = ra; p[cb] = rx
212 OP_ST8, // st8 rx, ra, rb -> u8 *p = ra; p[rb] = rx
213 OP_ST16, // st16 rx, ra, rb -> u16 *p = ra; p[rb] = rx
214 OP_ST32, // st32 rx, ra, rb -> u32 *p = ra; p[rb] = rx
215 OP_ST64, // st64 rx, ra, rb -> u64 *p = ra; p[rb] = rx
131 // Integer arithmetic (only int/s64 for now). 216 // Integer arithmetic (only int/s64 for now).
132 OP_ADDI, // addk rx, ra, cb 217 OP_ADDI, // addk rx, ra, cb
133 OP_SUBI, // subk rx, ra, cb 218 OP_SUBI, // subk rx, ra, cb
@@ -179,11 +264,13 @@ typedef enum OpCode {
179 OP_BITRSHIFTI, // shri rx, ra, cb 264 OP_BITRSHIFTI, // shri rx, ra, cb
180 OP_BITANDI, // bandi rx, ra, cb 265 OP_BITANDI, // bandi rx, ra, cb
181 OP_BITORI, // bori rx, ra, cb 266 OP_BITORI, // bori rx, ra, cb
267 OP_BITXORI, // bxor rx, ra, cb
182 OP_BITNOTI, // bnoti rx, ca 268 OP_BITNOTI, // bnoti rx, ca
183 OP_BITLSHIFT, // shl rx, ra, rb 269 OP_BITLSHIFT, // shl rx, ra, rb
184 OP_BITRSHIFT, // shr rx, ra, rb 270 OP_BITRSHIFT, // shr rx, ra, rb
185 OP_BITAND, // band rx, ra, rb 271 OP_BITAND, // band rx, ra, rb
186 OP_BITOR, // bor rx, ra, rb 272 OP_BITOR, // bor rx, ra, rb
273 OP_BITXOR, // bxor rx, ra, rb
187 OP_BITNOT, // bnot rx, ra 274 OP_BITNOT, // bnot rx, ra
188 // Jump instructions. 275 // Jump instructions.
189 OP_JMP, // jmp lx ; jmp to label lx 276 OP_JMP, // jmp lx ; jmp to label lx
@@ -191,6 +278,7 @@ typedef enum OpCode {
191 OP_JMPT, // jmpt lx, rx ; jmp to label lx if rx is true 278 OP_JMPT, // jmpt lx, rx ; jmp to label lx if rx is true
192 OP_JMPFI, // jmpf lx, cx ; jmp to label lx if rx is false 279 OP_JMPFI, // jmpf lx, cx ; jmp to label lx if rx is false
193 OP_JMPTI, // jmpt lx, cx ; jmp to label lx if rx is true 280 OP_JMPTI, // jmpt lx, cx ; jmp to label lx if rx is true
281 _OP_NUM,
194} OpCode; 282} OpCode;
195 283
196Str op_str[] = { 284Str op_str[] = {
@@ -200,25 +288,55 @@ Str op_str[] = {
200 [OP_STGVARI] = cstr("STGVARI "), 288 [OP_STGVARI] = cstr("STGVARI "),
201 [OP_LDGVAR] = cstr("LDGVAR "), 289 [OP_LDGVAR] = cstr("LDGVAR "),
202 [OP_LDGADDR] = cstr("LDGADDR "), 290 [OP_LDGADDR] = cstr("LDGADDR "),
203 [OP_PRINTSTR] = cstr("PRNTSTR "), 291 [OP_STLVAR] = cstr("STLVAR "),
204 [OP_PRINTS64] = cstr("PRNTS64 "), 292 [OP_STLVARI] = cstr("STLVARI "),
205 [OP_PRINTF64] = cstr("PRNTF64 "), 293 [OP_LDLVAR] = cstr("LDLVAR "),
206 [OP_PRINTS64I] = cstr("PRNTS64I"), 294 [OP_LDLADDR] = cstr("LDLADDR "),
207 [OP_PRINTF64I] = cstr("PRNTF64I"), 295 [OP_LDSTR] = cstr("LDSTR "),
296 [OP_PRINTSTR] = cstr("PRNSTR "),
297 [OP_PRINTSTRI] = cstr("PRNSTRI "),
298 [OP_PRINTS8] = cstr("PRNS8 "),
299 [OP_PRINTS8I] = cstr("PRNS8I "),
300 [OP_PRINTS16] = cstr("PRNS16 "),
301 [OP_PRINTS16I] = cstr("PRNS16I "),
302 [OP_PRINTS32] = cstr("PRNS32 "),
303 [OP_PRINTS32I] = cstr("PRNS32I "),
304 [OP_PRINTS64] = cstr("PRNS64 "),
305 [OP_PRINTS64I] = cstr("PRNS64I "),
306 [OP_PRINTU8] = cstr("PRNU8 "),
307 [OP_PRINTU8I] = cstr("PRNU8I "),
308 [OP_PRINTU16] = cstr("PRNU16 "),
309 [OP_PRINTU16I] = cstr("PRNU16I "),
310 [OP_PRINTU32] = cstr("PRNU32 "),
311 [OP_PRINTU32I] = cstr("PRNU32I "),
312 [OP_PRINTU64] = cstr("PRNU64 "),
313 [OP_PRINTU64I] = cstr("PRNU64I "),
314 [OP_PRINTF32] = cstr("PRNF32 "),
315 [OP_PRINTF32I] = cstr("PRNF32I "),
316 [OP_PRINTF64] = cstr("PRNF64 "),
317 [OP_PRINTF64I] = cstr("PRNF64I "),
318 [OP_PRINTBOOL] = cstr("PRNBOOL "),
319 [OP_PRINTBOOLI] = cstr("PRNBOOLI"),
208 [OP_PUTRET] = cstr("PUTRET "), 320 [OP_PUTRET] = cstr("PUTRET "),
209 [OP_PUTRETI] = cstr("PUTRETI "), 321 [OP_PUTRETI] = cstr("PUTRETI "),
210 // Functions. 322 // Functions.
211 [OP_CALL] = cstr("CALL "), 323 [OP_CALL] = cstr("CALL "),
324 [OP_RECUR] = cstr("RECUR "),
212 [OP_RET] = cstr("RET "), 325 [OP_RET] = cstr("RET "),
213 [OP_RESERVE] = cstr("RESERVE "), 326 [OP_RESERVE] = cstr("RESERVE "),
214 [OP_POP] = cstr("POP "), 327 [OP_POP] = cstr("POP "),
215 [OP_PUSH] = cstr("PUSH "), 328 [OP_PUSH] = cstr("PUSH "),
216 [OP_PUSHI] = cstr("PUSHI "), 329 [OP_PUSHI] = cstr("PUSHI "),
217 // Load ops. 330 // Load ops.
331 [OP_LDCONST] = cstr("LDCONST "),
218 [OP_LD8K] = cstr("LD8K "), 332 [OP_LD8K] = cstr("LD8K "),
219 [OP_LD16K] = cstr("LD16K "), 333 [OP_LD16K] = cstr("LD16K "),
220 [OP_LD32K] = cstr("LD32K "), 334 [OP_LD32K] = cstr("LD32K "),
221 [OP_LD64K] = cstr("LD64K "), 335 [OP_LD64K] = cstr("LD64K "),
336 [OP_ST8K] = cstr("ST8K "),
337 [OP_ST16K] = cstr("ST6K "),
338 [OP_ST32K] = cstr("ST32K "),
339 [OP_ST64K] = cstr("ST64K "),
222 [OP_LD8I] = cstr("LD8I "), 340 [OP_LD8I] = cstr("LD8I "),
223 [OP_LD16I] = cstr("LD16I "), 341 [OP_LD16I] = cstr("LD16I "),
224 [OP_LD32I] = cstr("LD32I "), 342 [OP_LD32I] = cstr("LD32I "),
@@ -286,11 +404,13 @@ Str op_str[] = {
286 [OP_BITRSHIFTI] = cstr("RSHI "), 404 [OP_BITRSHIFTI] = cstr("RSHI "),
287 [OP_BITANDI] = cstr("BANDI "), 405 [OP_BITANDI] = cstr("BANDI "),
288 [OP_BITORI] = cstr("BORI "), 406 [OP_BITORI] = cstr("BORI "),
407 [OP_BITXORI] = cstr("BXORI "),
289 [OP_BITNOTI] = cstr("BNOTI "), 408 [OP_BITNOTI] = cstr("BNOTI "),
290 [OP_BITLSHIFT] = cstr("LSH "), 409 [OP_BITLSHIFT] = cstr("LSH "),
291 [OP_BITRSHIFT] = cstr("RSH "), 410 [OP_BITRSHIFT] = cstr("RSH "),
292 [OP_BITAND] = cstr("BAND "), 411 [OP_BITAND] = cstr("BAND "),
293 [OP_BITOR] = cstr("BOR "), 412 [OP_BITOR] = cstr("BOR "),
413 [OP_BITXOR] = cstr("XBOR "),
294 [OP_BITNOT] = cstr("BNOT "), 414 [OP_BITNOT] = cstr("BNOT "),
295 // Jump instructions. 415 // Jump instructions.
296 [OP_JMP] = cstr("JMP "), 416 [OP_JMP] = cstr("JMP "),
@@ -305,6 +425,7 @@ typedef enum {
305 COMP_CONST, 425 COMP_CONST,
306 COMP_STRING, 426 COMP_STRING,
307 COMP_REG, 427 COMP_REG,
428 COMP_RET,
308 COMP_ERR, 429 COMP_ERR,
309} CompResultType; 430} CompResultType;
310 431
@@ -313,73 +434,195 @@ typedef struct CompResult {
313 CompResultType type; 434 CompResultType type;
314} CompResult; 435} CompResult;
315 436
316CompResult compile_expr(Chunk *chunk, Node *node); 437CompResult compile_expr(Compiler *compiler, Chunk *chunk, Node *node);
317 438
318#define EMIT_OP(OP, DST, A, B, NODE, CHUNK) \ 439sz
319 do { \ 440add_constant(Chunk *chunk, sz value) {
320 Instruction inst = (Instruction){ \ 441 IntIntMap *map = intintmap_lookup(&chunk->intmap, value);
321 .op = (OP), \ 442 // Make sure we don't have duplicated constants.
322 .dst = (DST), \ 443 if (!map) {
323 .a = (A), \ 444 map = intintmap_insert(&chunk->intmap, value, chunk->const_idx++,
324 .b = (B), \ 445 chunk->storage);
325 }; \ 446 Constant c = (Constant){.i = value};
326 array_push((CHUNK)->code, inst, (CHUNK)->storage); \ 447 array_push(chunk->constants, c, chunk->storage);
327 LineCol linecol = (LineCol){0}; \ 448 }
328 if (NODE) { \ 449 return map->val;
329 Node *_node = (NODE); \ 450}
330 linecol = (LineCol){.line = _node->line, .col = _node->col}; \ 451
331 } \ 452sz
332 array_push((CHUNK)->linecol, linecol, (CHUNK)->storage); \ 453add_string(Chunk *chunk, Str string) {
333 } while (0) 454 // Make sure we don't have duplicated string.
455 StrIntMap *map = strintmap_lookup(&chunk->strmap, string);
456 if (!map) {
457 map = strintmap_insert(&chunk->strmap, string, chunk->str_idx++,
458 chunk->storage);
459 array_push(chunk->strings, string, chunk->storage);
460 }
461 return map->val;
462}
463
464sz
465add_variable(Compiler *compiler,
466 Chunk *chunk,
467 Str name,
468 Str type_name,
469 sz arr_size) {
470 sz idx = array_size(chunk->vars);
471 Str base_type = type_name;
472 if (str_has_prefix(base_type, cstr("@"))) {
473 base_type = str_remove_prefix(base_type, cstr("@"));
474 if (str_has_prefix(base_type, cstr("@"))) {
475 base_type = cstr("Ptr");
476 } else if (str_has_prefix(base_type, cstr("["))) {
477 base_type = cstr("Ptr");
478 }
479 } else if (str_has_prefix(base_type, cstr("["))) {
480 str_split(&base_type, cstr("]"));
481 if (str_has_prefix(base_type, cstr("@"))) {
482 base_type = cstr("Ptr");
483 } else if (str_has_prefix(base_type, cstr("["))) {
484 base_type = cstr("Ptr");
485 }
486 }
487 StrTypeMap *t = strtype_lookup(&compiler->type_map, base_type);
488 sz size = t->val.size;
489
490 // An array.
491 if (arr_size) {
492 size *= arr_size;
493 } else if (str_has_prefix(type_name, cstr("@"))) {
494 StrTypeMap *tp = strtype_lookup(&compiler->type_map, cstr("Ptr"));
495 size = tp->val.size;
496 }
497
498 sz padding = -size & (WORD_SIZE - 1);
499 size += padding;
500 Variable var = (Variable){
501 .name = name,
502 .type = t->val,
503 .type_name = type_name,
504 .size = size,
505 .offset = chunk->var_off,
506 .idx = idx,
507 };
508 varmap_insert(&chunk->varmap, name, var, chunk->storage);
509 array_push(chunk->vars, var, chunk->storage);
510 chunk->var_off += size;
511 return idx;
512}
513
514void
515emit_op(OpCode op, sz dst, sz a, sz b, Node *node, Chunk *chunk) {
516 Instruction inst = (Instruction){
517 .op = op,
518 .dst = dst,
519 .a = a,
520 .b = b,
521 };
522 array_push(chunk->code, inst, chunk->storage);
523 LineCol linecol = (LineCol){0};
524 if (node) {
525 linecol = (LineCol){.line = node->line, .col = node->col};
526 }
527 array_push(chunk->linecol, linecol, chunk->storage);
528}
529
530void
531emit_sized_op(sz size,
532 OpCode op64,
533 OpCode op32,
534 OpCode op16,
535 OpCode op8,
536 sz dst,
537 sz a,
538 sz b,
539 Node *node,
540 Chunk *chunk) {
541 if (size == 8) {
542 emit_op(op64, dst, a, b, node, chunk);
543 } else if (size == 4) {
544 emit_op(op32, dst, a, b, node, chunk);
545 } else if (size == 2) {
546 emit_op(op16, dst, a, b, node, chunk);
547 } else if (size == 1) {
548 emit_op(op8, dst, a, b, node, chunk);
549 }
550}
551
552void
553emit_fat_copy(Chunk *chunk, Node *node, sz dst_addr, sz src_addr) {
554 sz reg_dst = chunk->reg_idx++;
555
556 // Store the fat string pointer into the variable.
557 sz zero = add_constant(chunk, 0);
558 sz one = add_constant(chunk, 1);
559
560 // Get the value for the first word of the string
561 // pointer.
562 emit_op(OP_LD64I, reg_dst, src_addr, zero, node, chunk);
563 emit_op(OP_ST64I, reg_dst, dst_addr, zero, node, chunk);
564 emit_op(OP_LD64I, reg_dst, src_addr, one, node, chunk);
565 emit_op(OP_ST64I, reg_dst, dst_addr, one, node, chunk);
566}
567
568void disassemble_chunk(Chunk chunk);
569
570void
571emit_compile_err(Compiler *compiler, Chunk *chunk, Node *node) {
572 disassemble_chunk(*chunk);
573 eprintln("%s:%d:%d: error: compilation error on: %s", compiler->file_name,
574 node->line, node->col, node_str[node->kind]);
575 exit(EXIT_FAILURE);
576}
334 577
335CompResult 578CompResult
336compile_binary(Chunk *chunk, Node *node) { 579compile_binary(Compiler *compiler, Chunk *chunk, Node *node) {
337 OpCode op = OP_HALT; 580 OpCode op = OP_HALT;
338 OpCode opi = OP_HALT; 581 OpCode opi = OP_HALT;
339 OpCode ldop = OP_LD64K; 582 OpCode ldop = OP_LDCONST;
340 switch (node->kind) { 583 switch (node->kind) {
341 // Arithmetic. 584 // Arithmetic.
342 case NODE_ADD: { 585 case NODE_ADD: {
343 if (str_eq(node->type, cstr("int"))) { 586 if (strset_lookup(&compiler->integer_types, node->type)) {
344 op = OP_ADD; 587 op = OP_ADD;
345 opi = OP_ADDI; 588 opi = OP_ADDI;
346 } else if (str_eq(node->type, cstr("f64"))) { 589 } else if (strset_lookup(&compiler->float_types, node->type)) {
347 op = OP_ADDF; 590 op = OP_ADDF;
348 opi = OP_ADDFI; 591 opi = OP_ADDFI;
349 } 592 }
350 } break; 593 } break;
351 case NODE_SUB: { 594 case NODE_SUB: {
352 if (str_eq(node->type, cstr("int"))) { 595 if (strset_lookup(&compiler->integer_types, node->type)) {
353 op = OP_SUB; 596 op = OP_SUB;
354 opi = OP_SUBI; 597 opi = OP_SUBI;
355 } else if (str_eq(node->type, cstr("f64"))) { 598 } else if (strset_lookup(&compiler->float_types, node->type)) {
356 op = OP_SUBF; 599 op = OP_SUBF;
357 opi = OP_SUBFI; 600 opi = OP_SUBFI;
358 } 601 }
359 } break; 602 } break;
360 case NODE_MUL: { 603 case NODE_MUL: {
361 if (str_eq(node->type, cstr("int"))) { 604 if (strset_lookup(&compiler->integer_types, node->type)) {
362 op = OP_MUL; 605 op = OP_MUL;
363 opi = OP_MULI; 606 opi = OP_MULI;
364 } else if (str_eq(node->type, cstr("f64"))) { 607 } else if (strset_lookup(&compiler->float_types, node->type)) {
365 op = OP_MULF; 608 op = OP_MULF;
366 opi = OP_MULFI; 609 opi = OP_MULFI;
367 } 610 }
368 } break; 611 } break;
369 case NODE_DIV: { 612 case NODE_DIV: {
370 if (str_eq(node->type, cstr("int"))) { 613 if (strset_lookup(&compiler->integer_types, node->type)) {
371 op = OP_DIV; 614 op = OP_DIV;
372 opi = OP_DIVI; 615 opi = OP_DIVI;
373 } else if (str_eq(node->type, cstr("f64"))) { 616 } else if (strset_lookup(&compiler->float_types, node->type)) {
374 op = OP_DIVF; 617 op = OP_DIVF;
375 opi = OP_DIVFI; 618 opi = OP_DIVFI;
376 } 619 }
377 } break; 620 } break;
378 case NODE_MOD: { 621 case NODE_MOD: {
379 if (str_eq(node->type, cstr("int"))) { 622 if (strset_lookup(&compiler->integer_types, node->type)) {
380 op = OP_MOD; 623 op = OP_MOD;
381 opi = OP_MODI; 624 opi = OP_MODI;
382 } else if (str_eq(node->type, cstr("f64"))) { 625 } else if (strset_lookup(&compiler->float_types, node->type)) {
383 op = OP_MODF; 626 op = OP_MODF;
384 opi = OP_MODFI; 627 opi = OP_MODFI;
385 } 628 }
@@ -409,19 +652,15 @@ compile_binary(Chunk *chunk, Node *node) {
409 op = OP_GE; 652 op = OP_GE;
410 opi = OP_GEI; 653 opi = OP_GEI;
411 } break; 654 } break;
412 case NODE_AND: {
413 op = OP_AND;
414 opi = OP_ANDI;
415 } break;
416 case NODE_OR: {
417 op = OP_OR;
418 opi = OP_ORI;
419 } break;
420 // Bitwise. 655 // Bitwise.
421 case NODE_BITOR: { 656 case NODE_BITOR: {
422 op = OP_BITOR; 657 op = OP_BITOR;
423 opi = OP_BITORI; 658 opi = OP_BITORI;
424 } break; 659 } break;
660 case NODE_BITXOR: {
661 op = OP_BITXOR;
662 opi = OP_BITXORI;
663 } break;
425 case NODE_BITAND: { 664 case NODE_BITAND: {
426 op = OP_BITAND; 665 op = OP_BITAND;
427 opi = OP_BITANDI; 666 opi = OP_BITANDI;
@@ -436,19 +675,20 @@ compile_binary(Chunk *chunk, Node *node) {
436 } break; 675 } break;
437 default: break; 676 default: break;
438 } 677 }
439 CompResult comp_a = compile_expr(chunk, node->left); 678 CompResult comp_a = compile_expr(compiler, chunk, node->binary.left);
440 CompResult comp_b = compile_expr(chunk, node->right); 679 CompResult comp_b = compile_expr(compiler, chunk, node->binary.right);
441 sz reg_a; 680 sz reg_a;
442 sz reg_b; 681 sz reg_b;
443 switch (comp_a.type) { 682 switch (comp_a.type) {
444 case COMP_CONST: { 683 case COMP_CONST: {
445 reg_a = chunk->reg_idx++; 684 reg_a = chunk->reg_idx++;
446 EMIT_OP(ldop, reg_a, comp_a.idx, 0, node, chunk); 685 emit_op(ldop, reg_a, comp_a.idx, 0, node, chunk);
447 } break; 686 } break;
448 case COMP_REG: { 687 case COMP_REG: {
449 reg_a = comp_a.idx; 688 reg_a = comp_a.idx;
450 } break; 689 } break;
451 default: { 690 default: {
691 emit_compile_err(compiler, chunk, node);
452 return (CompResult){.type = COMP_ERR}; 692 return (CompResult){.type = COMP_ERR};
453 } break; 693 } break;
454 } 694 }
@@ -461,16 +701,99 @@ compile_binary(Chunk *chunk, Node *node) {
461 reg_b = comp_b.idx; 701 reg_b = comp_b.idx;
462 } break; 702 } break;
463 default: { 703 default: {
704 emit_compile_err(compiler, chunk, node);
464 return (CompResult){.type = COMP_ERR}; 705 return (CompResult){.type = COMP_ERR};
465 } break; 706 } break;
466 } 707 }
467 sz reg_dst = chunk->reg_idx++; // Better for optimization 708 sz reg_dst = chunk->reg_idx++; // Better for optimization
468 EMIT_OP(op, reg_dst, reg_a, reg_b, node, chunk); 709 emit_op(op, reg_dst, reg_a, reg_b, node, chunk);
710 return (CompResult){.type = COMP_REG, .idx = reg_dst};
711}
712
713CompResult
714compile_binary_logic(Compiler *compiler, Chunk *chunk, Node *node) {
715 // Logical functions have to shortcircuit once the answer is known.
716 OpCode op = OP_HALT;
717 OpCode opi = OP_HALT;
718 OpCode ldop = OP_LDCONST;
719 OpCode jmpop = OP_HALT;
720 OpCode jmpopi = OP_HALT;
721 bool default_value = false;
722 switch (node->kind) {
723 case NODE_AND: {
724 op = OP_AND;
725 opi = OP_ANDI;
726 jmpop = OP_JMPF;
727 jmpopi = OP_JMPFI;
728 default_value = false;
729 } break;
730 case NODE_OR: {
731 op = OP_OR;
732 opi = OP_ORI;
733 jmpop = OP_JMPT;
734 jmpopi = OP_JMPTI;
735 default_value = true;
736 } break;
737 default: break;
738 }
739
740 sz lab0 = chunk->labels_idx++;
741 sz lab1 = chunk->labels_idx++;
742
743 CompResult comp_a = compile_expr(compiler, chunk, node->binary.left);
744 sz reg_a;
745 switch (comp_a.type) {
746 case COMP_CONST: {
747 emit_op(jmpopi, lab0, comp_a.idx, 0, node->binary.left, chunk);
748 reg_a = chunk->reg_idx++;
749 emit_op(ldop, reg_a, comp_a.idx, 0, node, chunk);
750 } break;
751 case COMP_REG: {
752 emit_op(jmpop, lab0, comp_a.idx, 0, node->binary.left, chunk);
753 reg_a = comp_a.idx;
754 } break;
755 default: {
756 emit_compile_err(compiler, chunk, node);
757 return (CompResult){.type = COMP_ERR};
758 } break;
759 }
760
761 CompResult comp_b = compile_expr(compiler, chunk, node->binary.right);
762 sz reg_b;
763 switch (comp_b.type) {
764 case COMP_CONST: {
765 reg_b = comp_b.idx;
766 op = opi;
767 } break;
768 case COMP_REG: {
769 reg_b = comp_b.idx;
770 } break;
771 default: {
772 emit_compile_err(compiler, chunk, node);
773 return (CompResult){.type = COMP_ERR};
774 } break;
775 }
776 sz reg_dst = chunk->reg_idx++;
777 emit_op(op, reg_dst, reg_a, reg_b, node, chunk);
778
779 // Jump to the end of this comparison.
780 emit_op(OP_JMP, lab1, 0, 0, node, chunk);
781 sz pos0 = array_size(chunk->code);
782
783 // Load default value.
784 sz defaul_const = add_constant(chunk, default_value);
785 emit_op(ldop, reg_dst, defaul_const, 0, node, chunk);
786 sz pos1 = array_size(chunk->code);
787
788 // Register labels.
789 intintmap_insert(&chunk->labels, lab0, pos0, chunk->storage);
790 intintmap_insert(&chunk->labels, lab1, pos1, chunk->storage);
791
469 return (CompResult){.type = COMP_REG, .idx = reg_dst}; 792 return (CompResult){.type = COMP_REG, .idx = reg_dst};
470} 793}
471 794
472CompResult 795CompResult
473compile_unary(Chunk *chunk, Node *node) { 796compile_unary(Compiler *compiler, Chunk *chunk, Node *node) {
474 OpCode op = OP_HALT; 797 OpCode op = OP_HALT;
475 OpCode opi = OP_HALT; 798 OpCode opi = OP_HALT;
476 switch (node->kind) { 799 switch (node->kind) {
@@ -484,7 +807,7 @@ compile_unary(Chunk *chunk, Node *node) {
484 } break; 807 } break;
485 default: break; 808 default: break;
486 } 809 }
487 CompResult comp_a = compile_expr(chunk, node->left); 810 CompResult comp_a = compile_expr(compiler, chunk, node->binary.left);
488 sz reg_a; 811 sz reg_a;
489 switch (comp_a.type) { 812 switch (comp_a.type) {
490 case COMP_CONST: { 813 case COMP_CONST: {
@@ -495,42 +818,18 @@ compile_unary(Chunk *chunk, Node *node) {
495 reg_a = comp_a.idx; 818 reg_a = comp_a.idx;
496 } break; 819 } break;
497 default: { 820 default: {
821 emit_compile_err(compiler, chunk, node);
498 return (CompResult){.type = COMP_ERR}; 822 return (CompResult){.type = COMP_ERR};
499 } break; 823 } break;
500 } 824 }
501 sz reg_dst = chunk->reg_idx++; 825 sz reg_dst = chunk->reg_idx++;
502 EMIT_OP(op, reg_dst, reg_a, 0, node, chunk); 826 emit_op(op, reg_dst, reg_a, 0, node, chunk);
503 return (CompResult){.type = COMP_REG, .idx = reg_dst}; 827 return (CompResult){.type = COMP_REG, .idx = reg_dst};
504} 828}
505 829
506sz
507add_constant(Chunk *chunk, sz value) {
508 IntIntMap *map = intintmap_lookup(&chunk->intmap, value);
509 // Make sure we don't have duplicated constants.
510 if (!map) {
511 map = intintmap_insert(&chunk->intmap, value, chunk->const_idx++,
512 chunk->storage);
513 Constant c = (Constant){.i = value};
514 array_push(chunk->constants, c, chunk->storage);
515 }
516 return map->val;
517}
518
519sz
520add_string(Chunk *chunk, Str string) {
521 // Make sure we don't have duplicated string.
522 StrIntMap *map = strintmap_lookup(&chunk->strmap, string);
523 if (!map) {
524 map = strintmap_insert(&chunk->strmap, string, chunk->str_idx++,
525 chunk->storage);
526 array_push(chunk->strings, string, chunk->storage);
527 }
528 return map->val;
529}
530
531CompResult 830CompResult
532compile_if(Chunk *chunk, Node *node) { 831compile_if(Compiler *compiler, Chunk *chunk, Node *node) {
533 CompResult cond = compile_expr(chunk, node->cond_if); 832 CompResult cond = compile_expr(compiler, chunk, node->ifelse.cond);
534 OpCode jmpop; 833 OpCode jmpop;
535 switch (cond.type) { 834 switch (cond.type) {
536 case COMP_CONST: { 835 case COMP_CONST: {
@@ -540,29 +839,35 @@ compile_if(Chunk *chunk, Node *node) {
540 jmpop = OP_JMPF; 839 jmpop = OP_JMPF;
541 } break; 840 } break;
542 default: { 841 default: {
842 emit_compile_err(compiler, chunk, node);
543 return (CompResult){.type = COMP_ERR}; 843 return (CompResult){.type = COMP_ERR};
544 } break; 844 } break;
545 } 845 }
546 846
547 if (!str_eq(node->type, cstr("nil"))) { 847 if (!str_eq(node->type, cstr("nil")) &&
848 !str_has_prefix(node->type, cstr("ret:")) &&
849 !str_has_prefix(node->type, cstr("flow:"))) {
548 sz reg_dst = chunk->reg_idx++; 850 sz reg_dst = chunk->reg_idx++;
549 851
550 // Jump to the `false` branch. 852 // Jump to the `false` branch.
551 sz lab0 = chunk->labels_idx++; 853 sz lab0 = chunk->labels_idx++;
552 EMIT_OP(jmpop, lab0, cond.idx, 0, node->cond_if, chunk); 854 emit_op(jmpop, lab0, cond.idx, 0, node->ifelse.cond, chunk);
553 855
554 // Condition is true. 856 // Condition is true.
555 CompResult then_expr = compile_expr(chunk, node->cond_expr); 857 CompResult then_expr =
858 compile_expr(compiler, chunk, node->ifelse.expr_true);
556 switch (then_expr.type) { 859 switch (then_expr.type) {
557 case COMP_CONST: { 860 case COMP_CONST: {
558 EMIT_OP(OP_LD64K, reg_dst, then_expr.idx, 0, node->cond_if, 861 emit_op(OP_LDCONST, reg_dst, then_expr.idx, 0,
559 chunk); 862 node->ifelse.cond, chunk);
560 } break; 863 } break;
561 case COMP_REG: { 864 case COMP_REG: {
562 EMIT_OP(OP_MOV64, reg_dst, then_expr.idx, 0, node->cond_if, 865 emit_op(OP_MOV64, reg_dst, then_expr.idx, 0, node->ifelse.cond,
563 chunk); 866 chunk);
564 } break; 867 } break;
868 case COMP_RET: break;
565 default: { 869 default: {
870 emit_compile_err(compiler, chunk, node);
566 return (CompResult){.type = COMP_ERR}; 871 return (CompResult){.type = COMP_ERR};
567 } break; 872 } break;
568 } 873 }
@@ -570,20 +875,23 @@ compile_if(Chunk *chunk, Node *node) {
570 // Jump to the end of the expression. 875 // Jump to the end of the expression.
571 sz pos0 = array_size(chunk->code); 876 sz pos0 = array_size(chunk->code);
572 sz lab1 = chunk->labels_idx++; 877 sz lab1 = chunk->labels_idx++;
573 EMIT_OP(OP_JMP, lab1, 0, 0, node->cond_else, chunk); 878 emit_op(OP_JMP, lab1, 0, 0, node->ifelse.expr_else, chunk);
574 879
575 // Else expression. 880 // Else expression.
576 CompResult else_expr = compile_expr(chunk, node->cond_else); 881 CompResult else_expr =
882 compile_expr(compiler, chunk, node->ifelse.expr_else);
577 switch (else_expr.type) { 883 switch (else_expr.type) {
578 case COMP_CONST: { 884 case COMP_CONST: {
579 EMIT_OP(OP_LD64K, reg_dst, else_expr.idx, 0, node->cond_else, 885 emit_op(OP_LDCONST, reg_dst, else_expr.idx, 0,
580 chunk); 886 node->ifelse.expr_else, chunk);
581 } break; 887 } break;
582 case COMP_REG: { 888 case COMP_REG: {
583 EMIT_OP(OP_MOV64, reg_dst, else_expr.idx, 0, node->cond_else, 889 emit_op(OP_MOV64, reg_dst, else_expr.idx, 0,
584 chunk); 890 node->ifelse.expr_else, chunk);
585 } break; 891 } break;
892 case COMP_RET: break;
586 default: { 893 default: {
894 emit_compile_err(compiler, chunk, node);
587 return (CompResult){.type = COMP_ERR}; 895 return (CompResult){.type = COMP_ERR};
588 } break; 896 } break;
589 } 897 }
@@ -592,47 +900,44 @@ compile_if(Chunk *chunk, Node *node) {
592 // Update labels. 900 // Update labels.
593 intintmap_insert(&chunk->labels, lab0, pos0 + 1, chunk->storage); 901 intintmap_insert(&chunk->labels, lab0, pos0 + 1, chunk->storage);
594 intintmap_insert(&chunk->labels, lab1, pos1, chunk->storage); 902 intintmap_insert(&chunk->labels, lab1, pos1, chunk->storage);
595 intintmap_insert(&chunk->labels_rev, pos0 + 1, lab0, chunk->storage);
596 intintmap_insert(&chunk->labels_rev, pos1, lab1, chunk->storage);
597 return (CompResult){.type = COMP_REG, .idx = reg_dst}; 903 return (CompResult){.type = COMP_REG, .idx = reg_dst};
598 } 904 }
599 905
600 // Jump to the `false` branch. 906 // Jump to the `false` branch.
601 sz lab0 = chunk->labels_idx++; 907 sz lab0 = chunk->labels_idx++;
602 EMIT_OP(jmpop, lab0, cond.idx, 0, node->cond_if, chunk); 908 emit_op(jmpop, lab0, cond.idx, 0, node->ifelse.cond, chunk);
603 909
604 // Condition is true. 910 // Condition is true.
605 compile_expr(chunk, node->cond_expr); 911 compile_expr(compiler, chunk, node->ifelse.expr_true);
606 912
607 // Jump to the end of the expression. 913 // Jump to the end of the expression.
608 sz pos0 = array_size(chunk->code); 914 sz pos0 = array_size(chunk->code);
609 sz lab1 = chunk->labels_idx++; 915 sz lab1 = chunk->labels_idx++;
610 EMIT_OP(OP_JMP, lab1, 0, 0, node->cond_else, chunk); 916 emit_op(OP_JMP, lab1, 0, 0, node->ifelse.expr_else, chunk);
611 917
612 // Else expression. 918 // Else expression.
613 if (node->cond_else) { 919 if (node->ifelse.expr_else) {
614 compile_expr(chunk, node->cond_else); 920 compile_expr(compiler, chunk, node->ifelse.expr_else);
615 } 921 }
616 sz pos1 = array_size(chunk->code); 922 sz pos1 = array_size(chunk->code);
617 923
618 // Update labels. 924 // Update labels.
619 intintmap_insert(&chunk->labels, lab0, pos0 + 1, chunk->storage); 925 intintmap_insert(&chunk->labels, lab0, pos0 + 1, chunk->storage);
620 intintmap_insert(&chunk->labels_rev, pos0 + 1, lab0, chunk->storage);
621 intintmap_insert(&chunk->labels, lab1, pos1, chunk->storage); 926 intintmap_insert(&chunk->labels, lab1, pos1, chunk->storage);
622 intintmap_insert(&chunk->labels_rev, pos1, lab1, chunk->storage);
623 927
624 return (CompResult){.type = COMP_NIL}; 928 return (CompResult){.type = COMP_NIL};
625} 929}
626 930
627CompResult 931CompResult
628compile_cond(Chunk *chunk, Node *node) { 932compile_cond(Compiler *compiler, Chunk *chunk, Node *node) {
629 if (str_eq(node->type, cstr("nil"))) { 933 if (str_eq(node->type, cstr("nil"))) {
630 sz lab1 = chunk->labels_idx++; 934 sz lab1 = chunk->labels_idx++;
631 for (sz i = 0; i < array_size(node->match_cases); i++) { 935 for (sz i = 0; i < array_size(node->match.cases); i++) {
632 // condition = expression 936 // condition = expression
633 Node *expr = node->match_cases[i]; 937 Node *expr = node->match.cases[i];
634 if (expr->case_value) { 938 if (expr->case_entry.cond) {
635 CompResult cond = compile_expr(chunk, expr->case_value); 939 CompResult cond =
940 compile_expr(compiler, chunk, expr->case_entry.cond);
636 OpCode jmpop; 941 OpCode jmpop;
637 switch (cond.type) { 942 switch (cond.type) {
638 case COMP_CONST: { 943 case COMP_CONST: {
@@ -642,42 +947,41 @@ compile_cond(Chunk *chunk, Node *node) {
642 jmpop = OP_JMPF; 947 jmpop = OP_JMPF;
643 } break; 948 } break;
644 default: { 949 default: {
950 emit_compile_err(compiler, chunk, node);
645 return (CompResult){.type = COMP_ERR}; 951 return (CompResult){.type = COMP_ERR};
646 } break; 952 } break;
647 } 953 }
648 // Jump to the `next` branch. 954 // Jump to the `next` branch.
649 sz lab0 = chunk->labels_idx++; 955 sz lab0 = chunk->labels_idx++;
650 EMIT_OP(jmpop, lab0, cond.idx, 0, expr->case_expr, chunk); 956 emit_op(jmpop, lab0, cond.idx, 0, expr->case_entry.expr, chunk);
651 957
652 // Condition is true. 958 // Condition is true.
653 compile_expr(chunk, expr->case_expr); 959 compile_expr(compiler, chunk, expr->case_entry.expr);
654 if (i != array_size(node->match_cases) - 1) { 960 if (i != array_size(node->match.cases) - 1) {
655 // Jump to the end of the expression. 961 // Jump to the end of the expression.
656 sz pos0 = array_size(chunk->code); 962 sz pos0 = array_size(chunk->code);
657 EMIT_OP(OP_JMP, lab1, 0, 0, node->cond_else, chunk); 963 emit_op(OP_JMP, lab1, 0, 0, node->ifelse.expr_else, chunk);
658 intintmap_insert(&chunk->labels, lab0, pos0 + 1, 964 intintmap_insert(&chunk->labels, lab0, pos0 + 1,
659 chunk->storage); 965 chunk->storage);
660 intintmap_insert(&chunk->labels_rev, pos0 + 1, lab0,
661 chunk->storage);
662 } 966 }
663 } else { 967 } else {
664 compile_expr(chunk, expr->case_expr); 968 compile_expr(compiler, chunk, expr->case_entry.expr);
665 break; 969 break;
666 } 970 }
667 } 971 }
668 sz pos1 = array_size(chunk->code); 972 sz pos1 = array_size(chunk->code);
669 intintmap_insert(&chunk->labels, lab1, pos1, chunk->storage); 973 intintmap_insert(&chunk->labels, lab1, pos1, chunk->storage);
670 intintmap_insert(&chunk->labels_rev, pos1, lab1, chunk->storage);
671 return (CompResult){.type = COMP_NIL}; 974 return (CompResult){.type = COMP_NIL};
672 } 975 }
673 976
674 sz reg_dst = chunk->reg_idx++; 977 sz reg_dst = chunk->reg_idx++;
675 sz lab1 = chunk->labels_idx++; 978 sz lab1 = chunk->labels_idx++;
676 for (sz i = 0; i < array_size(node->match_cases); i++) { 979 for (sz i = 0; i < array_size(node->match.cases); i++) {
677 // condition = expression 980 // condition = expression
678 Node *expr = node->match_cases[i]; 981 Node *expr = node->match.cases[i];
679 if (expr->case_value) { 982 if (expr->case_entry.cond) {
680 CompResult cond = compile_expr(chunk, expr->case_value); 983 CompResult cond =
984 compile_expr(compiler, chunk, expr->case_entry.cond);
681 OpCode jmpop; 985 OpCode jmpop;
682 switch (cond.type) { 986 switch (cond.type) {
683 case COMP_CONST: { 987 case COMP_CONST: {
@@ -687,49 +991,54 @@ compile_cond(Chunk *chunk, Node *node) {
687 jmpop = OP_JMPF; 991 jmpop = OP_JMPF;
688 } break; 992 } break;
689 default: { 993 default: {
994 emit_compile_err(compiler, chunk, node);
690 return (CompResult){.type = COMP_ERR}; 995 return (CompResult){.type = COMP_ERR};
691 } break; 996 } break;
692 } 997 }
693 // Jump to the `next` branch. 998 // Jump to the `next` branch.
694 sz lab0 = chunk->labels_idx++; 999 sz lab0 = chunk->labels_idx++;
695 EMIT_OP(jmpop, lab0, cond.idx, 0, expr->case_expr, chunk); 1000 emit_op(jmpop, lab0, cond.idx, 0, expr->case_entry.expr, chunk);
696 1001
697 // Condition is true. 1002 // Condition is true.
698 CompResult then_expr = compile_expr(chunk, expr->case_expr); 1003 CompResult then_expr =
1004 compile_expr(compiler, chunk, expr->case_entry.expr);
699 switch (then_expr.type) { 1005 switch (then_expr.type) {
700 case COMP_CONST: { 1006 case COMP_CONST: {
701 EMIT_OP(OP_LD64K, reg_dst, then_expr.idx, 0, 1007 emit_op(OP_LDCONST, reg_dst, then_expr.idx, 0,
702 expr->case_expr, chunk); 1008 expr->case_entry.expr, chunk);
703 } break; 1009 } break;
704 case COMP_REG: { 1010 case COMP_REG: {
705 EMIT_OP(OP_MOV64, reg_dst, then_expr.idx, 0, 1011 emit_op(OP_MOV64, reg_dst, then_expr.idx, 0,
706 expr->case_expr, chunk); 1012 expr->case_entry.expr, chunk);
707 } break; 1013 } break;
1014 case COMP_RET: break;
708 default: { 1015 default: {
1016 emit_compile_err(compiler, chunk, node);
709 return (CompResult){.type = COMP_ERR}; 1017 return (CompResult){.type = COMP_ERR};
710 } break; 1018 } break;
711 } 1019 }
712 if (i != array_size(node->match_cases) - 1) { 1020 if (i != array_size(node->match.cases) - 1) {
713 // Jump to the end of the expression. 1021 // Jump to the end of the expression.
714 sz pos0 = array_size(chunk->code); 1022 sz pos0 = array_size(chunk->code);
715 EMIT_OP(OP_JMP, lab1, 0, 0, node->cond_else, chunk); 1023 emit_op(OP_JMP, lab1, 0, 0, node->ifelse.expr_else, chunk);
716 intintmap_insert(&chunk->labels, lab0, pos0 + 1, 1024 intintmap_insert(&chunk->labels, lab0, pos0 + 1,
717 chunk->storage); 1025 chunk->storage);
718 intintmap_insert(&chunk->labels_rev, pos0 + 1, lab0,
719 chunk->storage);
720 } 1026 }
721 } else { 1027 } else {
722 CompResult then_expr = compile_expr(chunk, expr->case_expr); 1028 CompResult then_expr =
1029 compile_expr(compiler, chunk, expr->case_entry.expr);
723 switch (then_expr.type) { 1030 switch (then_expr.type) {
724 case COMP_CONST: { 1031 case COMP_CONST: {
725 EMIT_OP(OP_LD64K, reg_dst, then_expr.idx, 0, 1032 emit_op(OP_LDCONST, reg_dst, then_expr.idx, 0,
726 expr->case_expr, chunk); 1033 expr->case_entry.expr, chunk);
727 } break; 1034 } break;
728 case COMP_REG: { 1035 case COMP_REG: {
729 EMIT_OP(OP_MOV64, reg_dst, then_expr.idx, 0, 1036 emit_op(OP_MOV64, reg_dst, then_expr.idx, 0,
730 expr->case_expr, chunk); 1037 expr->case_entry.expr, chunk);
731 } break; 1038 } break;
1039 case COMP_RET: break;
732 default: { 1040 default: {
1041 emit_compile_err(compiler, chunk, node);
733 return (CompResult){.type = COMP_ERR}; 1042 return (CompResult){.type = COMP_ERR};
734 } break; 1043 } break;
735 } 1044 }
@@ -738,14 +1047,27 @@ compile_cond(Chunk *chunk, Node *node) {
738 } 1047 }
739 sz pos1 = array_size(chunk->code); 1048 sz pos1 = array_size(chunk->code);
740 intintmap_insert(&chunk->labels, lab1, pos1, chunk->storage); 1049 intintmap_insert(&chunk->labels, lab1, pos1, chunk->storage);
741 intintmap_insert(&chunk->labels_rev, pos1, lab1, chunk->storage);
742 return (CompResult){.type = COMP_REG, .idx = reg_dst}; 1050 return (CompResult){.type = COMP_REG, .idx = reg_dst};
743} 1051}
744 1052
745CompResult 1053CompResult
746compile_while(Chunk *chunk, Node *node) { 1054compile_break(Compiler *compiler, Chunk *chunk, Node *node) {
1055 emit_op(OP_JMP, compiler->lab_post, 0, 0, node, chunk);
1056 return (CompResult){.type = COMP_NIL};
1057}
1058
1059CompResult
1060compile_continue(Compiler *compiler, Chunk *chunk, Node *node) {
1061 emit_op(OP_JMP, compiler->lab_pre, 0, 0, node, chunk);
1062 return (CompResult){.type = COMP_NIL};
1063}
1064
1065CompResult
1066compile_while(Compiler *compiler, Chunk *chunk, Node *node) {
1067 sz lab0 = chunk->labels_idx++;
1068 sz lab1 = chunk->labels_idx++;
747 sz pos1 = array_size(chunk->code); 1069 sz pos1 = array_size(chunk->code);
748 CompResult cond = compile_expr(chunk, node->while_cond); 1070 CompResult cond = compile_expr(compiler, chunk, node->loop.cond);
749 OpCode jmpop; 1071 OpCode jmpop;
750 switch (cond.type) { 1072 switch (cond.type) {
751 case COMP_CONST: { 1073 case COMP_CONST: {
@@ -755,69 +1077,164 @@ compile_while(Chunk *chunk, Node *node) {
755 jmpop = OP_JMPF; 1077 jmpop = OP_JMPF;
756 } break; 1078 } break;
757 default: { 1079 default: {
1080 emit_compile_err(compiler, chunk, node);
758 return (CompResult){.type = COMP_ERR}; 1081 return (CompResult){.type = COMP_ERR};
759 } break; 1082 } break;
760 } 1083 }
761 1084
762 // Jump to the `end of the loop` branch. 1085 // Jump to the `end of the loop` branch.
763 sz lab0 = chunk->labels_idx++; 1086 emit_op(jmpop, lab0, cond.idx, 0, node->loop.cond, chunk);
764 EMIT_OP(jmpop, lab0, cond.idx, 0, node->while_cond, chunk);
765 1087
766 // Condition is true. 1088 // Condition is true.
767 compile_expr(chunk, node->while_expr); 1089 compiler->lab_pre = lab1;
1090 compiler->lab_post = lab0;
1091 compile_expr(compiler, chunk, node->loop.expr);
768 sz pos0 = array_size(chunk->code); 1092 sz pos0 = array_size(chunk->code);
769 sz lab1 = chunk->labels_idx++; 1093 emit_op(OP_JMP, lab1, 0, 0, node, chunk);
770 EMIT_OP(OP_JMP, lab1, 0, 0, node, chunk);
771 1094
772 // Update labels. 1095 // Update labels.
773 intintmap_insert(&chunk->labels, lab0, pos0 + 1, chunk->storage); 1096 intintmap_insert(&chunk->labels, lab0, pos0 + 1, chunk->storage);
774 intintmap_insert(&chunk->labels_rev, pos0 + 1, lab0, chunk->storage);
775 intintmap_insert(&chunk->labels, lab1, pos1, chunk->storage); 1097 intintmap_insert(&chunk->labels, lab1, pos1, chunk->storage);
776 intintmap_insert(&chunk->labels_rev, pos1, lab1, chunk->storage);
777 1098
778 // Return. 1099 // Return.
779 return (CompResult){.type = COMP_NIL}; 1100 return (CompResult){.type = COMP_NIL};
780} 1101}
781 1102
782CompResult 1103CompResult
783compile_funcall(Chunk *chunk, Node *node) { 1104compile_tail_call(Compiler *compiler, Chunk *chunk, Node *node) {
1105 // Update the local parameters.
1106 for (sz i = 0; i < array_size(node->elements); i++) {
1107 Node *expr = node->elements[i];
1108 CompResult result = compile_expr(compiler, chunk, expr);
1109 switch (result.type) {
1110 case COMP_CONST: {
1111 emit_op(OP_STLVARI, i, result.idx, 0, node, chunk);
1112 } break;
1113 case COMP_REG: {
1114 if (str_eq(expr->type, cstr("Str"))) {
1115 sz var_addr = chunk->reg_idx++;
1116 sz str_addr = result.idx;
1117 emit_op(OP_LDLADDR, var_addr, i, 0, node, chunk);
1118 emit_fat_copy(chunk, node, var_addr, str_addr);
1119 } else {
1120 emit_op(OP_STLVAR, i, result.idx, 0, node, chunk);
1121 }
1122 } break;
1123 case COMP_STRING: {
1124 sz var_addr = chunk->reg_idx++;
1125 sz str_addr = chunk->reg_idx++;
1126 emit_op(OP_LDLADDR, var_addr, i, 0, node, chunk);
1127 emit_op(OP_LDSTR, str_addr, result.idx, 0, node, chunk);
1128 emit_fat_copy(chunk, node, var_addr, str_addr);
1129 } break;
1130 default: {
1131 emit_compile_err(compiler, chunk, node);
1132 return (CompResult){.type = COMP_ERR};
1133 } break;
1134 }
1135 }
1136
1137 emit_op(OP_RECUR, 0, 0, 0, node, chunk);
1138 return (CompResult){.type = COMP_NIL};
1139}
1140
1141CompResult
1142compile_funcall(Compiler *compiler, Chunk *chunk, Node *node) {
784 Str name = node->value.str; 1143 Str name = node->value.str;
785 1144
786 // Builtins. 1145 // Builtins.
787 if (str_eq(name, cstr("print")) || str_eq(name, cstr("println"))) { 1146 if (str_eq(name, cstr("print")) || str_eq(name, cstr("println"))) {
788 for (sz i = 0; i < array_size(node->elements); i++) { 1147 for (sz i = 0; i < array_size(node->elements); i++) {
789 Node *expr = node->elements[i]; 1148 Node *expr = node->elements[i];
790 CompResult result = compile_expr(chunk, expr); 1149 Str type_name = expr->type;
791 if (str_eq(expr->type, cstr("int"))) { 1150 if (str_has_prefix(type_name, cstr("@")) ||
1151 str_has_prefix(type_name, cstr("["))) {
1152 type_name = cstr("Ptr");
1153 }
1154 StrTypeMap *t = strtype_lookup(&compiler->type_map, type_name);
1155 Str type = t->val.unique_name;
1156 sz size = t->val.size;
1157 CompResult result = compile_expr(compiler, chunk, expr);
1158 if (strset_lookup(&compiler->signed_ints, type)) {
1159 switch (result.type) {
1160 case COMP_CONST: {
1161 emit_sized_op(size, OP_PRINTS64I, OP_PRINTS32I,
1162 OP_PRINTS16I, OP_PRINTS8I, result.idx, 0,
1163 0, expr, chunk);
1164 } break;
1165 case COMP_REG: {
1166 emit_sized_op(size, OP_PRINTS64, OP_PRINTS32,
1167 OP_PRINTS16, OP_PRINTS8, result.idx, 0, 0,
1168 expr, chunk);
1169 } break;
1170 default: {
1171 emit_compile_err(compiler, chunk, node);
1172 return (CompResult){.type = COMP_ERR};
1173 } break;
1174 }
1175 } else if (strset_lookup(&compiler->unsigned_ints, type)) {
792 switch (result.type) { 1176 switch (result.type) {
793 case COMP_CONST: { 1177 case COMP_CONST: {
794 EMIT_OP(OP_PRINTS64I, result.idx, 0, 0, expr, chunk); 1178 emit_sized_op(size, OP_PRINTU64I, OP_PRINTU32I,
1179 OP_PRINTU16I, OP_PRINTU8I, result.idx, 0,
1180 0, expr, chunk);
795 } break; 1181 } break;
796 case COMP_REG: { 1182 case COMP_REG: {
797 EMIT_OP(OP_PRINTS64, result.idx, 0, 0, expr, chunk); 1183 emit_sized_op(size, OP_PRINTU64, OP_PRINTU32,
1184 OP_PRINTU16, OP_PRINTU8, result.idx, 0, 0,
1185 expr, chunk);
798 } break; 1186 } break;
799 default: { 1187 default: {
1188 emit_compile_err(compiler, chunk, node);
800 return (CompResult){.type = COMP_ERR}; 1189 return (CompResult){.type = COMP_ERR};
801 } break; 1190 } break;
802 } 1191 }
803 } else if (str_eq(expr->type, cstr("f64"))) { 1192 } else if (strset_lookup(&compiler->float_types, type)) {
804 switch (result.type) { 1193 switch (result.type) {
805 case COMP_CONST: { 1194 case COMP_CONST: {
806 EMIT_OP(OP_PRINTF64I, result.idx, 0, 0, expr, chunk); 1195 if (size == 8) {
1196 emit_op(OP_PRINTF64I, result.idx, 0, 0, expr,
1197 chunk);
1198 } else {
1199 emit_op(OP_PRINTF32I, result.idx, 0, 0, expr,
1200 chunk);
1201 }
807 } break; 1202 } break;
808 case COMP_REG: { 1203 case COMP_REG: {
809 EMIT_OP(OP_PRINTF64, result.idx, 0, 0, expr, chunk); 1204 if (size == 8) {
1205 emit_op(OP_PRINTF64, result.idx, 0, 0, expr, chunk);
1206 } else {
1207 emit_op(OP_PRINTF32, result.idx, 0, 0, expr, chunk);
1208 }
810 } break; 1209 } break;
811 default: { 1210 default: {
1211 emit_compile_err(compiler, chunk, node);
812 return (CompResult){.type = COMP_ERR}; 1212 return (CompResult){.type = COMP_ERR};
813 } break; 1213 } break;
814 } 1214 }
815 } else if (str_eq(expr->type, cstr("str"))) { 1215 } else if (str_eq(type, cstr("Str"))) {
816 switch (result.type) { 1216 switch (result.type) {
817 case COMP_STRING: { 1217 case COMP_STRING: {
818 EMIT_OP(OP_PRINTSTR, result.idx, 0, 0, expr, chunk); 1218 emit_op(OP_PRINTSTRI, result.idx, 0, 0, expr, chunk);
1219 } break;
1220 case COMP_REG: {
1221 emit_op(OP_PRINTSTR, result.idx, 0, 0, expr, chunk);
819 } break; 1222 } break;
820 default: { 1223 default: {
1224 emit_compile_err(compiler, chunk, node);
1225 return (CompResult){.type = COMP_ERR};
1226 } break;
1227 }
1228 } else if (str_eq(type, cstr("Bool"))) {
1229 switch (result.type) {
1230 case COMP_CONST: {
1231 emit_op(OP_PRINTBOOLI, result.idx, 0, 0, expr, chunk);
1232 } break;
1233 case COMP_REG: {
1234 emit_op(OP_PRINTBOOL, result.idx, 0, 0, expr, chunk);
1235 } break;
1236 default: {
1237 emit_compile_err(compiler, chunk, node);
821 return (CompResult){.type = COMP_ERR}; 1238 return (CompResult){.type = COMP_ERR};
822 } break; 1239 } break;
823 } 1240 }
@@ -825,75 +1242,217 @@ compile_funcall(Chunk *chunk, Node *node) {
825 } 1242 }
826 if (str_eq(name, cstr("println"))) { 1243 if (str_eq(name, cstr("println"))) {
827 sz idx = add_string(chunk, cstr("\n")); 1244 sz idx = add_string(chunk, cstr("\n"));
828 EMIT_OP(OP_PRINTSTR, idx, 0, 0, node, chunk); 1245 emit_op(OP_PRINTSTRI, idx, 0, 0, node, chunk);
829 } 1246 }
830 return (CompResult){.type = COMP_NIL}; 1247 return (CompResult){.type = COMP_NIL};
1248 } else if (str_eq(name, cstr("sizeof"))) {
1249 // Find size of the given type.
1250 Node *expr = node->elements[0];
1251 Str type_name = expr->value.str;
1252 // Try to find the type on the table.
1253 StrTypeMap *t = strtype_lookup(&compiler->type_map, type_name);
1254 sz size = 0;
1255 if (t) {
1256 size = t->val.size;
1257 } else {
1258 // If that's not possible, try resolving the symbol.
1259 Str name = expr->unique_name;
1260 StrVarMap *map = NULL;
1261 Chunk *next = chunk;
1262 while (next) {
1263 map = varmap_lookup(&next->varmap, name);
1264 if (map) {
1265 break;
1266 }
1267 next = next->parent;
1268 }
1269 if (!map) {
1270 emit_compile_err(compiler, chunk, expr);
1271 return (CompResult){.type = COMP_ERR};
1272 }
1273 Variable var = map->val;
1274 size = var.size;
1275 }
1276
1277 // FIXME: type size and tables is better done on semantic analyzer,
1278 // enough bloat here already.
1279 sz reg_dst = chunk->reg_idx++;
1280 sz const_idx = add_constant(chunk, size);
1281 emit_op(OP_LDCONST, reg_dst, const_idx, 0, node, chunk);
1282 return (CompResult){.type = COMP_REG, .idx = reg_dst};
831 } 1283 }
832 1284
833 // TODO: need to find this on the parents, not just in the current chunk. 1285 FunctionMap *map =
834 FunctionMap *map = funcmap_lookup(&chunk->funmap, node->unique_name); 1286 funcmap_lookup(&compiler->main_chunk.funmap, node->unique_name);
835 if (!map) { 1287 if (!map) {
836 println("how come?"); 1288 emit_compile_err(compiler, chunk, node);
1289 return (CompResult){.type = COMP_ERR};
837 } 1290 }
838 Function fun = map->val; 1291 Function fun = map->val;
839 1292
1293 // Check for tail recursive opportunities.
1294 if (str_eq(fun.name, node->unique_name) &&
1295 str_eq(chunk->name, node->unique_name)) {
1296 Node *parent = node->parent;
1297 Node *current = node;
1298 bool tail_recursive = true;
1299 while (parent != NULL) {
1300 switch (parent->kind) {
1301 case NODE_BLOCK: {
1302 sz idx = array_size(parent->statements) - 1;
1303 if (parent->statements[idx] != node) {
1304 tail_recursive = false;
1305 break;
1306 }
1307 } break;
1308 case NODE_WHILE: {
1309 if (current == parent->loop.cond) {
1310 tail_recursive = false;
1311 break;
1312 }
1313 } break;
1314 case NODE_IF: {
1315 if (current == parent->ifelse.cond) {
1316 tail_recursive = false;
1317 break;
1318 }
1319 } break;
1320 case NODE_FUN: {
1321 sz idx = array_size(parent->func.body->statements) - 1;
1322 if (parent->func.body->statements[idx] != current) {
1323 tail_recursive = false;
1324 break;
1325 }
1326 break;
1327 } break;
1328 case NODE_MATCH: {
1329 if (current == parent->match.expr) {
1330 tail_recursive = false;
1331 break;
1332 }
1333 } break;
1334 case NODE_COND: break;
1335 case NODE_CASE_COND: {
1336 if (current == parent->case_entry.cond) {
1337 tail_recursive = false;
1338 break;
1339 }
1340 } break;
1341 default: {
1342 tail_recursive = false;
1343 break;
1344 } break;
1345 }
1346 parent = parent->parent;
1347 current = current->parent;
1348 }
1349 if (tail_recursive) {
1350 return compile_tail_call(compiler, chunk, node);
1351 }
1352 }
1353
840 // Reserve space for the return value if needed. 1354 // Reserve space for the return value if needed.
841 if (fun.return_arity > 0) { 1355 if (fun.return_arity > 0) {
842 // Put the return data into a register 1356 // Put the return data into a register
843 sz ret_size = add_constant(chunk, 8); 1357 sz ret_size = add_constant(chunk, 8);
844 EMIT_OP(OP_RESERVE, ret_size, 0, 0, node, chunk); 1358 emit_op(OP_RESERVE, ret_size, 0, 0, node, chunk);
845 } 1359 }
846 1360
847 // Send parameters to the stack. 1361 // Send parameters to the stack.
848 for (sz i = 0; i < array_size(node->elements); i++) { 1362 for (sz i = 0; i < array_size(node->elements); i++) {
849 Node *expr = node->elements[i]; 1363 Node *expr = node->elements[i];
850 CompResult result = compile_expr(chunk, expr); 1364 CompResult result = compile_expr(compiler, chunk, expr);
851 // TODO: Assuming all values are 8 bytes... again. 1365 Str type_name = expr->type;
1366 if (str_has_prefix(type_name, cstr("@")) ||
1367 str_has_prefix(type_name, cstr("["))) {
1368 type_name = cstr("Ptr");
1369 }
1370 StrTypeMap *t = strtype_lookup(&compiler->type_map, type_name);
1371 sz size = t->val.size;
852 switch (result.type) { 1372 switch (result.type) {
853 case COMP_CONST: { 1373 case COMP_CONST: {
854 EMIT_OP(OP_PUSHI, result.idx, 0, 0, expr, chunk); 1374 emit_op(OP_PUSHI, result.idx, 0, 0, expr, chunk);
855 } break; 1375 } break;
856 case COMP_REG: { 1376 case COMP_REG: {
857 EMIT_OP(OP_PUSH, result.idx, 0, 0, expr, chunk); 1377 if (str_eq(expr->type, cstr("Str"))) {
1378 sz str_addr = result.idx;
1379 // Store the fat string pointer into the stack.
1380 sz reg_dst = chunk->reg_idx++;
1381 sz zero = add_constant(chunk, 0);
1382 sz one = add_constant(chunk, 1);
1383 emit_sized_op(size, OP_LD64I, OP_LD32I, OP_LD16I, OP_LD8I,
1384 reg_dst, str_addr, zero, node, chunk);
1385 emit_op(OP_PUSH, reg_dst, 0, 0, expr, chunk);
1386 emit_sized_op(size, OP_LD64I, OP_LD32I, OP_LD16I, OP_LD8I,
1387 reg_dst, str_addr, one, node, chunk);
1388 emit_op(OP_PUSH, reg_dst, 0, 0, expr, chunk);
1389 } else {
1390 emit_op(OP_PUSH, result.idx, 0, 0, expr, chunk);
1391 }
1392 } break;
1393 case COMP_STRING: {
1394 // Get the address for the string value variable.
1395 sz str_addr = chunk->reg_idx++;
1396 emit_op(OP_LDSTR, str_addr, result.idx, 0, node->var.val,
1397 chunk);
1398
1399 // Store the fat string pointer into the stack.
1400 sz reg_dst = chunk->reg_idx++;
1401 sz zero = add_constant(chunk, 0);
1402 sz one = add_constant(chunk, 1);
1403 emit_op(OP_LD64I, reg_dst, str_addr, zero, node, chunk);
1404 emit_op(OP_PUSH, reg_dst, 0, 0, expr, chunk);
1405 emit_op(OP_LD64I, reg_dst, str_addr, one, node, chunk);
1406 emit_op(OP_PUSH, reg_dst, 0, 0, expr, chunk);
858 } break; 1407 } break;
859 default: { 1408 default: {
1409 emit_compile_err(compiler, chunk, node);
860 return (CompResult){.type = COMP_ERR}; 1410 return (CompResult){.type = COMP_ERR};
861 } break; 1411 } break;
862 } 1412 }
863 } 1413 }
864 1414
865 // // TODO: prologue (how much space do we actually need)? we need the 1415 emit_op(OP_CALL, fun.index, 0, 0, node, chunk);
866 // symbol
867 // // table, arity and return parameters boy.
868 // // FIXME: assuming all values are 8 bytes for now...
869 // sz alloc_size = (fun.param_arity + fun.return_arity) * 8;
870 // sz alloc_const = add_constant(chunk, alloc_size);
871 // if (alloc_size > 0) {
872 // // EMIT_OP(OP_RESERVE, alloc_const, 0, 0, node, chunk);
873 // }
874
875 // // println("FUNCALL: unique name: %s", node->unique_name);
876 // // println("FUN: param_arity: %d", fun.param_arity);
877 // // println("FUN: return_arity: %d", fun.return_arity);
878 EMIT_OP(OP_CALL, fun.index, 0, 0, node, chunk);
879 1416
880 // Only one return parameter for now. 1417 // Only one return parameter for now.
881 if (fun.return_arity > 0) { 1418 if (fun.return_arity > 0) {
882 // Put the return data into a register 1419 // Put the return data into a register
883 sz reg_dst = chunk->reg_idx++; 1420 sz reg_dst = chunk->reg_idx++;
884 EMIT_OP(OP_POP, reg_dst, 0, 0, node, chunk); 1421 emit_op(OP_POP, reg_dst, 0, 0, node, chunk);
885 return (CompResult){.type = COMP_REG, .idx = reg_dst}; 1422 return (CompResult){.type = COMP_REG, .idx = reg_dst};
886 } 1423 }
887 1424
888 // if (alloc_size > 0) {
889 // // EMIT_OP(OP_POP, alloc_const, 0, 0, node, chunk);
890 // }
891 // TODO: epilogue (how much space do we actually need)? we need to remove
892 // the AR data here after using it. If we only have one return parameter we
893 // can put it in a register but what if that's not actually the case?
894 return (CompResult){.type = COMP_NIL}; 1425 return (CompResult){.type = COMP_NIL};
895} 1426}
896 1427
1428CompResult
1429compile_return(Compiler *compiler, Chunk *chunk, Node *node) {
1430 for (sz i = 0; i < array_size(node->elements); i++) {
1431 Node *expr = node->elements[i];
1432 CompResult res = compile_expr(compiler, chunk, expr);
1433
1434 // TODO: Only one return field for now, but this is the idea.
1435 // Put return values into memory.
1436 switch (res.type) {
1437 case COMP_CONST: {
1438 emit_op(OP_PUTRETI, res.idx, 0, 0, node, chunk);
1439 } break;
1440 case COMP_REG: {
1441 emit_op(OP_PUTRET, res.idx, 0, 0, node, chunk);
1442 } break;
1443 case COMP_NIL: break;
1444 default: {
1445 emit_compile_err(compiler, chunk, node);
1446 return (CompResult){.type = COMP_ERR};
1447 } break;
1448 }
1449 break;
1450 }
1451
1452 emit_op(OP_RET, 0, 0, 0, node, chunk);
1453 return (CompResult){.type = COMP_RET};
1454}
1455
897Chunk * 1456Chunk *
898chunk_alloc(Chunk *parent) { 1457chunk_alloc(Chunk *parent) {
899 static sz chunk_idx = 1; 1458 static sz chunk_idx = 1;
@@ -905,50 +1464,451 @@ chunk_alloc(Chunk *parent) {
905 return chunk; 1464 return chunk;
906} 1465}
907 1466
908CompResult 1467void
909compile_function(Chunk *chunk, Node *node) { 1468verify_chunk(Chunk *chunk) {
910 Chunk *func = chunk_alloc(chunk); 1469 if (chunk->const_idx >= 256) {
911 func->name = node->unique_name; 1470 eprintln("too many constants on chunk %s", chunk->id);
1471 exit(EXIT_FAILURE);
1472 }
1473 if (chunk->str_idx >= 256) {
1474 eprintln("too many strings on chunk %s", chunk->id);
1475 exit(EXIT_FAILURE);
1476 }
1477 if (chunk->reg_idx >= 256) {
1478 eprintln("too many registers used on chunk %s", chunk->id);
1479 exit(EXIT_FAILURE);
1480 }
1481 if (chunk->labels_idx >= 256) {
1482 eprintln("too many labels used on chunk %s", chunk->id);
1483 exit(EXIT_FAILURE);
1484 }
1485 if (chunk->fun_idx >= 256) {
1486 eprintln("too many functions on chunk %s", chunk->id);
1487 exit(EXIT_FAILURE);
1488 }
1489}
1490
1491void
1492declare_function(Chunk *chunk, Node *node) {
1493 Str name = node->unique_name;
1494 FunctionMap *map = funcmap_lookup(&chunk->funmap, node->unique_name);
1495 if (map) {
1496 return;
1497 }
912 Function fun = (Function){ 1498 Function fun = (Function){
913 .name = func->name, 1499 .name = name,
914 .index = chunk->fun_idx++, 1500 .index = chunk->fun_idx++,
915 .param_arity = array_size(node->func_params), 1501 .param_arity = array_size(node->func.params),
916 .return_arity = array_size(node->func_ret), 1502 .return_arity = array_size(node->func.ret),
917 }; 1503 };
918 funcmap_insert(&chunk->funmap, func->name, fun, chunk->storage); 1504 funcmap_insert(&chunk->funmap, node->unique_name, fun, chunk->storage);
1505}
1506
1507CompResult
1508compile_function(Compiler *compiler, Chunk *chunk, Node *node) {
1509 // The current activation record procedure for the VM is as follows:
1510 //
1511 // [caller][callee ]
1512 // [ .... ][ RET VAL ][ PARAMS ][ LOCALS ][ REGISTERS ][ RET META ]
1513 // ^
1514 // frame pointer
1515 //
1516 // The caller is responsible for allocating the return memory and the
1517 // parameter memory and filling the param data before OP_CALL.
1518 //
1519 chunk = &compiler->main_chunk;
1520 Chunk *func = chunk_alloc(chunk);
1521 func->name = node->unique_name;
1522 declare_function(chunk, node);
919 array_push(chunk->functions, func, chunk->storage); 1523 array_push(chunk->functions, func, chunk->storage);
920 1524
1525 // Push arguments as locals.
1526 for (sz i = 0; i < array_size(node->func.params); i++) {
1527 Node *param = node->func.params[i];
1528 Str name = param->unique_name;
1529 Str type = param->type;
1530 sz arr_size = 0;
1531 if (str_has_prefix(type, cstr("@"))) {
1532 // if (param->var.type->sym.arr_size->value.i > 0) {
1533 // arr_size = param->var.type->sym.arr_size->value.i;
1534 // }
1535 }
1536 add_variable(compiler, func, name, type, arr_size);
1537 }
1538 func->param_off = func->var_off;
1539
1540 // Compiling the body.
1541 CompResult res = compile_expr(compiler, func, node->func.body);
1542
921 // Put return values into memory. 1543 // Put return values into memory.
922 CompResult res = compile_expr(func, node->func_body);
923 switch (res.type) { 1544 switch (res.type) {
924 case COMP_CONST: { 1545 case COMP_CONST: {
925 EMIT_OP(OP_PUTRETI, res.idx, 0, 0, node, func); 1546 emit_op(OP_PUTRETI, res.idx, 0, 0, node, func);
926 } break; 1547 } break;
927 case COMP_REG: { 1548 case COMP_REG: {
928 EMIT_OP(OP_PUTRET, res.idx, 0, 0, node, func); 1549 emit_op(OP_PUTRET, res.idx, 0, 0, node, func);
929 } break; 1550 } break;
930 default: break; 1551 default: break;
931 } 1552 }
932 1553
933 // TODO: handle captured locals/globals? 1554 emit_op(OP_RET, 0, 0, 0, node, func);
934 EMIT_OP(OP_RET, 0, 0, 0, node, func); 1555 verify_chunk(func);
935 return (CompResult){.type = COMP_NIL}; 1556 return (CompResult){.type = COMP_NIL};
936} 1557}
937 1558
938CompResult 1559CompResult
939compile_expr(Chunk *chunk, Node *node) { 1560compile_let(Compiler *compiler, Chunk *chunk, Node *node) {
1561 sz op_ldaddr = OP_LDLADDR;
1562 if (chunk == &compiler->main_chunk) {
1563 op_ldaddr = OP_LDGADDR;
1564 }
1565 Str name = node->unique_name;
1566 Str type_name = node->var.name->type;
1567 sz arr_size = 0;
1568 if (node->var.type) {
1569 Node *next = node->var.type->t.next;
1570 if (next && next->kind == NODE_ARR) {
1571 // TODO: handle dynamic arrays and slices
1572 arr_size = next->array.size->value.i;
1573 }
1574 }
1575
1576 sz idx = add_variable(compiler, chunk, name, type_name, arr_size);
1577 StrVarMap *map = varmap_lookup(&chunk->varmap, name);
1578 Variable var = map->val;
1579 Type type = map->val.type;
1580
1581 // Value.
1582 if (node->var.val) {
1583 CompResult res = compile_expr(compiler, chunk, node->var.val);
1584 switch (res.type) {
1585 case COMP_CONST: {
1586 sz reg_addr = chunk->reg_idx++;
1587 sz reg_dst = chunk->reg_idx++;
1588 emit_op(op_ldaddr, reg_addr, idx, 0, node, chunk);
1589 emit_op(OP_LDCONST, reg_dst, res.idx, 0, node, chunk);
1590 emit_sized_op(type.size, OP_ST64K, OP_ST32K, OP_ST16K, OP_ST8K,
1591 reg_dst, reg_addr, 0, node, chunk);
1592 } break;
1593 case COMP_REG: {
1594 sz reg_addr = chunk->reg_idx++;
1595 sz reg_val = res.idx;
1596 emit_op(op_ldaddr, reg_addr, idx, 0, node, chunk);
1597 if (var.size > 8 || str_has_prefix(var.type_name, cstr("["))) {
1598 sz reg_dst = chunk->reg_idx++;
1599 for (sz i = 0; i < var.size / 8; i++) {
1600 sz offset = add_constant(chunk, i);
1601 emit_op(OP_LD64I, reg_dst, reg_val, offset, node,
1602 chunk);
1603 emit_op(OP_ST64I, reg_dst, reg_addr, offset, node,
1604 chunk);
1605 }
1606 } else {
1607 emit_sized_op(var.size, OP_ST64K, OP_ST32K, OP_ST16K,
1608 OP_ST8K, reg_val, reg_addr, 0, node, chunk);
1609 }
1610 } break;
1611 case COMP_STRING: {
1612 // Get the address for the string value variable.
1613 sz str_addr = chunk->reg_idx++;
1614 emit_op(OP_LDSTR, str_addr, res.idx, 0, node->var.val, chunk);
1615
1616 // Get the address for the local/global storage
1617 // variable.
1618 sz var_addr = chunk->reg_idx++;
1619 emit_op(op_ldaddr, var_addr, idx, 0, node, chunk);
1620
1621 // Copy the fat pointer.
1622 emit_fat_copy(chunk, node, var_addr, str_addr);
1623 } break;
1624 default: {
1625 emit_compile_err(compiler, chunk, node);
1626 return (CompResult){.type = COMP_ERR};
1627 } break;
1628 }
1629 }
1630
1631 return (CompResult){.type = COMP_NIL};
1632}
1633
1634CompResult
1635compile_set(Compiler *compiler, Chunk *chunk, Node *node) {
1636 Str name = node->unique_name;
1637 StrVarMap *map = NULL;
1638 Chunk *next = chunk;
1639 while (next) {
1640 map = varmap_lookup(&next->varmap, name);
1641 if (map) {
1642 break;
1643 }
1644 next = chunk->parent;
1645 }
1646 if (!map) {
1647 emit_compile_err(compiler, chunk, node);
1648 return (CompResult){.type = COMP_ERR};
1649 }
1650 sz op_ldaddr = OP_LDLADDR;
1651 if (next == &compiler->main_chunk) {
1652 op_ldaddr = OP_LDGADDR;
1653 }
1654 Variable var = map->val;
1655 Type type = map->val.type;
1656 sz idx = map->val.idx;
1657
1658 CompResult res = compile_expr(compiler, chunk, node->var.val);
1659 if (false) {
1660 // // Value.
1661 // sz reg_val;
1662 // switch (res.type) {
1663 // case COMP_CONST: {
1664 // reg_val = chunk->reg_idx++;
1665 // emit_op(OP_LDCONST, reg_val, res.idx, 0, node, chunk);
1666 // } break;
1667 // case COMP_REG: {
1668 // reg_val = res.idx;
1669 // } break;
1670 // default: {
1671 // emit_compile_err(compiler, chunk, node);
1672 // return (CompResult){.type = COMP_ERR};
1673 // } break;
1674 // }
1675
1676 // // Address.
1677 // sz reg_addr = chunk->reg_idx++;
1678 // // Is this a pointer access or an array access?
1679 // if (str_has_prefix(map->val.type_name, cstr("[]"))) {
1680 // emit_op(op_ldaddr, reg_addr, map->val.idx, 0, node->var.val,
1681 // chunk);
1682 // } else {
1683 // emit_op(op_ldvar, reg_addr, map->val.idx, 0, node->var.val,
1684 // chunk);
1685 // }
1686
1687 // // Index.
1688 // CompResult res_idx =
1689 // compile_expr(compiler, chunk, node->var.name->sym.arr_size);
1690 // switch (res_idx.type) {
1691 // case COMP_CONST: {
1692 // emit_sized_op(type.size, OP_ST64I, OP_ST32I, OP_ST16I,
1693 // OP_ST8I,
1694 // reg_val, reg_addr, res_idx.idx, node, chunk);
1695 // } break;
1696 // case COMP_REG: {
1697 // emit_sized_op(type.size, OP_ST64, OP_ST32, OP_ST16, OP_ST8,
1698 // reg_val, reg_addr, res_idx.idx, node, chunk);
1699 // } break;
1700 // case COMP_STRING: {
1701 // // Get the address for the string value variable.
1702 // sz str_addr = chunk->reg_idx++;
1703 // emit_op(OP_LDSTR, str_addr, res.idx, 0, node->var.val,
1704 // chunk);
1705
1706 // // Get the address for the local/global storage
1707 // // variable.
1708 // sz var_addr = chunk->reg_idx++;
1709 // emit_op(op_ldaddr, var_addr, idx, 0, node, chunk);
1710
1711 // // Copy the fat pointer.
1712 // emit_fat_copy(chunk, node, var_addr, str_addr);
1713 // } break;
1714 // default: {
1715 // emit_compile_err(compiler, chunk, node);
1716 // return (CompResult){.type = COMP_ERR};
1717 // } break;
1718 // }
1719 // return (CompResult){.type = COMP_NIL};
1720 } else if (node->var.name->kind == NODE_DEREF) {
1721 // Value.
1722 sz reg_val;
1723 switch (res.type) {
1724 case COMP_CONST: {
1725 reg_val = chunk->reg_idx++;
1726 emit_op(OP_LDCONST, reg_val, res.idx, 0, node, chunk);
1727 } break;
1728 case COMP_REG: {
1729 reg_val = res.idx;
1730 } break;
1731 default: {
1732 emit_compile_err(compiler, chunk, node);
1733 return (CompResult){.type = COMP_ERR};
1734 } break;
1735 }
1736
1737 Node *next = node->var.name->deref.next;
1738 sz n_deref = 0;
1739 while (next) {
1740 n_deref++;
1741 if (next->kind == NODE_SYMBOL) {
1742 break;
1743 }
1744 next = next->deref.next;
1745 }
1746 CompResult res = compile_expr(compiler, chunk, next);
1747 sz reg_src = res.idx;
1748 sz reg_dst = reg_src;
1749 for (sz i = 0; i < n_deref - 1; i++) {
1750 reg_dst = chunk->reg_idx++;
1751 emit_op(OP_LD64K, reg_dst, reg_src, 0, node, chunk);
1752 reg_src = reg_dst;
1753 }
1754 emit_sized_op(type.size, OP_ST64K, OP_ST32K, OP_ST16K, OP_ST8K, reg_val,
1755 reg_dst, 0, node, chunk);
1756
1757 return (CompResult){.type = COMP_NIL};
1758 }
1759
1760 switch (res.type) {
1761 case COMP_CONST: {
1762 sz reg_addr = chunk->reg_idx++;
1763 sz reg_dst = chunk->reg_idx++;
1764 emit_op(op_ldaddr, reg_addr, idx, 0, node, chunk);
1765 emit_op(OP_LDCONST, reg_dst, res.idx, 0, node, chunk);
1766 emit_sized_op(type.size, OP_ST64K, OP_ST32K, OP_ST16K, OP_ST8K,
1767 reg_dst, reg_addr, 0, node, chunk);
1768 } break;
1769 case COMP_REG: {
1770 sz reg_addr = chunk->reg_idx++;
1771 sz reg_val = res.idx;
1772 emit_op(op_ldaddr, reg_addr, idx, 0, node, chunk);
1773 if (var.size > 8 || str_has_prefix(var.type_name, cstr("["))) {
1774 sz reg_dst = chunk->reg_idx++;
1775 for (sz i = 0; i < var.size / 8; i++) {
1776 sz offset = add_constant(chunk, i);
1777 emit_op(OP_LD64I, reg_dst, reg_val, offset, node, chunk);
1778 emit_op(OP_ST64I, reg_dst, reg_addr, offset, node, chunk);
1779 }
1780 } else {
1781 emit_sized_op(var.size, OP_ST64K, OP_ST32K, OP_ST16K, OP_ST8K,
1782 reg_val, reg_addr, 0, node, chunk);
1783 }
1784 } break;
1785 case COMP_STRING: {
1786 // Get the address for the string value variable.
1787 sz str_addr = chunk->reg_idx++;
1788 emit_op(OP_LDSTR, str_addr, res.idx, 0, node->var.val, chunk);
1789
1790 // Get the address for the local/global storage
1791 // variable.
1792 sz var_addr = chunk->reg_idx++;
1793 emit_op(op_ldaddr, var_addr, idx, 0, node, chunk);
1794
1795 // Copy the fat pointer.
1796 emit_fat_copy(chunk, node, var_addr, str_addr);
1797 } break;
1798 default: {
1799 emit_compile_err(compiler, chunk, node);
1800 return (CompResult){.type = COMP_ERR};
1801 } break;
1802 }
1803 return (CompResult){.type = COMP_NIL};
1804}
1805
1806CompResult
1807compile_symbol(Compiler *compiler, Chunk *chunk, Node *node) {
1808 Str name = node->unique_name;
1809 StrVarMap *map = NULL;
1810 Chunk *next = chunk;
1811 while (next) {
1812 map = varmap_lookup(&next->varmap, name);
1813 if (map) {
1814 break;
1815 }
1816 next = next->parent;
1817 }
1818 if (!map) {
1819 emit_compile_err(compiler, chunk, node);
1820 return (CompResult){.type = COMP_ERR};
1821 }
1822 sz op_ldaddr = OP_LDLADDR;
1823 if (next == &compiler->main_chunk) {
1824 op_ldaddr = OP_LDGADDR;
1825 }
1826 Variable var = map->val;
1827 sz reg_dst = chunk->reg_idx++;
1828 if (str_has_prefix(var.type_name, cstr("[")) ||
1829 str_eq(var.type_name, cstr("Str"))) {
1830 emit_op(op_ldaddr, reg_dst, var.idx, 0, node, chunk);
1831 } else {
1832 sz reg_addr = chunk->reg_idx++;
1833 emit_op(op_ldaddr, reg_addr, var.idx, 0, node, chunk);
1834 emit_sized_op(var.size, OP_LD64K, OP_LD32K, OP_LD16K, OP_LD8K, reg_dst,
1835 reg_addr, 0, node, chunk);
1836 }
1837 return (CompResult){.type = COMP_REG, .idx = reg_dst};
1838}
1839
1840// CompResult
1841// compile_symbol_idx(Compiler *compiler, Chunk *chunk, Node *node) {
1842// Str name = node->unique_name;
1843// StrVarMap *map = NULL;
1844// Chunk *next = chunk;
1845// while (next) {
1846// map = varmap_lookup(&next->varmap, name);
1847// if (map) {
1848// break;
1849// }
1850// next = next->parent;
1851// }
1852// if (!map) {
1853// eprintln("couldn't resolve symbol name: %s", name);
1854// emit_compile_err(compiler, chunk, node);
1855// return (CompResult){.type = COMP_ERR};
1856// }
1857// sz op_ldaddr = OP_LDLADDR;
1858// sz op_ldvar = OP_LDLVAR;
1859// if (next == &compiler->main_chunk) {
1860// op_ldaddr = OP_LDGADDR;
1861// op_ldvar = OP_LDGVAR;
1862// }
1863
1864// // Destination.
1865// sz reg_dst = chunk->reg_idx++;
1866
1867// // Address.
1868// sz reg_addr = chunk->reg_idx++;
1869// if (str_has_prefix(map->val.type_name, cstr("[]"))) {
1870// emit_op(op_ldaddr, reg_addr, map->val.idx, 0, node->var.val, chunk);
1871// } else {
1872// emit_op(op_ldvar, reg_addr, map->val.idx, 0, node->var.val, chunk);
1873// }
1874
1875// Type type = map->val.type;
1876
1877// // Index.
1878// CompResult idx = compile_expr(compiler, chunk, node->sym.arr_size);
1879// switch (idx.type) {
1880// case COMP_CONST: {
1881// emit_sized_op(type.size, OP_LD64I, OP_LD32I, OP_LD16I, OP_LD8I,
1882// reg_dst, reg_addr, idx.idx, node, chunk);
1883// } break;
1884// case COMP_REG: {
1885// emit_sized_op(type.size, OP_LD64, OP_LD32, OP_LD16, OP_LD8, reg_dst,
1886// reg_addr, idx.idx, node, chunk);
1887// } break;
1888// default: {
1889// emit_compile_err(compiler, chunk, node);
1890// return (CompResult){.type = COMP_ERR};
1891// } break;
1892// }
1893// return (CompResult){.type = COMP_REG, .idx = reg_dst};
1894// }
1895
1896CompResult
1897compile_expr(Compiler *compiler, Chunk *chunk, Node *node) {
940 switch (node->kind) { 1898 switch (node->kind) {
941 case NODE_FUN: return compile_function(chunk, node); 1899 case NODE_BREAK: return compile_break(compiler, chunk, node);
942 case NODE_FUNCALL: return compile_funcall(chunk, node); 1900 case NODE_CONTINUE: return compile_continue(compiler, chunk, node);
943 case NODE_WHILE: return compile_while(chunk, node); 1901 case NODE_RETURN: return compile_return(compiler, chunk, node);
944 case NODE_IF: return compile_if(chunk, node); 1902 case NODE_FUN: return compile_function(compiler, chunk, node);
945 case NODE_COND: return compile_cond(chunk, node); 1903 case NODE_FUNCALL: return compile_funcall(compiler, chunk, node);
1904 case NODE_WHILE: return compile_while(compiler, chunk, node);
1905 case NODE_IF: return compile_if(compiler, chunk, node);
1906 case NODE_COND: return compile_cond(compiler, chunk, node);
946 // Logic. 1907 // Logic.
947 // case NODE_XOR:
948 case NODE_BITNOT: 1908 case NODE_BITNOT:
949 case NODE_NOT: return compile_unary(chunk, node); break; 1909 case NODE_NOT: return compile_unary(compiler, chunk, node); break;
950 case NODE_AND: 1910 case NODE_AND:
951 case NODE_OR: 1911 case NODE_OR: return compile_binary_logic(compiler, chunk, node); break;
952 case NODE_EQ: 1912 case NODE_EQ:
953 case NODE_NEQ: 1913 case NODE_NEQ:
954 case NODE_LT: 1914 case NODE_LT:
@@ -957,6 +1917,7 @@ compile_expr(Chunk *chunk, Node *node) {
957 // Bitwise ops. 1917 // Bitwise ops.
958 case NODE_BITAND: 1918 case NODE_BITAND:
959 case NODE_BITOR: 1919 case NODE_BITOR:
1920 case NODE_BITXOR:
960 case NODE_BITLSHIFT: 1921 case NODE_BITLSHIFT:
961 case NODE_BITRSHIFT: 1922 case NODE_BITRSHIFT:
962 // Arithmetic. 1923 // Arithmetic.
@@ -965,7 +1926,7 @@ compile_expr(Chunk *chunk, Node *node) {
965 case NODE_SUB: 1926 case NODE_SUB:
966 case NODE_MUL: 1927 case NODE_MUL:
967 case NODE_DIV: 1928 case NODE_DIV:
968 case NODE_MOD: return compile_binary(chunk, node); break; 1929 case NODE_MOD: return compile_binary(compiler, chunk, node); break;
969 case NODE_TRUE: 1930 case NODE_TRUE:
970 case NODE_FALSE: 1931 case NODE_FALSE:
971 case NODE_NUM_FLOAT: 1932 case NODE_NUM_FLOAT:
@@ -986,192 +1947,74 @@ compile_expr(Chunk *chunk, Node *node) {
986 .idx = str_idx, 1947 .idx = str_idx,
987 }; 1948 };
988 } break; 1949 } break;
989 case NODE_LET: { 1950 case NODE_LET: return compile_let(compiler, chunk, node);
990 sz idx = array_size(chunk->vars); 1951 case NODE_SET: return compile_set(compiler, chunk, node);
991 Str name = node->unique_name; 1952 case NODE_SYMBOL: return compile_symbol(compiler, chunk, node);
992 Str type = node->var_name->type; 1953 case NODE_PTR: {
993 sz size = 8; 1954 // Load and return address of associated symbol.
994 // TODO: get type storage from a table to consider all the basic 1955 Str name = node->t.next->unique_name;
995 // types as well as user defined ones. 1956 sz op_ldaddr = OP_LDLADDR;
996 if (str_eq(type, cstr("str"))) { 1957 if (chunk == &compiler->main_chunk) {
997 size = 16; 1958 op_ldaddr = OP_LDGADDR;
998 }
999 if (str_has_prefix(type, cstr("@"))) {
1000 if (node->var_type && node->var_type->kind == NODE_ARR_TYPE &&
1001 node->var_type->arr_size->value.i > 0) {
1002 // TODO: get the proper storage size for the multiplication.
1003 size *= node->var_type->arr_size->value.i;
1004 // FIXME: this should be done on the static analysis, plus,
1005 // we shouldn't be checking all these types by hand, but
1006 // using the symbol tables.
1007 type = str_remove_prefix(type, cstr("@"));
1008 type = str_concat(cstr("[]"), type, chunk->storage);
1009 }
1010 }
1011 Variable var = (Variable){
1012 .name = name,
1013 .type = type,
1014 .size = size,
1015 .offset = chunk->var_off,
1016 .idx = idx,
1017 };
1018 varmap_insert(&chunk->varmap, name, var, chunk->storage);
1019 array_push(chunk->vars, var, chunk->storage);
1020 chunk->var_off += size;
1021
1022 // Value.
1023 if (node->var_val) {
1024 CompResult res = compile_expr(chunk, node->var_val);
1025 switch (res.type) {
1026 case COMP_CONST: {
1027 EMIT_OP(OP_STGVARI, idx, res.idx, 0, node->var_val,
1028 chunk);
1029 } break;
1030 case COMP_REG: {
1031 EMIT_OP(OP_STGVAR, idx, res.idx, 0, node->var_val,
1032 chunk);
1033 } break;
1034 default: {
1035 return (CompResult){.type = COMP_ERR};
1036 } break;
1037 }
1038 } 1959 }
1039 1960
1040 return (CompResult){.type = COMP_NIL};
1041 } break;
1042 case NODE_SET: {
1043 Str name = node->unique_name;
1044 StrVarMap *map = varmap_lookup(&chunk->varmap, name); 1961 StrVarMap *map = varmap_lookup(&chunk->varmap, name);
1045 if (!map) { 1962 if (!map) {
1046 eprintln("error: node_set: symbol name not found: %s", name); 1963 emit_compile_err(compiler, chunk, node);
1047 }
1048 CompResult res = compile_expr(chunk, node->var_val);
1049 if (node->var_name->kind == NODE_SYMBOL_IDX) {
1050 // Value.
1051 sz reg_val;
1052 switch (res.type) {
1053 case COMP_CONST: {
1054 reg_val = chunk->reg_idx++;
1055 EMIT_OP(OP_LD64K, reg_val, res.idx, 0, node, chunk);
1056 } break;
1057 case COMP_REG: {
1058 reg_val = res.idx;
1059 } break;
1060 default: {
1061 return (CompResult){.type = COMP_ERR};
1062 } break;
1063 }
1064
1065 // Address.
1066 sz reg_addr = chunk->reg_idx++;
1067 // Is this a pointer access or an array access?
1068 if (str_has_prefix(map->val.type, cstr("[]"))) {
1069 EMIT_OP(OP_LDGADDR, reg_addr, map->val.idx, 0,
1070 node->var_val, chunk);
1071 } else {
1072 EMIT_OP(OP_LDGVAR, reg_addr, map->val.idx, 0, node->var_val,
1073 chunk);
1074 }
1075
1076 // Index.
1077 CompResult idx = compile_expr(chunk, node->var_name->arr_size);
1078 switch (idx.type) {
1079 case COMP_CONST: {
1080 EMIT_OP(OP_ST64I, reg_val, reg_addr, idx.idx, node,
1081 chunk);
1082 } break;
1083 case COMP_REG: {
1084 EMIT_OP(OP_ST64, reg_val, reg_addr, idx.idx, node,
1085 chunk);
1086 } break;
1087 default: {
1088 return (CompResult){.type = COMP_ERR};
1089 } break;
1090 }
1091 // TODO: offset should be in bytes, in this case we are assuming
1092 // 64bit types, hence ST64
1093 return (CompResult){.type = COMP_NIL};
1094 }
1095 switch (res.type) {
1096 case COMP_CONST: {
1097 EMIT_OP(OP_STGVARI, map->val.idx, res.idx, 0, node->var_val,
1098 chunk);
1099 } break;
1100 case COMP_REG: {
1101 EMIT_OP(OP_STGVAR, map->val.idx, res.idx, 0, node->var_val,
1102 chunk);
1103 } break;
1104 default: {
1105 return (CompResult){.type = COMP_ERR};
1106 } break;
1107 }
1108 return (CompResult){.type = COMP_NIL};
1109 } break;
1110 case NODE_SYMBOL: {
1111 Str name = node->unique_name;
1112 StrVarMap *map = varmap_lookup(&chunk->varmap, name);
1113 if (!map) {
1114 println("error: unreachable... name: %s", name);
1115 exit(EXIT_FAILURE);
1116 } 1964 }
1117 Variable var = map->val; 1965 Variable var = map->val;
1118 u8 reg_dst = chunk->reg_idx++;
1119 if (node->is_ptr) {
1120 EMIT_OP(OP_LDGADDR, reg_dst, var.idx, 0, node, chunk);
1121 } else {
1122 EMIT_OP(OP_LDGVAR, reg_dst, var.idx, 0, node, chunk);
1123 }
1124 return (CompResult){.type = COMP_REG, .idx = reg_dst};
1125 } break;
1126 case NODE_SYMBOL_IDX: {
1127 Str name = node->unique_name;
1128 StrVarMap *map = varmap_lookup(&chunk->varmap, name);
1129 if (!map) {
1130 println("error: unreachable... name: %s", name);
1131 exit(EXIT_FAILURE);
1132 }
1133 1966
1134 // Destination.
1135 u8 reg_dst = chunk->reg_idx++;
1136
1137 // Address.
1138 sz reg_addr = chunk->reg_idx++; 1967 sz reg_addr = chunk->reg_idx++;
1139 if (str_has_prefix(map->val.type, cstr("[]"))) { 1968 emit_op(op_ldaddr, reg_addr, var.idx, 0, node, chunk);
1140 EMIT_OP(OP_LDGADDR, reg_addr, map->val.idx, 0, node->var_val, 1969 return (CompResult){.type = COMP_REG, .idx = reg_addr};
1141 chunk); 1970 } break;
1142 } else { 1971 case NODE_DEREF: {
1143 EMIT_OP(OP_LDGVAR, reg_addr, map->val.idx, 0, node->var_val, 1972 Str type_name = node->type;
1144 chunk); 1973 if (str_has_prefix(type_name, cstr("@")) ||
1974 str_has_prefix(type_name, cstr("["))) {
1975 type_name = cstr("Ptr");
1145 } 1976 }
1146 1977 StrTypeMap *t = strtype_lookup(&compiler->type_map, type_name);
1147 // Index. 1978 sz size = t->val.size;
1148 CompResult idx = compile_expr(chunk, node->arr_size); 1979
1149 switch (idx.type) { 1980 Node *next = node->deref.next;
1150 case COMP_CONST: { 1981 sz n_deref = 0;
1151 EMIT_OP(OP_LD64I, reg_dst, reg_addr, idx.idx, node, chunk); 1982 while (next) {
1152 } break; 1983 n_deref++;
1153 case COMP_REG: { 1984 if (next->kind == NODE_SYMBOL) {
1154 EMIT_OP(OP_LD64, reg_dst, reg_addr, idx.idx, node, chunk); 1985 break;
1155 } break; 1986 }
1156 default: { 1987 next = next->deref.next;
1157 return (CompResult){.type = COMP_ERR}; 1988 }
1158 } break; 1989 CompResult res = compile_symbol(compiler, chunk, next);
1990 sz reg_dst = res.idx;
1991 sz reg_src = res.idx;
1992 for (sz i = 0; i < n_deref; i++) {
1993 reg_dst = chunk->reg_idx++;
1994 if (i == n_deref - 1) {
1995 emit_sized_op(size, OP_LD64K, OP_LD32K, OP_LD16K, OP_LD8K,
1996 reg_dst, reg_src, 0, node, chunk);
1997 } else {
1998 emit_op(OP_LD64K, reg_dst, reg_src, 0, node, chunk);
1999 }
2000 reg_src = reg_dst;
1159 } 2001 }
1160 // TODO: hardcoding the type size for now (LD64/LD64I).
1161 return (CompResult){.type = COMP_REG, .idx = reg_dst}; 2002 return (CompResult){.type = COMP_REG, .idx = reg_dst};
1162 } break; 2003 } break;
1163 case NODE_BLOCK: { 2004 case NODE_BLOCK: {
1164 CompResult res; 2005 CompResult res;
1165 for (sz i = 0; i < array_size(node->elements); i++) { 2006 for (sz i = 0; i < array_size(node->elements); i++) {
1166 Node *root = node->elements[i]; 2007 Node *root = node->elements[i];
1167 res = compile_expr(chunk, root); 2008 res = compile_expr(compiler, chunk, root);
1168 } 2009 }
1169 return res; 2010 return res;
1170 } break; 2011 } break;
2012 case NODE_NIL: return (CompResult){.type = COMP_NIL};
1171 default: { 2013 default: {
1172 eprintln("error: compilation not implemented for node %s", 2014 eprintln("error: compilation not implemented for node %s",
1173 node_str[node->kind]); 2015 node_str[node->kind]);
1174 exit(EXIT_FAILURE); 2016 emit_compile_err(compiler, chunk, node);
2017 return (CompResult){.type = COMP_ERR};
1175 } break; 2018 } break;
1176 } 2019 }
1177 return (CompResult){.type = COMP_ERR}; 2020 return (CompResult){.type = COMP_ERR};
@@ -1188,6 +2031,14 @@ disassemble_instruction(Instruction instruction) {
1188 case OP_MOV16: 2031 case OP_MOV16:
1189 case OP_MOV32: 2032 case OP_MOV32:
1190 case OP_MOV64: 2033 case OP_MOV64:
2034 case OP_LD8K:
2035 case OP_LD16K:
2036 case OP_LD32K:
2037 case OP_LD64K:
2038 case OP_ST8K:
2039 case OP_ST16K:
2040 case OP_ST32K:
2041 case OP_ST64K:
1191 println("%s r%d, r%d", op_str[instruction.op], instruction.dst, 2042 println("%s r%d, r%d", op_str[instruction.op], instruction.dst,
1192 instruction.a, instruction.b); 2043 instruction.a, instruction.b);
1193 break; 2044 break;
@@ -1196,10 +2047,7 @@ disassemble_instruction(Instruction instruction) {
1196 println("%s l%d, r%d", op_str[instruction.op], instruction.dst, 2047 println("%s l%d, r%d", op_str[instruction.op], instruction.dst,
1197 instruction.a, instruction.b); 2048 instruction.a, instruction.b);
1198 break; 2049 break;
1199 case OP_LD8K: 2050 case OP_LDCONST:
1200 case OP_LD16K:
1201 case OP_LD32K:
1202 case OP_LD64K:
1203 println("%s r%d, c%d", op_str[instruction.op], instruction.dst, 2051 println("%s r%d, c%d", op_str[instruction.op], instruction.dst,
1204 instruction.a, instruction.b); 2052 instruction.a, instruction.b);
1205 break; 2053 break;
@@ -1233,6 +2081,7 @@ disassemble_instruction(Instruction instruction) {
1233 case OP_BITRSHIFTI: 2081 case OP_BITRSHIFTI:
1234 case OP_BITANDI: 2082 case OP_BITANDI:
1235 case OP_BITORI: 2083 case OP_BITORI:
2084 case OP_BITXORI:
1236 println("%s r%d, r%d, c%d", op_str[instruction.op], instruction.dst, 2085 println("%s r%d, r%d, c%d", op_str[instruction.op], instruction.dst,
1237 instruction.a, instruction.b); 2086 instruction.a, instruction.b);
1238 break; 2087 break;
@@ -1266,19 +2115,28 @@ disassemble_instruction(Instruction instruction) {
1266 case OP_BITRSHIFT: 2115 case OP_BITRSHIFT:
1267 case OP_BITAND: 2116 case OP_BITAND:
1268 case OP_BITOR: 2117 case OP_BITOR:
2118 case OP_BITXOR:
1269 println("%s r%d, r%d, r%d", op_str[instruction.op], instruction.dst, 2119 println("%s r%d, r%d, r%d", op_str[instruction.op], instruction.dst,
1270 instruction.a, instruction.b); 2120 instruction.a, instruction.b);
1271 break; 2121 break;
1272 case OP_LDGVAR: 2122 case OP_LDGVAR:
1273 case OP_LDGADDR: 2123 case OP_LDGADDR:
2124 case OP_LDLVAR:
2125 case OP_LDLADDR:
1274 println("%s r%d, v%d", op_str[instruction.op], instruction.dst, 2126 println("%s r%d, v%d", op_str[instruction.op], instruction.dst,
1275 instruction.a, instruction.b); 2127 instruction.a, instruction.b);
1276 break; 2128 break;
2129 case OP_LDSTR:
2130 println("%s r%d, s%d", op_str[instruction.op], instruction.dst,
2131 instruction.a, instruction.b);
2132 break;
1277 case OP_STGVAR: 2133 case OP_STGVAR:
2134 case OP_STLVAR:
1278 println("%s v%d, r%d", op_str[instruction.op], instruction.dst, 2135 println("%s v%d, r%d", op_str[instruction.op], instruction.dst,
1279 instruction.a, instruction.b); 2136 instruction.a, instruction.b);
1280 break; 2137 break;
1281 case OP_STGVARI: 2138 case OP_STGVARI:
2139 case OP_STLVARI:
1282 println("%s v%d, c%d", op_str[instruction.op], instruction.dst, 2140 println("%s v%d, c%d", op_str[instruction.op], instruction.dst,
1283 instruction.a, instruction.b); 2141 instruction.a, instruction.b);
1284 break; 2142 break;
@@ -1301,17 +2159,36 @@ disassemble_instruction(Instruction instruction) {
1301 println("%s l%d, c%d", op_str[instruction.op], instruction.dst, 2159 println("%s l%d, c%d", op_str[instruction.op], instruction.dst,
1302 instruction.a, instruction.b); 2160 instruction.a, instruction.b);
1303 break; 2161 break;
2162 case OP_PRINTS8:
2163 case OP_PRINTS16:
2164 case OP_PRINTS32:
1304 case OP_PRINTS64: 2165 case OP_PRINTS64:
2166 case OP_PRINTU8:
2167 case OP_PRINTU16:
2168 case OP_PRINTU32:
2169 case OP_PRINTU64:
2170 case OP_PRINTF32:
1305 case OP_PRINTF64: 2171 case OP_PRINTF64:
1306 case OP_PRINTSTR: 2172 case OP_PRINTSTR:
2173 case OP_PRINTBOOL:
1307 case OP_PUSH: 2174 case OP_PUSH:
1308 case OP_POP: 2175 case OP_POP:
1309 case OP_PUTRET: 2176 case OP_PUTRET:
1310 println("%s r%d", op_str[instruction.op], instruction.dst, 2177 println("%s r%d", op_str[instruction.op], instruction.dst,
1311 instruction.a, instruction.b); 2178 instruction.a, instruction.b);
1312 break; 2179 break;
2180 case OP_PRINTSTRI:
2181 case OP_PRINTS8I:
2182 case OP_PRINTS16I:
2183 case OP_PRINTS32I:
1313 case OP_PRINTS64I: 2184 case OP_PRINTS64I:
2185 case OP_PRINTU8I:
2186 case OP_PRINTU16I:
2187 case OP_PRINTU32I:
2188 case OP_PRINTU64I:
2189 case OP_PRINTF32I:
1314 case OP_PRINTF64I: 2190 case OP_PRINTF64I:
2191 case OP_PRINTBOOLI:
1315 case OP_RESERVE: 2192 case OP_RESERVE:
1316 case OP_PUSHI: 2193 case OP_PUSHI:
1317 case OP_PUTRETI: 2194 case OP_PUTRETI:
@@ -1319,6 +2196,7 @@ disassemble_instruction(Instruction instruction) {
1319 instruction.a, instruction.b); 2196 instruction.a, instruction.b);
1320 break; 2197 break;
1321 case OP_RET: 2198 case OP_RET:
2199 case OP_RECUR:
1322 case OP_HALT: println("%s", op_str[instruction.op]); break; 2200 case OP_HALT: println("%s", op_str[instruction.op]); break;
1323 default: println("Unknown opcode %d", instruction.op); break; 2201 default: println("Unknown opcode %d", instruction.op); break;
1324 } 2202 }
@@ -1336,11 +2214,25 @@ disassemble_chunk(Chunk chunk) {
1336 for (sz i = 0; i < array_size(chunk.code); i++) { 2214 for (sz i = 0; i < array_size(chunk.code); i++) {
1337 printf(" %.4ld:%.4ld %.4lx ", chunk.linecol[i].line, 2215 printf(" %.4ld:%.4ld %.4lx ", chunk.linecol[i].line,
1338 chunk.linecol[i].col, i); 2216 chunk.linecol[i].col, i);
1339 IntIntMap *label = intintmap_lookup(&chunk.labels_rev, i); 2217 IntIntMapIter lab_it = intintmap_iterator(chunk.labels, chunk.storage);
1340 if (label) { 2218 IntIntMap *m = intintmap_next(&lab_it, chunk.storage);
1341 printf(".L%.2ld ", label->val); 2219 Str labs = cstr("");
2220 while (m) {
2221 if (m->val == i) {
2222 labs = str_concat(labs, cstr(".L"), chunk.storage);
2223 labs = str_concat(labs, str_from_int(m->key, chunk.storage),
2224 chunk.storage);
2225 break;
2226 }
2227 m = intintmap_next(&lab_it, chunk.storage);
2228 }
2229 if (labs.size) {
2230 print("%s", labs);
2231 for (sz i = 0; i < 7 - labs.size; i++) {
2232 print(" ");
2233 }
1342 } else { 2234 } else {
1343 printf(" %2s ", ""); 2235 printf(" ");
1344 } 2236 }
1345 disassemble_instruction(chunk.code[i]); 2237 disassemble_instruction(chunk.code[i]);
1346 } 2238 }
@@ -1361,7 +2253,7 @@ disassemble_chunk(Chunk chunk) {
1361 for (sz i = 0; i < array_size(chunk.vars); i++) { 2253 for (sz i = 0; i < array_size(chunk.vars); i++) {
1362 println(" %x{2}: [%x{4}:%x{4}] %s: %s", i, chunk.vars[i].offset, 2254 println(" %x{2}: [%x{4}:%x{4}] %s: %s", i, chunk.vars[i].offset,
1363 chunk.vars[i].offset + chunk.vars[i].size, 2255 chunk.vars[i].offset + chunk.vars[i].size,
1364 chunk.vars[i].name, chunk.vars[i].type); 2256 chunk.vars[i].name, chunk.vars[i].type_name);
1365 } 2257 }
1366 } 2258 }
1367 if (array_size(chunk.functions) > 0) { 2259 if (array_size(chunk.functions) > 0) {
@@ -1378,4 +2270,75 @@ disassemble_chunk(Chunk chunk) {
1378 } 2270 }
1379} 2271}
1380 2272
2273void
2274bytecode_compiler(Compiler *compiler, Parser parser) {
2275 compiler->main_chunk = (Chunk){
2276 .file_name = compiler->file_name,
2277 .storage = compiler->storage,
2278 .name = cstr(".main"),
2279 };
2280 array_zero(compiler->main_chunk.constants, 256, compiler->storage);
2281 array_zero(compiler->main_chunk.code, 0xffff, compiler->storage);
2282 sz n_roots = array_size(parser.nodes);
2283
2284 // Fill up builtin types and tables.
2285 for (sz i = 0; i < LEN(builtin_types); i++) {
2286 Type type = builtin_types[i];
2287 strtype_insert(&compiler->type_map, type.unique_name, type,
2288 compiler->storage);
2289 }
2290 Str unsigned_ints[] = {
2291 cstr("U8"), cstr("U16"), cstr("U32"),
2292 cstr("U64"), cstr("Ptr"), cstr("UInt"),
2293 };
2294 for (sz i = 0; i < LEN(unsigned_ints); i++) {
2295 Str type = unsigned_ints[i];
2296 strset_insert(&compiler->unsigned_ints, type, compiler->storage);
2297 }
2298 Str signed_ints[] = {
2299 cstr("S8"), cstr("S16"), cstr("S32"), cstr("S64"), cstr("Int"),
2300 };
2301 for (sz i = 0; i < LEN(signed_ints); i++) {
2302 Str type = signed_ints[i];
2303 strset_insert(&compiler->signed_ints, type, compiler->storage);
2304 }
2305
2306 // Do a first pass to setup the function declarations on the main scope.
2307 Chunk *chunk = &compiler->main_chunk;
2308 for (sz i = 0; i < n_roots; i++) {
2309 Node *root = parser.nodes[i];
2310 if (root->kind == NODE_FUN) {
2311 declare_function(chunk, root);
2312 }
2313 }
2314
2315 // Compile all root expressions.
2316 CompResult res = {0};
2317 for (sz i = 0; i < n_roots; i++) {
2318 Node *root = parser.nodes[i];
2319 res = compile_expr(compiler, chunk, root);
2320 }
2321
2322 // Make sure the last result is on r0.
2323 sz res_reg = 0;
2324 bool is_nil = false;
2325 switch (res.type) {
2326 case COMP_CONST: {
2327 res_reg = chunk->reg_idx++;
2328 Instruction inst =
2329 (Instruction){.op = OP_LDCONST, .dst = res_reg, .a = res.idx};
2330 array_push(chunk->code, inst, chunk->storage);
2331 } break;
2332 case COMP_REG: {
2333 res_reg = res.idx;
2334 } break;
2335 case COMP_NIL: {
2336 is_nil = true;
2337 } break;
2338 default: break;
2339 }
2340 emit_op(OP_HALT, res_reg, !is_nil, 0, NULL, chunk);
2341 verify_chunk(chunk);
2342}
2343
1381#endif // COMPILER_C 2344#endif // COMPILER_C
diff --git a/src/lexer.c b/src/lexer.c
index 2feba2a..84b69e7 100644
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -41,18 +41,24 @@ typedef enum TokenKind {
41 TOK_STRUCT, // struct 41 TOK_STRUCT, // struct
42 TOK_TRUE, // true 42 TOK_TRUE, // true
43 TOK_WHILE, // while 43 TOK_WHILE, // while
44 TOK_FOR, // for
44 45
45 // Arithmetic ops. 46 // Arithmetic ops.
46 TOK_ADD, // + 47 TOK_ADD, // +
47 TOK_SUB, // - 48 TOK_SUB, // -
48 TOK_MUL, // * 49 TOK_MUL, // *
49 TOK_DIV, // / 50 TOK_DIV, // /
50 TOK_MOD, // % 51 TOK_MOD, // %
52 TOK_ADD_ASSIGN, // +=
53 TOK_SUB_ASSIGN, // -=
54 TOK_MUL_ASSIGN, // *=
55 TOK_DIV_ASSIGN, // /=
56 TOK_MOD_ASSIGN, // %=
51 57
52 // Logical ops. 58 // Logical ops.
53 TOK_NOT, // ! 59 TOK_NOT, // !
54 TOK_AND, // && 60 TOK_AND, // and
55 TOK_OR, // || 61 TOK_OR, // or
56 TOK_EQ, // == 62 TOK_EQ, // ==
57 TOK_NEQ, // != 63 TOK_NEQ, // !=
58 TOK_LT, // < 64 TOK_LT, // <
@@ -61,11 +67,17 @@ typedef enum TokenKind {
61 TOK_GE, // >= 67 TOK_GE, // >=
62 68
63 // Bitwise ops. 69 // Bitwise ops.
64 TOK_BITNOT, // ~ 70 TOK_BITNOT, // ~
65 TOK_BITAND, // & 71 TOK_BITAND, // &
66 TOK_BITOR, // | 72 TOK_BITOR, // |
67 TOK_BITLSHIFT, // << 73 TOK_BITXOR, // ^
68 TOK_BITRSHIFT, // >> 74 TOK_BITLSHIFT, // <<
75 TOK_BITRSHIFT, // >>
76 TOK_BITAND_ASSIGN, // &=
77 TOK_BITOR_ASSIGN, // |=
78 TOK_BITXOR_ASSIGN, // ^=
79 TOK_BITLSHIFT_ASSIGN, // <<=
80 TOK_BITRSHIFT_ASSIGN, // >>=
69 81
70 // Special ops. 82 // Special ops.
71 TOK_COLON, // : 83 TOK_COLON, // :
@@ -113,6 +125,7 @@ Str token_str[] = {
113 [TOK_STRUCT] = cstr("STRUCT"), 125 [TOK_STRUCT] = cstr("STRUCT"),
114 [TOK_TRUE] = cstr("TRUE"), 126 [TOK_TRUE] = cstr("TRUE"),
115 [TOK_WHILE] = cstr("WHILE"), 127 [TOK_WHILE] = cstr("WHILE"),
128 [TOK_FOR] = cstr("FOR"),
116 129
117 // Arithmetic ops. 130 // Arithmetic ops.
118 [TOK_ADD] = cstr("ADD"), 131 [TOK_ADD] = cstr("ADD"),
@@ -120,6 +133,11 @@ Str token_str[] = {
120 [TOK_MUL] = cstr("MUL"), 133 [TOK_MUL] = cstr("MUL"),
121 [TOK_DIV] = cstr("DIV"), 134 [TOK_DIV] = cstr("DIV"),
122 [TOK_MOD] = cstr("MOD"), 135 [TOK_MOD] = cstr("MOD"),
136 [TOK_ADD_ASSIGN] = cstr("ADD_ASSIGN"),
137 [TOK_SUB_ASSIGN] = cstr("SUB_ASSIGN"),
138 [TOK_MUL_ASSIGN] = cstr("MUL_ASSIGN"),
139 [TOK_DIV_ASSIGN] = cstr("DIV_ASSIGN"),
140 [TOK_MOD_ASSIGN] = cstr("MOD_ASSIGN"),
123 141
124 // Logical ops. 142 // Logical ops.
125 [TOK_NOT] = cstr("NOT"), 143 [TOK_NOT] = cstr("NOT"),
@@ -136,8 +154,14 @@ Str token_str[] = {
136 [TOK_BITNOT] = cstr("BITNOT"), 154 [TOK_BITNOT] = cstr("BITNOT"),
137 [TOK_BITAND] = cstr("BITAND"), 155 [TOK_BITAND] = cstr("BITAND"),
138 [TOK_BITOR] = cstr("BITOR"), 156 [TOK_BITOR] = cstr("BITOR"),
157 [TOK_BITXOR] = cstr("BITXOR"),
139 [TOK_BITLSHIFT] = cstr("BITLSHIFT"), 158 [TOK_BITLSHIFT] = cstr("BITLSHIFT"),
140 [TOK_BITRSHIFT] = cstr("BITRSHIFT"), 159 [TOK_BITRSHIFT] = cstr("BITRSHIFT"),
160 [TOK_BITAND_ASSIGN] = cstr("BITAND_ASSIGN"),
161 [TOK_BITOR_ASSIGN] = cstr("BITOR_ASSIGN"),
162 [TOK_BITXOR_ASSIGN] = cstr("BITXOR_ASSIGN"),
163 [TOK_BITLSHIFT_ASSIGN] = cstr("BITLSHIFT_ASSIGN"),
164 [TOK_BITRSHIFT_ASSIGN] = cstr("BITRSHIFT_ASSIGN"),
141 165
142 // Special ops. 166 // Special ops.
143 [TOK_COLON] = cstr("COLON"), 167 [TOK_COLON] = cstr("COLON"),
@@ -432,6 +456,10 @@ scan_token(Scanner *scanner) {
432 *scanner = current; 456 *scanner = current;
433 return emit_token_number(scanner); 457 return emit_token_number(scanner);
434 } 458 }
459 if (p == '=') {
460 scan_next(scanner);
461 return emit_token(current, scanner, TOK_ADD_ASSIGN);
462 }
435 return emit_token(current, scanner, TOK_ADD); 463 return emit_token(current, scanner, TOK_ADD);
436 }; 464 };
437 case '-': { 465 case '-': {
@@ -440,11 +468,33 @@ scan_token(Scanner *scanner) {
440 *scanner = current; 468 *scanner = current;
441 return emit_token_number(scanner); 469 return emit_token_number(scanner);
442 } 470 }
471 if (p == '=') {
472 scan_next(scanner);
473 return emit_token(current, scanner, TOK_SUB_ASSIGN);
474 }
443 return emit_token(current, scanner, TOK_SUB); 475 return emit_token(current, scanner, TOK_SUB);
444 }; 476 };
445 case '*': return emit_token(current, scanner, TOK_MUL); 477 case '*': {
446 case '/': return emit_token(current, scanner, TOK_DIV); 478 if (scan_peek(scanner) == '=') {
447 case '%': return emit_token(current, scanner, TOK_MOD); 479 scan_next(scanner);
480 return emit_token(current, scanner, TOK_MUL_ASSIGN);
481 }
482 return emit_token(current, scanner, TOK_MUL);
483 }
484 case '/': {
485 if (scan_peek(scanner) == '=') {
486 scan_next(scanner);
487 return emit_token(current, scanner, TOK_DIV_ASSIGN);
488 }
489 return emit_token(current, scanner, TOK_DIV);
490 }
491 case '%': {
492 if (scan_peek(scanner) == '=') {
493 scan_next(scanner);
494 return emit_token(current, scanner, TOK_MOD_ASSIGN);
495 }
496 return emit_token(current, scanner, TOK_MOD);
497 }
448 case '!': { 498 case '!': {
449 if (scan_peek(scanner) == '=') { 499 if (scan_peek(scanner) == '=') {
450 scan_next(scanner); 500 scan_next(scanner);
@@ -467,6 +517,10 @@ scan_token(Scanner *scanner) {
467 } 517 }
468 if (p == '<') { 518 if (p == '<') {
469 scan_next(scanner); 519 scan_next(scanner);
520 if (scan_peek(scanner) == '=') {
521 scan_next(scanner);
522 return emit_token(current, scanner, TOK_BITLSHIFT_ASSIGN);
523 }
470 return emit_token(current, scanner, TOK_BITLSHIFT); 524 return emit_token(current, scanner, TOK_BITLSHIFT);
471 } 525 }
472 return emit_token(current, scanner, TOK_LT); 526 return emit_token(current, scanner, TOK_LT);
@@ -479,22 +533,33 @@ scan_token(Scanner *scanner) {
479 } 533 }
480 if (p == '>') { 534 if (p == '>') {
481 scan_next(scanner); 535 scan_next(scanner);
536 if (scan_peek(scanner) == '=') {
537 scan_next(scanner);
538 return emit_token(current, scanner, TOK_BITRSHIFT_ASSIGN);
539 }
482 return emit_token(current, scanner, TOK_BITRSHIFT); 540 return emit_token(current, scanner, TOK_BITRSHIFT);
483 } 541 }
484 return emit_token(current, scanner, TOK_GT); 542 return emit_token(current, scanner, TOK_GT);
485 }; 543 };
486 case '~': return emit_token(current, scanner, TOK_BITNOT); 544 case '~': return emit_token(current, scanner, TOK_BITNOT);
545 case '^': {
546 if (scan_peek(scanner) == '=') {
547 scan_next(scanner);
548 return emit_token(current, scanner, TOK_BITXOR_ASSIGN);
549 }
550 return emit_token(current, scanner, TOK_BITXOR);
551 };
487 case '&': { 552 case '&': {
488 if (scan_peek(scanner) == '&') { 553 if (scan_peek(scanner) == '=') {
489 scan_next(scanner); 554 scan_next(scanner);
490 return emit_token(current, scanner, TOK_AND); 555 return emit_token(current, scanner, TOK_BITOR_ASSIGN);
491 } 556 }
492 return emit_token(current, scanner, TOK_BITAND); 557 return emit_token(current, scanner, TOK_BITAND);
493 }; 558 };
494 case '|': { 559 case '|': {
495 if (scan_peek(scanner) == '|') { 560 if (scan_peek(scanner) == '=') {
496 scan_next(scanner); 561 scan_next(scanner);
497 return emit_token(current, scanner, TOK_OR); 562 return emit_token(current, scanner, TOK_BITOR_ASSIGN);
498 } 563 }
499 return emit_token(current, scanner, TOK_BITOR); 564 return emit_token(current, scanner, TOK_BITOR);
500 }; 565 };
@@ -535,78 +600,91 @@ scan_token(Scanner *scanner) {
535 return emit_token_err(&current, cstr("unexpected character")); 600 return emit_token_err(&current, cstr("unexpected character"));
536 } 601 }
537 switch (val.mem[0]) { 602 switch (val.mem[0]) {
603 case 'a': {
604 if (str_eq(val, cstr("and"))) {
605 return emit_token(current, scanner, TOK_AND);
606 }
607 } break;
538 case 'b': { 608 case 'b': {
539 if (str_has_prefix(val, cstr("break"))) { 609 if (str_eq(val, cstr("break"))) {
540 return emit_token(current, scanner, TOK_BREAK); 610 return emit_token(current, scanner, TOK_BREAK);
541 } 611 }
542 } break; 612 } break;
543 case 'c': { 613 case 'c': {
544 if (str_has_prefix(val, cstr("case"))) { 614 if (str_eq(val, cstr("case"))) {
545 return emit_token(current, scanner, TOK_CASE); 615 return emit_token(current, scanner, TOK_CASE);
546 } 616 }
547 if (str_has_prefix(val, cstr("continue"))) { 617 if (str_eq(val, cstr("continue"))) {
548 return emit_token(current, scanner, TOK_CONTINUE); 618 return emit_token(current, scanner, TOK_CONTINUE);
549 } 619 }
550 if (str_has_prefix(val, cstr("cond"))) { 620 if (str_eq(val, cstr("cond"))) {
551 return emit_token(current, scanner, TOK_COND); 621 return emit_token(current, scanner, TOK_COND);
552 } 622 }
553 } break; 623 } break;
554 case 'e': { 624 case 'e': {
555 if (str_has_prefix(val, cstr("else"))) { 625 if (str_eq(val, cstr("else"))) {
556 return emit_token(current, scanner, TOK_ELSE); 626 return emit_token(current, scanner, TOK_ELSE);
557 } 627 }
558 if (str_has_prefix(val, cstr("enum"))) { 628 if (str_eq(val, cstr("enum"))) {
559 return emit_token(current, scanner, TOK_ENUM); 629 return emit_token(current, scanner, TOK_ENUM);
560 } 630 }
561 } break; 631 } break;
562 case 'f': { 632 case 'f': {
563 if (str_has_prefix(val, cstr("false"))) { 633 if (str_eq(val, cstr("false"))) {
564 return emit_token(current, scanner, TOK_FALSE); 634 return emit_token(current, scanner, TOK_FALSE);
565 } 635 }
566 if (str_has_prefix(val, cstr("fun"))) { 636 if (str_eq(val, cstr("fun"))) {
567 return emit_token(current, scanner, TOK_FUN); 637 return emit_token(current, scanner, TOK_FUN);
568 } 638 }
639 if (str_eq(val, cstr("for"))) {
640 return emit_token(current, scanner, TOK_FOR);
641 }
569 } break; 642 } break;
570 case 'i': { 643 case 'i': {
571 if (str_has_prefix(val, cstr("if"))) { 644 if (str_eq(val, cstr("if"))) {
572 return emit_token(current, scanner, TOK_IF); 645 return emit_token(current, scanner, TOK_IF);
573 } 646 }
574 } break; 647 } break;
575 case 'l': { 648 case 'l': {
576 if (str_has_prefix(val, cstr("let"))) { 649 if (str_eq(val, cstr("let"))) {
577 return emit_token(current, scanner, TOK_LET); 650 return emit_token(current, scanner, TOK_LET);
578 } 651 }
579 } break; 652 } break;
580 case 'm': { 653 case 'm': {
581 if (str_has_prefix(val, cstr("match"))) { 654 if (str_eq(val, cstr("match"))) {
582 return emit_token(current, scanner, TOK_MATCH); 655 return emit_token(current, scanner, TOK_MATCH);
583 } 656 }
584 } break; 657 } break;
585 case 'n': { 658 case 'n': {
586 if (str_has_prefix(val, cstr("nil"))) { 659 if (str_eq(val, cstr("nil"))) {
587 return emit_token(current, scanner, TOK_NIL); 660 return emit_token(current, scanner, TOK_NIL);
588 } 661 }
589 } break; 662 } break;
590 case 'r': { 663 case 'r': {
591 if (str_has_prefix(val, cstr("return"))) { 664 if (str_eq(val, cstr("return"))) {
592 return emit_token(current, scanner, TOK_RETURN); 665 return emit_token(current, scanner, TOK_RETURN);
593 } 666 }
594 } break; 667 } break;
595 case 's': { 668 case 's': {
596 if (str_has_prefix(val, cstr("set"))) { 669 if (str_eq(val, cstr("set"))) {
597 return emit_token(current, scanner, TOK_SET); 670 return emit_token(current, scanner, TOK_SET);
598 } 671 }
599 if (str_has_prefix(val, cstr("struct"))) { 672 if (str_eq(val, cstr("struct"))) {
600 return emit_token(current, scanner, TOK_STRUCT); 673 return emit_token(current, scanner, TOK_STRUCT);
601 } 674 }
602 } break; 675 } break;
603 case 't': { 676 case 't': {
604 if (str_has_prefix(val, cstr("true"))) { 677 if (str_eq(val, cstr("true"))) {
605 return emit_token(current, scanner, TOK_TRUE); 678 return emit_token(current, scanner, TOK_TRUE);
606 } 679 }
607 } break; 680 } break;
681 case 'o': {
682 if (str_eq(val, cstr("or"))) {
683 return emit_token(current, scanner, TOK_OR);
684 }
685 } break;
608 case 'w': { 686 case 'w': {
609 if (str_has_prefix(val, cstr("while"))) { 687 if (str_eq(val, cstr("while"))) {
610 return emit_token(current, scanner, TOK_WHILE); 688 return emit_token(current, scanner, TOK_WHILE);
611 } 689 }
612 } break; 690 } break;
@@ -628,4 +706,4 @@ print_tokens(Str path, Token *tokens) {
628 } 706 }
629} 707}
630 708
631#endif // LEXER_C 709#endif // LEXER_C
diff --git a/src/main.c b/src/main.c
index 3c3dd29..1ede868 100644
--- a/src/main.c
+++ b/src/main.c
@@ -12,19 +12,49 @@
12// TODO: unions 12// TODO: unions
13// TODO: embed (binary file) and include (source file) 13// TODO: embed (binary file) and include (source file)
14// TODO: revisit ast parsing for pointers and arrays (I think I'm missing corner 14// TODO: revisit ast parsing for pointers and arrays (I think I'm missing corner
15// cases). 15// cases):
16// TODO: for loops? 16// []Int vs Int[], @sym vs sym@. On the right dereference, on the left
17// for i = 0 , i < 10 , i++ { 17// declaration or taking the address/reference of a variable. Similar
18// 18// to what Odin does.
19// let a: @Int ; pointer to int
20// let b: @@Int ; pointer to pointer to int (etc.)
21// let c: [123]Int ; static array -> @Int
22// let m: [32][32]Int ; multi-dimensional-arrays
23// let d: []Int ; slice / view -> struct Slice { u8* mem ; sz size ; }
24// let e: [...]Int ; dynamic array -> struct DArry { u8* mem ; sz size ; sz cap ; }
25// let f: [123]@Int ; static array of int pointers [](@Int)
26// let g: @[123]Int ; pointer to a static array of integers @([123]Int)
27// let h: #[Str:Int] ; Hash map of string keys and integer values
28// let i: #[Str:@Int] ; Hash map of string keys and pointers to integer
29// let j: #[@Str:Int] ; Hash map of string pointers to integers
30// let k: @#[Str:Int] ; Pointer to a hash map of string to ints
31// let l: (Int Int : Int) ; Function pointer == @(fun(Int,Int):Int)
32// TODO: constexpr or const expressions could be evaluated with the bytecode
33// interpreter if we are performing compilation.
34// TODO: "first class functions" via function pointers
35// TODO: convenient function calls per data type instead of methods:
36// fun add(a: int, b: int): int a + b
37// add(12, 34) == 12.add(34)
38// concat(str, str): str
39// "hello ".concat("world") ; "hello world"
40// TODO: structs and user defined types
41// TODO: constant folding
42// TODO: casting on demand (1:u16, 0x123:ptr, "hi":int ??? how to deal with
43// unsafe casts?)
44// TODO: extract table generation from compiler into the semantic analyzer,
45// compiler should only focus on translating things to bytecode/linear ir.
46// TODO: sizeof function doesn't work well for arrays and variables.
47// TODO: store more parameters for variables, for example
48// TODO: don't allow overwriting default types with other symbols within a scope
49// {
50// let Int = 0.0
19// } 51// }
20// TODO: fix semantics for the following expression: 52// TODO: This shouldn't be possible
21// let b = int 53// let b = 4
22// a type shouldn't be a valid symbol name 54// let a: [32]U8 = @b
23// TODO: fix semantics for arrays: static arrays can't have size 0. 55// TODO: Properly reference and dereference multiple chains of arrays:
24// TODO: consider making all tye types PascalCase: Int F64 Str... 56// let a: [32][32]Int ; The size is not correct at the moment for this.
25// TODO: add a `const` keyword that can only take literals or constexpr values. 57// a[1][2] ?
26// TODO: add assignment operators instead of `set` :=, +=, -=
27// TODO: add mifix operators ++ and --
28 58
29typedef enum ExecMode { 59typedef enum ExecMode {
30 RUN_NORMAL, 60 RUN_NORMAL,
@@ -56,6 +86,9 @@ process_file(Str path) {
56 sz errors = 0; 86 sz errors = 0;
57 87
58 // Lexer. 88 // Lexer.
89#if DEBUG == 1
90 println("lexing...");
91#endif
59 Scanner scanner = {.str = file.data}; 92 Scanner scanner = {.str = file.data};
60 Token *tokens = NULL; 93 Token *tokens = NULL;
61 Token tok = {0}; 94 Token tok = {0};
@@ -79,6 +112,9 @@ process_file(Str path) {
79 } 112 }
80 113
81 // Parser. 114 // Parser.
115#if DEBUG == 1
116 println("parsing...");
117#endif
82 Parser parser = { 118 Parser parser = {
83 .tokens = tokens, 119 .tokens = tokens,
84 .storage = &lexer_arena, 120 .storage = &lexer_arena,
@@ -92,9 +128,6 @@ process_file(Str path) {
92 println("ROOT: %d", ctr++); 128 println("ROOT: %d", ctr++);
93#endif 129#endif
94 parse_expr(&parser, PREC_LOW); 130 parse_expr(&parser, PREC_LOW);
95 if (parser.panic) {
96 break;
97 }
98 } 131 }
99 parse_consume(&parser, TOK_EOF, cstr("expected end of file")); 132 parse_consume(&parser, TOK_EOF, cstr("expected end of file"));
100 if (parser.err) { 133 if (parser.err) {
@@ -106,6 +139,9 @@ process_file(Str path) {
106 } 139 }
107 140
108 // Semantic analysis. 141 // Semantic analysis.
142#if DEBUG == 1
143 println("semantic analysis...");
144#endif
109 Analyzer analyzer = (Analyzer){ 145 Analyzer analyzer = (Analyzer){
110 .storage = &lexer_arena, 146 .storage = &lexer_arena,
111 .file_name = path, 147 .file_name = path,
@@ -175,68 +211,26 @@ process_file(Str path) {
175 } 211 }
176#endif 212#endif
177 213
178 // TODO: Type checking.
179
180 // Compile roots. 214 // Compile roots.
215#if DEBUG == 1
216 println("compilation...");
217#endif
181 Arena bytecode_arena = arena_create(LEXER_MEM, os_allocator); 218 Arena bytecode_arena = arena_create(LEXER_MEM, os_allocator);
182 Chunk chunk = { 219 Compiler compiler = {
183 .file_name = path, 220 .file_name = path,
184 .storage = &bytecode_arena, 221 .storage = &bytecode_arena,
185 .name = cstr(".main"), 222 .integer_types = analyzer.integer_types,
223 .float_types = analyzer.float_types,
224 .numeric_types = analyzer.numeric_types,
225 .lab_pre = -1,
226 .lab_post = -1,
186 }; 227 };
187 array_zero(chunk.constants, 256, &bytecode_arena); 228 bytecode_compiler(&compiler, parser);
188 array_zero(chunk.code, 0xffff, &bytecode_arena); 229 disassemble_chunk(compiler.main_chunk);
189 sz n_roots = array_size(parser.nodes);
190 CompResult res = {0};
191 for (sz i = 0; i < n_roots; i++) {
192 // The parser stores the root nodes as a stack.
193 Node *root = parser.nodes[i];
194 res = compile_expr(&chunk, root);
195 if (res.type == COMP_ERR) {
196 eprintln("compilation error...");
197 exit(EXIT_FAILURE);
198 }
199 }
200 // Make sure the last result is on r0.
201 sz res_reg = 0;
202 bool is_nil = false;
203 switch (res.type) {
204 case COMP_CONST: {
205 res_reg = chunk.reg_idx++;
206 Instruction inst =
207 (Instruction){.op = OP_LD64K, .dst = res_reg, .a = res.idx};
208 array_push(chunk.code, inst, chunk.storage);
209 } break;
210 case COMP_REG: {
211 res_reg = res.idx;
212 } break;
213 case COMP_NIL: {
214 is_nil = true;
215 } break;
216 default: break;
217 }
218 EMIT_OP(OP_HALT, res_reg, !is_nil, 0, NULL, &chunk);
219
220 if (chunk.const_idx >= 256) {
221 eprintln("too many constants on chunk %s", chunk.id);
222 exit(EXIT_FAILURE);
223 }
224 if (chunk.str_idx >= 256) {
225 eprintln("too many strings on chunk %s", chunk.id);
226 exit(EXIT_FAILURE);
227 }
228 if (chunk.reg_idx >= 256) {
229 eprintln("too many registers used on chunk %s", chunk.id);
230 exit(EXIT_FAILURE);
231 }
232
233 disassemble_chunk(chunk);
234 230
235 // Run bytecode on VM. 231 // Run bytecode on VM.
236 VM vm = {0}; 232 VM vm = {0};
237 vm_init(&vm, &chunk); 233 vm_init(&vm, &compiler.main_chunk);
238 // println("VM REGISTERS BEFORE:\n%{Mem}",
239 // &(Array){.mem = (u8 *)&vm.regs, sizeof(vm.regs)});
240 vm_run(&vm); 234 vm_run(&vm);
241#if DEBUG == 1 235#if DEBUG == 1
242 println("MEMORY:\n%{Mem}", 236 println("MEMORY:\n%{Mem}",
diff --git a/src/parser.c b/src/parser.c
index 90adaf3..05a00e7 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -9,6 +9,7 @@
9// 9//
10 10
11typedef enum NodeKind { 11typedef enum NodeKind {
12 NODE_ERR,
12 // Arithmetic. 13 // Arithmetic.
13 NODE_ADD, 14 NODE_ADD,
14 NODE_SUB, 15 NODE_SUB,
@@ -29,6 +30,7 @@ typedef enum NodeKind {
29 NODE_BITNOT, 30 NODE_BITNOT,
30 NODE_BITAND, 31 NODE_BITAND,
31 NODE_BITOR, 32 NODE_BITOR,
33 NODE_BITXOR,
32 NODE_BITLSHIFT, 34 NODE_BITLSHIFT,
33 NODE_BITRSHIFT, 35 NODE_BITRSHIFT,
34 // Literals. 36 // Literals.
@@ -60,15 +62,18 @@ typedef enum NodeKind {
60 NODE_FUNCALL, 62 NODE_FUNCALL,
61 NODE_RETURN, 63 NODE_RETURN,
62 // Helpers. 64 // Helpers.
63 NODE_SYMBOL_IDX,
64 NODE_TYPE, 65 NODE_TYPE,
65 NODE_COMPOUND_TYPE, 66 NODE_COMPOUND_TYPE,
66 NODE_ARR_TYPE,
67 NODE_FIELD, 67 NODE_FIELD,
68 NODE_BLOCK, 68 NODE_BLOCK,
69 NODE_PTR,
70 NODE_DEREF,
71 NODE_ARR,
72 NODE_INDEX,
69} NodeKind; 73} NodeKind;
70 74
71Str node_str[] = { 75Str node_str[] = {
76 [NODE_ERR] = cstr("ERR"),
72 // Arithmetic. 77 // Arithmetic.
73 [NODE_ADD] = cstr("ADD"), 78 [NODE_ADD] = cstr("ADD"),
74 [NODE_SUB] = cstr("SUB"), 79 [NODE_SUB] = cstr("SUB"),
@@ -89,6 +94,7 @@ Str node_str[] = {
89 [NODE_BITNOT] = cstr("BITNOT"), 94 [NODE_BITNOT] = cstr("BITNOT"),
90 [NODE_BITAND] = cstr("BITAND"), 95 [NODE_BITAND] = cstr("BITAND"),
91 [NODE_BITOR] = cstr("BITOR"), 96 [NODE_BITOR] = cstr("BITOR"),
97 [NODE_BITXOR] = cstr("BITXOR"),
92 [NODE_BITLSHIFT] = cstr("BITLSHIFT"), 98 [NODE_BITLSHIFT] = cstr("BITLSHIFT"),
93 [NODE_BITRSHIFT] = cstr("BITRSHIFT"), 99 [NODE_BITRSHIFT] = cstr("BITRSHIFT"),
94 // Literals. 100 // Literals.
@@ -122,81 +128,137 @@ Str node_str[] = {
122 // Helpers. 128 // Helpers.
123 [NODE_TYPE] = cstr("TYPE"), 129 [NODE_TYPE] = cstr("TYPE"),
124 [NODE_COMPOUND_TYPE] = cstr("COMPOUND TYPE"), 130 [NODE_COMPOUND_TYPE] = cstr("COMPOUND TYPE"),
125 [NODE_ARR_TYPE] = cstr("TYPE (ARR)"),
126 [NODE_SYMBOL_IDX] = cstr("SYMBOL[IDX]"),
127 [NODE_FIELD] = cstr("FIELD"), 131 [NODE_FIELD] = cstr("FIELD"),
128 [NODE_BLOCK] = cstr("BLOCK"), 132 [NODE_BLOCK] = cstr("BLOCK"),
133 [NODE_PTR] = cstr("@"),
134 [NODE_DEREF] = cstr("DEREF"),
135 [NODE_ARR] = cstr("ARR"),
136 [NODE_INDEX] = cstr("INDEX"),
129}; 137};
130 138
139typedef union NodeLit {
140 f64 d;
141 sz i;
142 u64 u;
143 Str str;
144 Str sym;
145} NodeLit;
146
147typedef struct NodeBinary {
148 struct Node *left;
149 struct Node *right;
150} NodeBinary;
151
152typedef struct NodeUnary {
153 struct Node *left;
154} NodeUnary;
155
156typedef struct NodeVariable {
157 struct Node *name;
158 struct Node *type;
159 struct Node *val;
160} NodeVariable;
161
162typedef struct NodeLoop {
163 struct Node *cond;
164 struct Node *expr;
165} NodeLoop;
166
167typedef struct NodeIf {
168 struct Node *cond;
169 struct Node *expr_true;
170 struct Node *expr_else;
171} NodeIf;
172
173typedef struct NodeField {
174 struct Node *type;
175 struct Node *val;
176} NodeField;
177
178typedef struct NodeParam {
179 struct Node *name;
180 struct Node *type;
181} NodeParam;
182
183typedef struct NodeMatch {
184 struct Node *expr;
185 struct Node **cases;
186} NodeMatch;
187
188typedef struct NodeCase {
189 struct Node *cond;
190 struct Node *expr;
191} NodeCase;
192
193typedef struct NodeFunction {
194 struct Node *name;
195 struct Node **params;
196 struct Node **ret;
197 struct Node *body;
198} NodeFunction;
199
200typedef struct NodeSymbol {
201 struct Node *next;
202} NodeSymbol;
203
204typedef struct NodeIndex {
205 struct Node *next;
206 struct Node *value;
207} NodeIndex;
208
209typedef struct NodeType {
210 struct Node *next;
211} NodeType;
212
213typedef struct NodeDeref {
214 struct Node *next;
215} NodeDeref;
216
217typedef enum {
218 NODE_ARR_STATIC,
219 NODE_ARR_DYNAMIC,
220 NODE_ARR_SLICE,
221} NodeArrKind;
222
223typedef struct NodeArr {
224 struct Node *next;
225 struct Node *size;
226 NodeArrKind kind;
227} NodeArr;
228
131typedef struct Node { 229typedef struct Node {
132 sz id; 230 sz id;
133 sz line; 231 sz line;
134 sz col; 232 sz col;
233 struct Node *parent;
135 234
136 NodeKind kind; 235 NodeKind kind;
236 NodeLit value;
137 union { 237 union {
138 f64 d; 238 NodeBinary binary;
139 sz i; 239 NodeUnary unary;
140 u64 u; 240 NodeVariable var;
141 Str str; 241 NodeSymbol sym;
142 Str sym; 242 NodeLoop loop;
143 } value; 243 NodeIf ifelse;
144 union { 244 NodeField field;
145 struct { 245 NodeParam param;
146 struct Node *left; 246 NodeMatch match;
147 struct Node *right; 247 NodeCase case_entry;
148 }; 248 NodeFunction func;
149 struct { 249 NodeType t;
150 struct Node *next; 250 NodeIndex idx;
151 struct Node *arr_size; 251 NodeDeref deref;
152 }; 252 NodeArr array;
153 struct {
154 struct Node *var_name;
155 struct Node *var_type;
156 struct Node *var_val;
157 };
158 struct {
159 struct Node *while_cond;
160 struct Node *while_expr;
161 };
162 struct {
163 struct Node *cond_if;
164 struct Node *cond_expr;
165 struct Node *cond_else;
166 };
167 struct {
168 struct Node *field_type;
169 struct Node *field_val;
170 };
171 struct {
172 struct Node *param_name;
173 struct Node *param_type;
174 };
175 struct {
176 struct Node *match_expr;
177 struct Node **match_cases;
178 };
179 struct {
180 struct Node *case_value;
181 struct Node *case_expr;
182 };
183 struct Node **struct_field; 253 struct Node **struct_field;
184 struct Node **elements; 254 struct Node **elements;
185 struct Node **statements; 255 struct Node **statements;
186 struct Node **expressions; 256 struct Node **expressions;
187 struct Node **arguments; 257 struct Node **arguments;
188 struct {
189 struct Node *func_name;
190 struct Node **func_params;
191 struct Node **func_ret;
192 struct Node *func_body;
193 };
194 }; 258 };
195 bool is_ptr;
196 struct Scope *scope;
197 Str type; 259 Str type;
198 Str fun_params; 260 Str type_params;
199 Str fun_return; 261 Str type_returns;
200 Str unique_name; 262 Str unique_name;
201} Node; 263} Node;
202 264
@@ -286,6 +348,7 @@ ParseRule parse_rules[] = {
286 [TOK_BITNOT] = {parse_unary, NULL, PREC_NONE}, 348 [TOK_BITNOT] = {parse_unary, NULL, PREC_NONE},
287 [TOK_BITAND] = {NULL, parse_binary, PREC_BITLOGIC}, 349 [TOK_BITAND] = {NULL, parse_binary, PREC_BITLOGIC},
288 [TOK_BITOR] = {NULL, parse_binary, PREC_BITLOGIC}, 350 [TOK_BITOR] = {NULL, parse_binary, PREC_BITLOGIC},
351 [TOK_BITXOR] = {NULL, parse_binary, PREC_BITLOGIC},
289 [TOK_BITLSHIFT] = {NULL, parse_binary, PREC_BITSHIFT}, 352 [TOK_BITLSHIFT] = {NULL, parse_binary, PREC_BITSHIFT},
290 [TOK_BITRSHIFT] = {NULL, parse_binary, PREC_BITSHIFT}, 353 [TOK_BITRSHIFT] = {NULL, parse_binary, PREC_BITSHIFT},
291 354
@@ -308,6 +371,7 @@ ParseRule parse_rules[] = {
308 [TOK_MATCH] = {parse_keyword, NULL, PREC_NONE}, 371 [TOK_MATCH] = {parse_keyword, NULL, PREC_NONE},
309 [TOK_COND] = {parse_keyword, NULL, PREC_NONE}, 372 [TOK_COND] = {parse_keyword, NULL, PREC_NONE},
310 [TOK_WHILE] = {parse_keyword, NULL, PREC_NONE}, 373 [TOK_WHILE] = {parse_keyword, NULL, PREC_NONE},
374 [TOK_FOR] = {parse_keyword, NULL, PREC_NONE},
311 [TOK_CONTINUE] = {parse_keyword, NULL, PREC_NONE}, 375 [TOK_CONTINUE] = {parse_keyword, NULL, PREC_NONE},
312 [TOK_BREAK] = {parse_keyword, NULL, PREC_NONE}, 376 [TOK_BREAK] = {parse_keyword, NULL, PREC_NONE},
313 [TOK_FUN] = {parse_keyword, NULL, PREC_NONE}, 377 [TOK_FUN] = {parse_keyword, NULL, PREC_NONE},
@@ -318,7 +382,6 @@ ParseRule parse_rules[] = {
318 382
319Node * 383Node *
320node_alloc(Parser *parser, NodeKind kind, Token tok) { 384node_alloc(Parser *parser, NodeKind kind, Token tok) {
321 if (parser->panic) return NULL;
322 static sz id = 0; 385 static sz id = 0;
323 Node *node = arena_calloc((sz)sizeof(Node), parser->storage); 386 Node *node = arena_calloc((sz)sizeof(Node), parser->storage);
324 node->id = id++; 387 node->id = id++;
@@ -388,20 +451,44 @@ parse_block(Parser *parser) {
388 print_token(parser->previous); 451 print_token(parser->previous);
389#endif 452#endif
390 Node *block = node_alloc(parser, NODE_BLOCK, parser->previous); 453 Node *block = node_alloc(parser, NODE_BLOCK, parser->previous);
391 if (!block) return;
392 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { 454 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) {
393 parse_expr(parser, PREC_LOW); 455 parse_expr(parser, PREC_LOW);
394 Node *next = array_pop(parser->nodes); 456 Node *next = array_pop(parser->nodes);
457 next->parent = block;
395 array_push(block->statements, next, parser->storage); 458 array_push(block->statements, next, parser->storage);
396 } 459 }
397 array_push(parser->nodes, block, parser->storage); 460 array_push(parser->nodes, block, parser->storage);
398} 461}
399 462
400void 463void
464parser_sync(Parser *parser) {
465 parser->panic = false;
466 while (parser->current.kind != TOK_EOF) {
467 switch (parser->current.kind) {
468 case TOK_FUN:
469 case TOK_LET:
470 case TOK_SET:
471 case TOK_STRUCT:
472 case TOK_ENUM:
473 case TOK_FOR:
474 case TOK_IF:
475 case TOK_WHILE:
476 case TOK_BREAK:
477 case TOK_CONTINUE:
478 case TOK_COND:
479 case TOK_MATCH:
480 case TOK_CASE:
481 case TOK_RETURN: return;
482 default: break;
483 }
484 parse_advance(parser);
485 }
486}
487
488void
401parse_expr(Parser *parser, ParsePrecedence precedence) { 489parse_expr(Parser *parser, ParsePrecedence precedence) {
402 parse_advance(parser); 490 parse_advance(parser);
403 // TODO: synchronize panic mode on keywords. 491 if (parser->panic) parser_sync(parser);
404 if (parser->panic) return;
405 ParseFn prefix = parse_rules[parser->previous.kind].prefix; 492 ParseFn prefix = parse_rules[parser->previous.kind].prefix;
406 if (prefix == NULL) { 493 if (prefix == NULL) {
407 parse_emit_err(parser, parser->previous, cstr("expected expression")); 494 parse_emit_err(parser, parser->previous, cstr("expected expression"));
@@ -436,8 +523,8 @@ parse_unary(Parser *parser) {
436 case TOK_BITNOT: node = node_alloc(parser, NODE_BITNOT, prev); break; 523 case TOK_BITNOT: node = node_alloc(parser, NODE_BITNOT, prev); break;
437 default: break; // Unreachable. 524 default: break; // Unreachable.
438 } 525 }
439 if (!node) return; 526 node->unary.left = array_pop(parser->nodes);
440 node->left = array_pop(parser->nodes); 527 node->unary.left->parent = node;
441 array_push(parser->nodes, node, parser->storage); 528 array_push(parser->nodes, node, parser->storage);
442} 529}
443 530
@@ -459,7 +546,6 @@ parse_literal(Parser *parser) {
459 case TOK_NIL: node = node_alloc(parser, NODE_NIL, prev); break; 546 case TOK_NIL: node = node_alloc(parser, NODE_NIL, prev); break;
460 default: return; // Unreachable. 547 default: return; // Unreachable.
461 } 548 }
462 if (!node) return;
463 array_push(parser->nodes, node, parser->storage); 549 array_push(parser->nodes, node, parser->storage);
464} 550}
465 551
@@ -471,21 +557,50 @@ parse_type(Parser *parser) {
471 print_token(prev); 557 print_token(prev);
472#endif 558#endif
473 Node *node = node_alloc(parser, NODE_TYPE, prev); 559 Node *node = node_alloc(parser, NODE_TYPE, prev);
474 if (!node) return; 560 Node *child = node;
475 if (parse_match(parser, TOK_AT)) { 561 while (parse_match(parser, TOK_AT) || parse_match(parser, TOK_LSQUARE)) {
476 node->is_ptr = true; 562 switch (parser->previous.kind) {
563 case TOK_AT: {
564 Node *ptr_node = node_alloc(parser, NODE_PTR, parser->previous);
565 ptr_node->parent = child;
566 child->t.next = ptr_node;
567 child = ptr_node;
568 } break;
569 case TOK_LSQUARE: {
570 Node *ptr_node = node_alloc(parser, NODE_ARR, parser->previous);
571 if (parse_match(parser, TOK_NUM_INT)) {
572 // Static array.
573 parse_number(parser);
574 ptr_node->array.size = array_pop(parser->nodes);
575 ptr_node->array.kind = NODE_ARR_STATIC;
576 ptr_node->array.size->parent = ptr_node;
577 parse_consume(parser, TOK_RSQUARE,
578 cstr("unmatched brackets ']' in array type"));
579 } else if (parse_match(parser, TOK_RSQUARE)) {
580 // Slice.
581 ptr_node->array.kind = NODE_ARR_SLICE;
582 } else {
583 // Dynamic array.
584 parse_consume(parser, TOK_DOT, cstr("invalid array type"));
585 parse_consume(parser, TOK_DOT, cstr("invalid array type"));
586 parse_consume(parser, TOK_DOT, cstr("invalid array type"));
587 parse_consume(parser, TOK_RSQUARE,
588 cstr("unmatched brackets ']' in array type"));
589 ptr_node->array.kind = NODE_ARR_DYNAMIC;
590 }
591 ptr_node->parent = child;
592 child->t.next = ptr_node;
593 child = ptr_node;
594 } break;
595 default: {
596 parse_emit_err(parser, prev, cstr("unimplemented"));
597 } break;
598 }
477 } 599 }
478 parse_consume(parser, TOK_SYMBOL, cstr("no type given for struct field")); 600 // TODO: maps
601 // TODO: function pointer syntax: : (T T : R)
602 parse_consume(parser, TOK_SYMBOL, cstr("expected type name"));
479 node->value.sym = parser->previous.val; 603 node->value.sym = parser->previous.val;
480 // Optional array value?
481 if (parse_match(parser, TOK_LSQUARE)) {
482 node->kind = NODE_ARR_TYPE,
483 parse_consume(parser, TOK_NUM_INT, cstr("no array size given"));
484 parse_number(parser);
485 node->arr_size = array_pop(parser->nodes);
486 parse_consume(parser, TOK_RSQUARE,
487 cstr("unmatched brackets ']' in array type"));
488 }
489 array_push(parser->nodes, node, parser->storage); 604 array_push(parser->nodes, node, parser->storage);
490} 605}
491 606
@@ -497,29 +612,31 @@ parse_struct_field(Parser *parser) {
497 print_token(parser->previous); 612 print_token(parser->previous);
498#endif 613#endif
499 Node *field = node_alloc(parser, NODE_FIELD, parser->current); 614 Node *field = node_alloc(parser, NODE_FIELD, parser->current);
500 if (!field) return;
501 parse_consume(parser, TOK_SYMBOL, 615 parse_consume(parser, TOK_SYMBOL,
502 cstr("expected symbol name on struct field")); 616 cstr("expected symbol name on struct field"));
503 field->value.sym = parser->previous.val; 617 field->value.sym = parser->previous.val;
504 parse_consume(parser, TOK_COLON, cstr("expected type in struct field")); 618 parse_consume(parser, TOK_COLON, cstr("expected type in struct field"));
505 if (parse_match(parser, TOK_LCURLY)) { 619 if (parse_match(parser, TOK_LCURLY)) {
506 Node *type = node_alloc(parser, NODE_COMPOUND_TYPE, parser->current); 620 Node *type = node_alloc(parser, NODE_COMPOUND_TYPE, parser->current);
507 if (!type) return; 621 type->parent = field;
508 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { 622 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) {
509 parse_struct_field(parser); 623 parse_struct_field(parser);
510 Node *subfield = array_pop(parser->nodes); 624 Node *subfield = array_pop(parser->nodes);
625 subfield->parent = type;
511 array_push(type->elements, subfield, parser->storage); 626 array_push(type->elements, subfield, parser->storage);
512 } 627 }
513 field->field_type = type; 628 field->field.type = type;
514 } else { 629 } else {
515 parse_type(parser); 630 parse_type(parser);
516 field->field_type = array_pop(parser->nodes); 631 field->field.type = array_pop(parser->nodes);
632 field->field.type->parent = field;
517 } 633 }
518 634
519 // Optional assignment. 635 // Optional assignment.
520 if (parse_match(parser, TOK_ASSIGN)) { 636 if (parse_match(parser, TOK_ASSIGN)) {
521 parse_expr(parser, PREC_LOW); 637 parse_expr(parser, PREC_LOW);
522 field->field_val = array_pop(parser->nodes); 638 field->field.val = array_pop(parser->nodes);
639 field->field.val->parent = field;
523 } 640 }
524 array_push(parser->nodes, field, parser->storage); 641 array_push(parser->nodes, field, parser->storage);
525} 642}
@@ -532,7 +649,6 @@ parse_struct_lit_field(Parser *parser) {
532 print_token(parser->previous); 649 print_token(parser->previous);
533#endif 650#endif
534 Node *field = node_alloc(parser, NODE_FIELD, parser->current); 651 Node *field = node_alloc(parser, NODE_FIELD, parser->current);
535 if (!field) return;
536 parse_consume(parser, TOK_SYMBOL, 652 parse_consume(parser, TOK_SYMBOL,
537 cstr("expected symbol name on struct field")); 653 cstr("expected symbol name on struct field"));
538 field->value.sym = parser->previous.val; 654 field->value.sym = parser->previous.val;
@@ -540,16 +656,18 @@ parse_struct_lit_field(Parser *parser) {
540 cstr("expected field value on struct literal")); 656 cstr("expected field value on struct literal"));
541 if (parse_match(parser, TOK_LCURLY)) { 657 if (parse_match(parser, TOK_LCURLY)) {
542 Node *type = node_alloc(parser, NODE_COMPOUND_TYPE, parser->current); 658 Node *type = node_alloc(parser, NODE_COMPOUND_TYPE, parser->current);
543 if (!type) return; 659 type->parent = field;
544 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { 660 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) {
545 parse_struct_lit_field(parser); 661 parse_struct_lit_field(parser);
546 Node *subfield = array_pop(parser->nodes); 662 Node *subfield = array_pop(parser->nodes);
663 subfield->parent = type;
547 array_push(type->elements, subfield, parser->storage); 664 array_push(type->elements, subfield, parser->storage);
548 } 665 }
549 field->field_val = type; 666 field->field.val = type;
550 } else { 667 } else {
551 parse_expr(parser, PREC_LOW); 668 parse_expr(parser, PREC_LOW);
552 field->field_val = array_pop(parser->nodes); 669 field->field.val = array_pop(parser->nodes);
670 field->field.val->parent = field;
553 } 671 }
554 array_push(parser->nodes, field, parser->storage); 672 array_push(parser->nodes, field, parser->storage);
555} 673}
@@ -566,12 +684,12 @@ parse_keyword(Parser *parser) {
566 switch (prev.kind) { 684 switch (prev.kind) {
567 case TOK_LET: { 685 case TOK_LET: {
568 node = node_alloc(parser, NODE_LET, prev); 686 node = node_alloc(parser, NODE_LET, prev);
569 if (!node) return;
570 parse_consume(parser, TOK_SYMBOL, 687 parse_consume(parser, TOK_SYMBOL,
571 cstr("expected symbol name on let expression")); 688 cstr("expected symbol name on let expression"));
572 parse_symbol(parser); 689 parse_symbol(parser);
573 node->var_name = array_pop(parser->nodes); 690 node->var.name = array_pop(parser->nodes);
574 if (node->var_name->next) { 691 node->var.name->parent = node;
692 if (node->var.name->sym.next) {
575 parse_emit_err(parser, prev, 693 parse_emit_err(parser, prev,
576 cstr("invalid symbol name in let expression")); 694 cstr("invalid symbol name in let expression"));
577 return; 695 return;
@@ -580,16 +698,18 @@ parse_keyword(Parser *parser) {
580 // Optional type declaration. 698 // Optional type declaration.
581 if (parse_match(parser, TOK_COLON)) { 699 if (parse_match(parser, TOK_COLON)) {
582 parse_type(parser); 700 parse_type(parser);
583 node->var_type = array_pop(parser->nodes); 701 node->var.type = array_pop(parser->nodes);
702 node->var.type->parent = node;
584 } 703 }
585 704
586 // Optional assignment. 705 // Optional assignment.
587 if (parse_match(parser, TOK_ASSIGN)) { 706 if (parse_match(parser, TOK_ASSIGN)) {
588 parse_expr(parser, PREC_LOW); 707 parse_expr(parser, PREC_LOW);
589 node->var_val = array_pop(parser->nodes); 708 node->var.val = array_pop(parser->nodes);
709 node->var.val->parent = node;
590 } 710 }
591 711
592 if (node->var_type == NULL && node->var_val == NULL) { 712 if (node->var.type == NULL && node->var.val == NULL) {
593 parse_emit_err(parser, prev, 713 parse_emit_err(parser, prev,
594 cstr("variable declaration must include type or " 714 cstr("variable declaration must include type or "
595 "value information")); 715 "value information"));
@@ -597,19 +717,58 @@ parse_keyword(Parser *parser) {
597 } break; 717 } break;
598 case TOK_SET: { 718 case TOK_SET: {
599 node = node_alloc(parser, NODE_SET, prev); 719 node = node_alloc(parser, NODE_SET, prev);
600 if (!node) return;
601 parse_consume(parser, TOK_SYMBOL, 720 parse_consume(parser, TOK_SYMBOL,
602 cstr("expected symbol name on let expression")); 721 cstr("expected symbol name on set expression"));
603 parse_symbol(parser); 722 parse_symbol(parser);
604 node->var_name = array_pop(parser->nodes); 723 node->var.name = array_pop(parser->nodes);
605 parse_consume(parser, TOK_ASSIGN, 724 node->var.name->parent = node;
606 cstr("expected assignment on set expression")); 725
607 parse_expr(parser, PREC_LOW); 726 if (parse_match(parser, TOK_ADD_ASSIGN) ||
608 node->var_val = array_pop(parser->nodes); 727 parse_match(parser, TOK_ADD_ASSIGN) ||
728 parse_match(parser, TOK_SUB_ASSIGN) ||
729 parse_match(parser, TOK_MUL_ASSIGN) ||
730 parse_match(parser, TOK_DIV_ASSIGN) ||
731 parse_match(parser, TOK_MOD_ASSIGN) ||
732 parse_match(parser, TOK_BITAND_ASSIGN) ||
733 parse_match(parser, TOK_BITOR_ASSIGN) ||
734 parse_match(parser, TOK_BITXOR_ASSIGN) ||
735 parse_match(parser, TOK_BITLSHIFT_ASSIGN) ||
736 parse_match(parser, TOK_BITRSHIFT_ASSIGN)) {
737 NodeKind kind = NODE_ERR;
738 switch (parser->previous.kind) {
739 case TOK_ADD_ASSIGN: kind = NODE_ADD; break;
740 case TOK_SUB_ASSIGN: kind = NODE_SUB; break;
741 case TOK_MUL_ASSIGN: kind = NODE_MUL; break;
742 case TOK_DIV_ASSIGN: kind = NODE_DIV; break;
743 case TOK_MOD_ASSIGN: kind = NODE_MOD; break;
744 case TOK_BITAND_ASSIGN: kind = NODE_BITAND; break;
745 case TOK_BITOR_ASSIGN: kind = NODE_BITOR; break;
746 case TOK_BITXOR_ASSIGN: kind = NODE_BITXOR; break;
747 case TOK_BITLSHIFT_ASSIGN: kind = NODE_BITLSHIFT; break;
748 case TOK_BITRSHIFT_ASSIGN: kind = NODE_BITRSHIFT; break;
749 default: break;
750 }
751 parse_expr(parser, PREC_LOW);
752 Node *value = array_pop(parser->nodes);
753 Node *sym = node_alloc(parser, NODE_SYMBOL, prev);
754 Node *op = node_alloc(parser, kind, prev);
755 op->binary.left = sym;
756 op->binary.right = value;
757 sym->parent = op;
758 value->parent = op;
759 node->var.val = op;
760 node->var.val->parent = node;
761 sym->value = node->var.name->value;
762 sym->kind = node->var.name->kind;
763 } else {
764 parse_consume(parser, TOK_ASSIGN,
765 cstr("expected assignment on set expression"));
766 parse_expr(parser, PREC_LOW);
767 node->var.val = array_pop(parser->nodes);
768 }
609 } break; 769 } break;
610 case TOK_STRUCT: { 770 case TOK_STRUCT: {
611 node = node_alloc(parser, NODE_STRUCT, prev); 771 node = node_alloc(parser, NODE_STRUCT, prev);
612 if (!node) return;
613 parse_consume(parser, TOK_SYMBOL, 772 parse_consume(parser, TOK_SYMBOL,
614 cstr("expected symbol name on struct definition")); 773 cstr("expected symbol name on struct definition"));
615 // Just consume this to avoid conflicts with struct literals. 774 // Just consume this to avoid conflicts with struct literals.
@@ -621,54 +780,53 @@ parse_keyword(Parser *parser) {
621 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { 780 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) {
622 parse_struct_field(parser); 781 parse_struct_field(parser);
623 Node *field = array_pop(parser->nodes); 782 Node *field = array_pop(parser->nodes);
624 783 field->parent = node;
625 array_push(node->struct_field, field, parser->storage); 784 array_push(node->struct_field, field, parser->storage);
626 } 785 }
627 } break; 786 } break;
628 case TOK_IF: { 787 case TOK_IF: {
629 node = node_alloc(parser, NODE_IF, prev); 788 node = node_alloc(parser, NODE_IF, prev);
630 if (!node) return;
631 parse_expr(parser, PREC_LOW); 789 parse_expr(parser, PREC_LOW);
632 node->cond_if = array_pop(parser->nodes); 790 node->ifelse.cond = array_pop(parser->nodes);
791 node->ifelse.cond->parent = node;
633 parse_expr(parser, PREC_LOW); 792 parse_expr(parser, PREC_LOW);
634 node->cond_expr = array_pop(parser->nodes); 793 node->ifelse.expr_true = array_pop(parser->nodes);
794 node->ifelse.expr_true->parent = node;
635 if (parse_match(parser, TOK_ELSE)) { 795 if (parse_match(parser, TOK_ELSE)) {
636 parse_expr(parser, PREC_LOW); 796 parse_expr(parser, PREC_LOW);
637 node->cond_else = array_pop(parser->nodes); 797 node->ifelse.expr_else = array_pop(parser->nodes);
798 node->ifelse.expr_else->parent = node;
638 } 799 }
639 } break; 800 } break;
640 case TOK_MATCH: { 801 case TOK_MATCH: {
641 node = node_alloc(parser, NODE_MATCH, prev); 802 node = node_alloc(parser, NODE_MATCH, prev);
642 if (!node) return;
643 parse_expr(parser, PREC_LOW); 803 parse_expr(parser, PREC_LOW);
644 node->match_expr = array_pop(parser->nodes); 804 node->match.expr = array_pop(parser->nodes);
805 node->match.expr->parent = node;
645 parse_consume(parser, TOK_LCURLY, 806 parse_consume(parser, TOK_LCURLY,
646 cstr("expected block of match cases")); 807 cstr("expected block of match cases"));
647 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { 808 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) {
648 Node *tmp = 809 Node *tmp =
649 node_alloc(parser, NODE_CASE_MATCH, parser->previous); 810 node_alloc(parser, NODE_CASE_MATCH, parser->previous);
650 if (!tmp) return; 811 tmp->parent = node;
651 // Are we on the default case. 812 // Are we on the default case.
652 if (!parse_match(parser, TOK_ELSE)) { 813 if (!parse_match(parser, TOK_ELSE)) {
653 parse_consume(parser, TOK_CASE, 814 parse_consume(parser, TOK_CASE,
654 cstr("expected case statement")); 815 cstr("expected case statement"));
655 parse_expr(parser, PREC_LOW); 816 parse_expr(parser, PREC_LOW);
656 tmp->case_value = array_pop(parser->nodes); 817 tmp->case_entry.cond = array_pop(parser->nodes);
818 tmp->case_entry.cond->parent = tmp;
657 } 819 }
658 parse_consume(parser, TOK_ASSIGN, 820 parse_consume(parser, TOK_ASSIGN,
659 cstr("malformed case statement")); 821 cstr("malformed case statement"));
660 parse_expr(parser, PREC_LOW); 822 parse_expr(parser, PREC_LOW);
661 tmp->case_expr = array_pop(parser->nodes); 823 tmp->case_entry.expr = array_pop(parser->nodes);
662 array_push(node->match_cases, tmp, parser->storage); 824 tmp->case_entry.expr->parent = tmp;
825 array_push(node->match.cases, tmp, parser->storage);
663 } 826 }
664 // TODO: Check that we only have literals on the match case,
665 // this could be done on the analysis step, but also here...
666 // TODO: Check that there are no multiple default or duplicated
667 // cases.
668 } break; 827 } break;
669 case TOK_ENUM: { 828 case TOK_ENUM: {
670 node = node_alloc(parser, NODE_ENUM, prev); 829 node = node_alloc(parser, NODE_ENUM, prev);
671 if (!node) return;
672 parse_consume(parser, TOK_SYMBOL, 830 parse_consume(parser, TOK_SYMBOL,
673 cstr("expected symbol name on enum definition")); 831 cstr("expected symbol name on enum definition"));
674 // Just consume this to avoid conflicts with struct literals. 832 // Just consume this to avoid conflicts with struct literals.
@@ -677,13 +835,14 @@ parse_keyword(Parser *parser) {
677 cstr("expected '{' on enum definition")); 835 cstr("expected '{' on enum definition"));
678 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { 836 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) {
679 Node *field = node_alloc(parser, NODE_FIELD, parser->current); 837 Node *field = node_alloc(parser, NODE_FIELD, parser->current);
680 if (!field) return; 838 field->parent = node;
681 parse_consume(parser, TOK_SYMBOL, 839 parse_consume(parser, TOK_SYMBOL,
682 cstr("expected symbol name on enum definition")); 840 cstr("expected symbol name on enum definition"));
683 field->value.sym = parser->previous.val; 841 field->value.sym = parser->previous.val;
684 if (parse_match(parser, TOK_ASSIGN)) { 842 if (parse_match(parser, TOK_ASSIGN)) {
685 parse_expr(parser, PREC_LOW); 843 parse_expr(parser, PREC_LOW);
686 field->field_val = array_pop(parser->nodes); 844 field->field.val = array_pop(parser->nodes);
845 field->field.val->parent = field;
687 } 846 }
688 array_push(node->struct_field, field, parser->storage); 847 array_push(node->struct_field, field, parser->storage);
689 } 848 }
@@ -693,144 +852,133 @@ parse_keyword(Parser *parser) {
693 } break; 852 } break;
694 case TOK_COND: { 853 case TOK_COND: {
695 node = node_alloc(parser, NODE_COND, prev); 854 node = node_alloc(parser, NODE_COND, prev);
696 if (!node) return;
697 parse_consume(parser, TOK_LCURLY, 855 parse_consume(parser, TOK_LCURLY,
698 cstr("expected '{' on cond expression")); 856 cstr("expected '{' on cond expression"));
699 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { 857 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) {
700 Node *tmp = 858 Node *tmp =
701 node_alloc(parser, NODE_CASE_COND, parser->previous); 859 node_alloc(parser, NODE_CASE_COND, parser->previous);
702 if (!tmp) return; 860 tmp->parent = node;
703 // Are we on the default case. 861 // Are we on the default case.
704 if (!parse_match(parser, TOK_ELSE)) { 862 if (!parse_match(parser, TOK_ELSE)) {
705 parse_expr(parser, PREC_LOW); 863 parse_expr(parser, PREC_LOW);
706 tmp->case_value = array_pop(parser->nodes); 864 tmp->case_entry.cond = array_pop(parser->nodes);
865 tmp->case_entry.cond->parent = tmp;
707 } 866 }
708 parse_consume(parser, TOK_ASSIGN, 867 parse_consume(parser, TOK_ASSIGN,
709 cstr("malformed case statement")); 868 cstr("malformed case statement"));
710 parse_expr(parser, PREC_LOW); 869 parse_expr(parser, PREC_LOW);
711 tmp->case_expr = array_pop(parser->nodes); 870 tmp->case_entry.expr = array_pop(parser->nodes);
712 array_push(node->match_cases, tmp, parser->storage); 871 tmp->case_entry.expr->parent = tmp;
872 array_push(node->match.cases, tmp, parser->storage);
713 } 873 }
714 } break; 874 } break;
715 case TOK_BREAK: { 875 case TOK_BREAK: {
716 node = node_alloc(parser, NODE_BREAK, prev); 876 node = node_alloc(parser, NODE_BREAK, prev);
717 if (!node) return;
718 } break; 877 } break;
719 case TOK_CONTINUE: { 878 case TOK_CONTINUE: {
720 node = node_alloc(parser, NODE_CONTINUE, prev); 879 node = node_alloc(parser, NODE_CONTINUE, prev);
721 if (!node) return; 880 } break;
881 case TOK_FOR: {
882 node = node_alloc(parser, NODE_BLOCK, prev);
883
884 Node *node_while = node_alloc(parser, NODE_WHILE, prev);
885 node_while->parent = node;
886 Node *block = node_alloc(parser, NODE_BLOCK, prev);
887 block->parent = node_while;
888
889 parse_expr(parser, PREC_LOW);
890 Node *pre = array_pop(parser->nodes);
891 pre->parent = node;
892
893 parse_expr(parser, PREC_LOW);
894 Node *cond = array_pop(parser->nodes);
895 cond->parent = node_while;
896
897 parse_expr(parser, PREC_LOW);
898 Node *post = array_pop(parser->nodes);
899 post->parent = block;
900
901 // Body.
902 parse_consume(parser, TOK_LCURLY,
903 cstr("expected '{' on for loop statement"));
904 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) {
905 parse_expr(parser, PREC_LOW);
906 Node *next = array_pop(parser->nodes);
907 next->parent = block;
908 array_push(block->statements, next, parser->storage);
909 }
910 array_push(block->statements, post, parser->storage);
911
912 // Put everything together
913 node_while->loop.cond = cond;
914 node_while->loop.expr = block;
915 array_push(node->statements, pre, parser->storage);
916 array_push(node->statements, node_while, parser->storage);
722 } break; 917 } break;
723 case TOK_WHILE: { 918 case TOK_WHILE: {
724 node = node_alloc(parser, NODE_WHILE, prev); 919 node = node_alloc(parser, NODE_WHILE, prev);
725 if (!node) return;
726 parse_expr(parser, PREC_LOW); 920 parse_expr(parser, PREC_LOW);
727 node->while_cond = array_pop(parser->nodes); 921 node->loop.cond = array_pop(parser->nodes);
922 node->loop.cond->parent = node;
728 parse_expr(parser, PREC_LOW); 923 parse_expr(parser, PREC_LOW);
729 node->while_expr = array_pop(parser->nodes); 924 node->loop.expr = array_pop(parser->nodes);
925 node->loop.expr->parent = node;
730 } break; 926 } break;
731 case TOK_FUN: { 927 case TOK_FUN: {
732 node = node_alloc(parser, NODE_FUN, prev); 928 node = node_alloc(parser, NODE_FUN, prev);
733 if (!node) return;
734 parse_consume(parser, TOK_SYMBOL, cstr("expected function name")); 929 parse_consume(parser, TOK_SYMBOL, cstr("expected function name"));
735 Node *name = node_alloc(parser, NODE_SYMBOL, prev); 930 Node *name = node_alloc(parser, NODE_SYMBOL, prev);
736 if (!name) return; 931 name->parent = node;
737 name->value.sym = parser->previous.val; 932 name->value.sym = parser->previous.val;
738 node->func_name = name; 933 node->func.name = name;
739 parse_consume(parser, TOK_LPAREN, 934 parse_consume(parser, TOK_LPAREN,
740 cstr("expected '(' on function definition")); 935 cstr("expected '(' on function definition"));
741 // Parameters. 936 // Parameters.
742 while (!parse_match(parser, TOK_RPAREN) && !parser->panic) { 937 while (!parse_match(parser, TOK_RPAREN) && !parser->panic) {
743 Node *param = 938 Node *param =
744 node_alloc(parser, NODE_FUN_PARAM, parser->current); 939 node_alloc(parser, NODE_FUN_PARAM, parser->current);
745 if (!param) return; 940 param->parent = node;
941
942 // Name.
746 Node *name = node_alloc(parser, NODE_SYMBOL, prev); 943 Node *name = node_alloc(parser, NODE_SYMBOL, prev);
747 if (!name) return;
748 parse_consume(parser, TOK_SYMBOL, cstr("expected symbol name")); 944 parse_consume(parser, TOK_SYMBOL, cstr("expected symbol name"));
749 name->value.sym = parser->previous.val; 945 name->value.sym = parser->previous.val;
750 param->param_name = name;
751 946
752 Node *type = node_alloc(parser, NODE_TYPE, prev); 947 // Type.
753 if (!type) return;
754 parse_consume(parser, TOK_COLON, cstr("expected param type")); 948 parse_consume(parser, TOK_COLON, cstr("expected param type"));
755 if (parse_match(parser, TOK_AT)) { 949 parse_type(parser);
756 type->is_ptr = true; 950
757 } 951 // Put everything together.
758 parse_consume(parser, TOK_SYMBOL, cstr("expected param type")); 952 param->param.name = name;
759 type->value.sym = parser->previous.val; 953 param->param.type = array_pop(parser->nodes);
760 param->param_type = type; 954 param->param.name->parent = param;
761 if (parse_match(parser, TOK_LSQUARE)) { 955 param->param.type->parent = param;
762 type->kind = NODE_ARR_TYPE, 956 array_push(node->func.params, param, parser->storage);
763 parse_consume(parser, TOK_NUM_INT,
764 cstr("no array size given"));
765 parse_number(parser);
766 type->arr_size = array_pop(parser->nodes);
767 parse_consume(parser, TOK_RSQUARE,
768 cstr("unmatched brackets ']' in array type"));
769 }
770 array_push(node->func_params, param, parser->storage);
771 } 957 }
772 parse_consume(parser, TOK_COLON, cstr("expected param type"));
773 958
774 // Return type(s). 959 // Return type(s).
775 if (!parse_match(parser, TOK_NIL)) { 960 // NOTE: We are setup here for multiple return values, but we are
776 if (parse_match(parser, TOK_LPAREN)) { 961 // currently only considering a single one for simplicity.
777 while (!parse_match(parser, TOK_RPAREN) && !parser->panic) { 962 if (parse_match(parser, TOK_COLON)) {
778 Node *ret = node_alloc(parser, NODE_TYPE, prev); 963 parse_type(parser);
779 if (!ret) return; 964 Node *ret = array_pop(parser->nodes);
780 if (parse_match(parser, TOK_AT)) { 965 ret->parent = node;
781 ret->is_ptr = true; 966 array_push(node->func.ret, ret, parser->storage);
782 }
783 parse_consume(parser, TOK_SYMBOL,
784 cstr("expected type name"));
785 ret->value.sym = parser->previous.val;
786 if (parse_match(parser, TOK_LSQUARE)) {
787 ret->kind = NODE_ARR_TYPE,
788 parse_consume(parser, TOK_NUM_INT,
789 cstr("no array size given"));
790 parse_number(parser);
791 ret->arr_size = array_pop(parser->nodes);
792 parse_consume(parser, TOK_RSQUARE,
793 cstr("unmatched brackets ']' in "
794 "array type"));
795 }
796 array_push(node->func_ret, ret, parser->storage);
797 }
798 } else {
799 Node *ret = node_alloc(parser, NODE_TYPE, prev);
800 if (!ret) return;
801 if (parse_match(parser, TOK_AT)) {
802 ret->is_ptr = true;
803 }
804 parse_consume(parser, TOK_SYMBOL,
805 cstr("expected type name"));
806 ret->value.sym = parser->previous.val;
807 if (parse_match(parser, TOK_LSQUARE)) {
808 ret->kind = NODE_ARR_TYPE,
809 parse_consume(parser, TOK_NUM_INT,
810 cstr("no array size given"));
811 parse_number(parser);
812 ret->arr_size = array_pop(parser->nodes);
813 parse_consume(
814 parser, TOK_RSQUARE,
815 cstr("unmatched brackets ']' in array type"));
816 }
817 array_push(node->func_ret, ret, parser->storage);
818 }
819 } 967 }
820 968
821 // Body. 969 // Body.
822 parse_expr(parser, PREC_LOW); 970 parse_expr(parser, PREC_LOW);
823 node->func_body = array_pop(parser->nodes); 971 node->func.body = array_pop(parser->nodes);
824 } break; 972 } break;
825 case TOK_RETURN: { 973 case TOK_RETURN: {
826 node = node_alloc(parser, NODE_RETURN, prev); 974 node = node_alloc(parser, NODE_RETURN, prev);
827 if (!node) return;
828 parse_consume(parser, TOK_LPAREN, 975 parse_consume(parser, TOK_LPAREN,
829 cstr("expected '(' after return")); 976 cstr("expected '(' after return"));
830 while (!parse_match(parser, TOK_RPAREN) && !parser->panic) { 977 while (!parse_match(parser, TOK_RPAREN) && !parser->panic) {
831 parse_expr(parser, PREC_LOW); 978 parse_expr(parser, PREC_LOW);
832 array_push(node->expressions, array_pop(parser->nodes), 979 Node *val = array_pop(parser->nodes);
833 parser->storage); 980 val->parent = node;
981 array_push(node->expressions, val, parser->storage);
834 } 982 }
835 } break; 983 } break;
836 default: return; // Unreachable. 984 default: return; // Unreachable.
@@ -870,6 +1018,9 @@ parse_binary(Parser *parser) {
870 case TOK_BITOR: { 1018 case TOK_BITOR: {
871 node = node_alloc(parser, NODE_BITOR, prev); 1019 node = node_alloc(parser, NODE_BITOR, prev);
872 } break; 1020 } break;
1021 case TOK_BITXOR: {
1022 node = node_alloc(parser, NODE_BITXOR, prev);
1023 } break;
873 case TOK_BITLSHIFT: { 1024 case TOK_BITLSHIFT: {
874 node = node_alloc(parser, NODE_BITLSHIFT, prev); 1025 node = node_alloc(parser, NODE_BITLSHIFT, prev);
875 } break; 1026 } break;
@@ -881,9 +1032,10 @@ parse_binary(Parser *parser) {
881 return; 1032 return;
882 } 1033 }
883 } 1034 }
884 if (!node) return; 1035 node->binary.right = array_pop(parser->nodes);
885 node->right = array_pop(parser->nodes); 1036 node->binary.left = array_pop(parser->nodes);
886 node->left = array_pop(parser->nodes); 1037 node->binary.right->parent = node;
1038 node->binary.left->parent = node;
887 array_push(parser->nodes, node, parser->storage); 1039 array_push(parser->nodes, node, parser->storage);
888} 1040}
889 1041
@@ -901,22 +1053,18 @@ parse_number(Parser *parser) {
901 if (str_has_prefix(prev.val, cstr("0x")) || 1053 if (str_has_prefix(prev.val, cstr("0x")) ||
902 str_has_prefix(prev.val, cstr("0b"))) { 1054 str_has_prefix(prev.val, cstr("0b"))) {
903 node = node_alloc(parser, NODE_NUM_UINT, prev); 1055 node = node_alloc(parser, NODE_NUM_UINT, prev);
904 if (!node) return;
905 node->value.u = str_to_uint(prev.val); 1056 node->value.u = str_to_uint(prev.val);
906 } else { 1057 } else {
907 node = node_alloc(parser, NODE_NUM_INT, prev); 1058 node = node_alloc(parser, NODE_NUM_INT, prev);
908 if (!node) return;
909 node->value.i = str_to_int(prev.val); 1059 node->value.i = str_to_int(prev.val);
910 } 1060 }
911 } break; 1061 } break;
912 case TOK_NUM_FLOAT: { 1062 case TOK_NUM_FLOAT: {
913 node = node_alloc(parser, NODE_NUM_FLOAT, prev); 1063 node = node_alloc(parser, NODE_NUM_FLOAT, prev);
914 if (!node) return;
915 node->value.d = str_to_float(prev.val); 1064 node->value.d = str_to_float(prev.val);
916 } break; 1065 } break;
917 case TOK_CHAR: { 1066 case TOK_CHAR: {
918 node = node_alloc(parser, NODE_NUM_INT, prev); 1067 node = node_alloc(parser, NODE_NUM_INT, prev);
919 if (!node) return;
920 node->value.i = prev.val.mem[1]; 1068 node->value.i = prev.val.mem[1];
921 } break; 1069 } break;
922 default: break; 1070 default: break;
@@ -933,7 +1081,6 @@ parse_string(Parser *parser) {
933 print_token(prev); 1081 print_token(prev);
934#endif 1082#endif
935 Node *node = node_alloc(parser, NODE_STRING, prev); 1083 Node *node = node_alloc(parser, NODE_STRING, prev);
936 if (!node) return;
937 node->value.str = str_remove_prefix(prev.val, cstr("\"")); 1084 node->value.str = str_remove_prefix(prev.val, cstr("\""));
938 node->value.str = str_remove_suffix(node->value.str, cstr("\"")); 1085 node->value.str = str_remove_suffix(node->value.str, cstr("\""));
939 array_push(parser->nodes, node, parser->storage); 1086 array_push(parser->nodes, node, parser->storage);
@@ -947,25 +1094,27 @@ parse_symbol(Parser *parser) {
947 print("parsing symbol "); 1094 print("parsing symbol ");
948 print_token(prev); 1095 print_token(prev);
949#endif 1096#endif
1097 // Dereference operators.
950 if (prev.kind == TOK_AT) { 1098 if (prev.kind == TOK_AT) {
1099 Node *node = node_alloc(parser, NODE_PTR, parser->previous);
951 parse_consume(parser, TOK_SYMBOL, 1100 parse_consume(parser, TOK_SYMBOL,
952 cstr("expected symbol after '.' operator")); 1101 cstr("expected symbol after '@' operator"));
953 parse_symbol(parser); 1102 parse_symbol(parser);
954 Node *node = array_pop(parser->nodes); 1103 node->t.next = array_pop(parser->nodes);
955 if (node) { 1104 node->t.next->parent = node;
956 node->is_ptr = true; 1105 array_push(parser->nodes, node, parser->storage);
957 array_push(parser->nodes, node, parser->storage);
958 }
959 return; 1106 return;
960 } 1107 }
1108
961 Node *node = node_alloc(parser, NODE_SYMBOL, prev); 1109 Node *node = node_alloc(parser, NODE_SYMBOL, prev);
962 if (!node) return; 1110 node->value.sym = prev.val;
963 if (parse_match(parser, TOK_DOT)) { 1111 if (parse_match(parser, TOK_DOT)) {
964 // Symbol chain. 1112 // Symbol chain.
965 parse_consume(parser, TOK_SYMBOL, 1113 parse_consume(parser, TOK_SYMBOL,
966 cstr("expected symbol after '.' operator")); 1114 cstr("expected symbol after '.' operator"));
967 parse_symbol(parser); 1115 parse_symbol(parser);
968 node->next = array_pop(parser->nodes); 1116 node->sym.next = array_pop(parser->nodes);
1117 node->sym.next->parent = node;
969 } else if (parser->current.kind == TOK_COLON && 1118 } else if (parser->current.kind == TOK_COLON &&
970 parse_peek(parser) == TOK_LCURLY) { 1119 parse_peek(parser) == TOK_LCURLY) {
971 parse_advance(parser); 1120 parse_advance(parser);
@@ -976,37 +1125,62 @@ parse_symbol(Parser *parser) {
976 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { 1125 while (!parse_match(parser, TOK_RCURLY) && !parser->panic) {
977 parse_struct_lit_field(parser); 1126 parse_struct_lit_field(parser);
978 Node *field = array_pop(parser->nodes); 1127 Node *field = array_pop(parser->nodes);
1128 field->parent = node;
979 array_push(node->elements, field, parser->storage); 1129 array_push(node->elements, field, parser->storage);
980 } 1130 }
981 } else if (parse_match(parser, TOK_LSQUARE)) { 1131 } else if (parse_match(parser, TOK_LSQUARE)) {
982 node->kind = NODE_SYMBOL_IDX; 1132 Node *index = node_alloc(parser, NODE_INDEX, prev);
1133 Node *start = index;
983 parse_expr(parser, PREC_LOW); 1134 parse_expr(parser, PREC_LOW);
984 node->arr_size = array_pop(parser->nodes);
985 parse_consume(parser, TOK_RSQUARE, 1135 parse_consume(parser, TOK_RSQUARE,
986 cstr("unmatched brackets ']' in array type")); 1136 cstr("unmatched brackets ']' in array type"));
987 if (parse_match(parser, TOK_DOT)) { 1137 index->idx.value = array_pop(parser->nodes);
988 // Symbol chain. 1138 index->idx.value->parent = start;
989 parse_consume(parser, TOK_SYMBOL, 1139 while (parse_match(parser, TOK_LSQUARE)) {
990 cstr("expected symbol after '.' operator")); 1140 Node *next = node_alloc(parser, NODE_INDEX, prev);
991 parse_symbol(parser); 1141 parse_expr(parser, PREC_LOW);
992 node->next = array_pop(parser->nodes); 1142 parse_consume(parser, TOK_RSQUARE,
1143 cstr("unmatched brackets ']' in array type"));
1144 next->idx.value = array_pop(parser->nodes);
1145 next->parent = index;
1146 index->idx.next = next;
1147 index = next;
993 } 1148 }
1149
1150 index->idx.next = node;
1151 index->idx.next->parent = index;
1152 array_push(parser->nodes, start, parser->storage);
1153 return;
994 } else if (parse_match(parser, TOK_LPAREN)) { 1154 } else if (parse_match(parser, TOK_LPAREN)) {
995 node->kind = NODE_FUNCALL; 1155 node->kind = NODE_FUNCALL;
996 while (!parse_match(parser, TOK_RPAREN) && !parser->panic) { 1156 while (!parse_match(parser, TOK_RPAREN) && !parser->panic) {
997 parse_expr(parser, PREC_LOW); 1157 parse_expr(parser, PREC_LOW);
998 array_push(node->arguments, array_pop(parser->nodes), 1158 Node *arg = array_pop(parser->nodes);
999 parser->storage); 1159 arg->parent = node;
1160 array_push(node->arguments, arg, parser->storage);
1000 } 1161 }
1001 if (parse_match(parser, TOK_DOT)) { 1162 if (parse_match(parser, TOK_DOT)) {
1002 // Symbol chain. 1163 // Symbol chain.
1003 parse_consume(parser, TOK_SYMBOL, 1164 parse_consume(parser, TOK_SYMBOL,
1004 cstr("expected symbol after '.' operator")); 1165 cstr("expected symbol after '.' operator"));
1005 parse_symbol(parser); 1166 parse_symbol(parser);
1006 node->next = array_pop(parser->nodes); 1167 node->sym.next = array_pop(parser->nodes);
1168 node->sym.next->parent = node;
1169 }
1170 } else if (parse_match(parser, TOK_AT)) {
1171 Node *deref = node_alloc(parser, NODE_DEREF, prev);
1172 Node *start = deref;
1173 while (parse_match(parser, TOK_AT)) {
1174 Node *next = node_alloc(parser, NODE_DEREF, prev);
1175 next->parent = deref;
1176 deref->deref.next = next;
1177 deref = next;
1007 } 1178 }
1179 deref->deref.next = node;
1180 deref->deref.next->parent = deref;
1181 array_push(parser->nodes, start, parser->storage);
1182 return;
1008 } 1183 }
1009 node->value.sym = prev.val;
1010 array_push(parser->nodes, node, parser->storage); 1184 array_push(parser->nodes, node, parser->storage);
1011} 1185}
1012 1186
@@ -1032,62 +1206,71 @@ graph_node(Node *node) {
1032 case NODE_NUM_UINT: print("| Value: %x", node->value.u); break; 1206 case NODE_NUM_UINT: print("| Value: %x", node->value.u); break;
1033 case NODE_NUM_FLOAT: print("| Value: %f{2}", node->value.d); break; 1207 case NODE_NUM_FLOAT: print("| Value: %f{2}", node->value.d); break;
1034 case NODE_STRING: print("| Value: %s", node->value.str); break; 1208 case NODE_STRING: print("| Value: %s", node->value.str); break;
1035 case NODE_SYMBOL_IDX:
1036 case NODE_STRUCT: 1209 case NODE_STRUCT:
1037 case NODE_STRUCT_LIT: print("| Name: %s", node->value.sym); break; 1210 case NODE_STRUCT_LIT: print("| Name: %s", node->value.sym); break;
1038 case NODE_SYMBOL: 1211 case NODE_SYMBOL:
1039 case NODE_FUNCALL: 1212 case NODE_FUNCALL:
1040 case NODE_ARR_TYPE:
1041 case NODE_FIELD: 1213 case NODE_FIELD:
1042 case NODE_TYPE: { 1214 case NODE_TYPE: {
1043 if (node->is_ptr) { 1215 print("| Name: %s", node->value.sym);
1044 print("| Name: @%s", node->value.sym); 1216 } break;
1045 } else { 1217 case NODE_ARR: {
1046 print("| Name: %s", node->value.sym); 1218 if (node->array.kind == NODE_ARR_STATIC) {
1219 print("| Static [%d]", node->array.size->value.i);
1220 } else if (node->array.kind == NODE_ARR_SLICE) {
1221 print("| Slice []");
1222 } else if (node->array.kind == NODE_ARR_DYNAMIC) {
1223 print("| Dynamic [...]");
1047 } 1224 }
1048 } break; 1225 } break;
1049 default: break; 1226 default: break;
1050 } 1227 }
1228 if (node->unique_name.size > 0) {
1229 print("| Unique Name: %s", node->unique_name);
1230 }
1051 if (node->type.size > 0) { 1231 if (node->type.size > 0) {
1052 print("| Type: %s", node->type); 1232 print("| Type: %s", node->type);
1053 } 1233 }
1054 if (node->fun_params.size > 0) { 1234 if (node->type_params.size > 0) {
1055 print("| Params: %s", node->fun_params); 1235 print("| Params: %s", node->type_params);
1056 } 1236 }
1057 if (node->fun_return.size > 0) { 1237 if (node->type_returns.size > 0) {
1058 print("| Return: %s", node->fun_return); 1238 print("| Return: %s", node->type_returns);
1059 } 1239 }
1060 println("\"];"); 1240 println("\"];");
1061 1241
1242 if (node->parent) {
1243 println("%d:w->%d:e;", node->id, node->parent->id);
1244 }
1062 switch (node->kind) { 1245 switch (node->kind) {
1063 case NODE_FUN: { 1246 case NODE_FUN: {
1064 for (sz i = 0; i < array_size(node->func_params); i++) { 1247 for (sz i = 0; i < array_size(node->func.params); i++) {
1065 Node *next = node->func_params[i]; 1248 Node *next = node->func.params[i];
1066 println("%d:e->%d:w;", node->id, next->id); 1249 println("%d:e->%d:w;", node->id, next->id);
1067 graph_node(next); 1250 graph_node(next);
1068 } 1251 }
1069 for (sz i = 0; i < array_size(node->func_ret); i++) { 1252 for (sz i = 0; i < array_size(node->func.ret); i++) {
1070 Node *next = node->func_ret[i]; 1253 Node *next = node->func.ret[i];
1071 println("%d:e->%d:w;", node->id, next->id); 1254 println("%d:e->%d:w;", node->id, next->id);
1072 graph_node(next); 1255 graph_node(next);
1073 } 1256 }
1074 if (node->func_name) { 1257 if (node->func.name) {
1075 println("%d:e->%d:w;", node->id, node->func_name->id); 1258 println("%d:e->%d:w;", node->id, node->func.name->id);
1076 graph_node(node->func_name); 1259 graph_node(node->func.name);
1077 } 1260 }
1078 if (node->func_body) { 1261 if (node->func.body) {
1079 println("%d:e->%d:w;", node->id, node->func_body->id); 1262 println("%d:e->%d:w;", node->id, node->func.body->id);
1080 graph_node(node->func_body); 1263 graph_node(node->func.body);
1081 } 1264 }
1082 } break; 1265 } break;
1083 case NODE_COND: 1266 case NODE_COND:
1084 case NODE_MATCH: { 1267 case NODE_MATCH: {
1085 if (node->match_expr) { 1268 if (node->match.expr) {
1086 println("%d:e->%d:w;", node->id, node->match_expr->id); 1269 println("%d:e->%d:w;", node->id, node->match.expr->id);
1087 graph_node(node->match_expr); 1270 graph_node(node->match.expr);
1088 } 1271 }
1089 for (sz i = 0; i < array_size(node->match_cases); i++) { 1272 for (sz i = 0; i < array_size(node->match.cases); i++) {
1090 Node *next = node->match_cases[i]; 1273 Node *next = node->match.cases[i];
1091 println("%d:e->%d:w;", node->id, next->id); 1274 println("%d:e->%d:w;", node->id, next->id);
1092 graph_node(next); 1275 graph_node(next);
1093 } 1276 }
@@ -1112,43 +1295,43 @@ graph_node(Node *node) {
1112 } 1295 }
1113 } break; 1296 } break;
1114 case NODE_IF: { 1297 case NODE_IF: {
1115 if (node->cond_if) { 1298 if (node->ifelse.cond) {
1116 println("%d:e->%d:w;", node->id, node->cond_if->id); 1299 println("%d:e->%d:w;", node->id, node->ifelse.cond->id);
1117 graph_node(node->cond_if); 1300 graph_node(node->ifelse.cond);
1118 } 1301 }
1119 if (node->cond_expr) { 1302 if (node->ifelse.expr_true) {
1120 println("%d:e->%d:w;", node->id, node->cond_expr->id); 1303 println("%d:e->%d:w;", node->id, node->ifelse.expr_true->id);
1121 graph_node(node->cond_expr); 1304 graph_node(node->ifelse.expr_true);
1122 } 1305 }
1123 if (node->cond_else) { 1306 if (node->ifelse.expr_else) {
1124 println("%d:e->%d:w;", node->id, node->cond_else->id); 1307 println("%d:e->%d:w;", node->id, node->ifelse.expr_else->id);
1125 graph_node(node->cond_else); 1308 graph_node(node->ifelse.expr_else);
1126 } 1309 }
1127 } break; 1310 } break;
1128 case NODE_FIELD: 1311 case NODE_FIELD:
1129 case NODE_SET: 1312 case NODE_SET:
1130 case NODE_LET: { 1313 case NODE_LET: {
1131 if (node->var_name) { 1314 if (node->var.name) {
1132 println("%d:e->%d:w;", node->id, node->var_name->id); 1315 println("%d:e->%d:w;", node->id, node->var.name->id);
1133 graph_node(node->var_name); 1316 graph_node(node->var.name);
1134 } 1317 }
1135 if (node->var_type) { 1318 if (node->var.type) {
1136 println("%d:e->%d:w;", node->id, node->var_type->id); 1319 println("%d:e->%d:w;", node->id, node->var.type->id);
1137 graph_node(node->var_type); 1320 graph_node(node->var.type);
1138 } 1321 }
1139 if (node->var_val) { 1322 if (node->var.val) {
1140 println("%d:e->%d:w;", node->id, node->var_val->id); 1323 println("%d:e->%d:w;", node->id, node->var.val->id);
1141 graph_node(node->var_val); 1324 graph_node(node->var.val);
1142 } 1325 }
1143 } break; 1326 } break;
1144 default: { 1327 default: {
1145 if (node->left) { 1328 if (node->binary.left) {
1146 println("%d:e->%d:w;", node->id, node->left->id); 1329 println("%d:e->%d:w;", node->id, node->binary.left->id);
1147 graph_node(node->left); 1330 graph_node(node->binary.left);
1148 } 1331 }
1149 if (node->right) { 1332 if (node->binary.right) {
1150 println("%d:e->%d:w;", node->id, node->right->id); 1333 println("%d:e->%d:w;", node->id, node->binary.right->id);
1151 graph_node(node->right); 1334 graph_node(node->binary.right);
1152 } 1335 }
1153 } break; 1336 } break;
1154 } 1337 }
diff --git a/src/semantic.c b/src/semantic.c
index a0231d5..2e2735f 100644
--- a/src/semantic.c
+++ b/src/semantic.c
@@ -39,6 +39,10 @@ typedef struct Fun {
39 Str name; 39 Str name;
40 Str param_type; 40 Str param_type;
41 Str return_type; 41 Str return_type;
42 Str *param_types;
43 Str *return_types;
44 sz param_arity;
45 sz return_arity;
42} Fun; 46} Fun;
43 47
44typedef struct Enum { 48typedef struct Enum {
@@ -62,6 +66,7 @@ typedef struct Scope {
62 sz depth; 66 sz depth;
63 Str name; 67 Str name;
64 SymbolMap *symbols; 68 SymbolMap *symbols;
69 StrSet *types;
65 FunMap *funcs; 70 FunMap *funcs;
66 EnumMap *enums; 71 EnumMap *enums;
67 StructMap *structs; 72 StructMap *structs;
@@ -75,6 +80,7 @@ typedef struct Analyzer {
75 Scope **scopes; 80 Scope **scopes;
76 StrSet *numeric_types; 81 StrSet *numeric_types;
77 StrSet *integer_types; 82 StrSet *integer_types;
83 StrSet *float_types;
78 bool err; 84 bool err;
79} Analyzer; 85} Analyzer;
80 86
@@ -82,16 +88,19 @@ Scope *
82typescope_alloc(Analyzer *a, Scope *parent) { 88typescope_alloc(Analyzer *a, Scope *parent) {
83 Scope *scope = arena_calloc(sizeof(Scope), a->storage); 89 Scope *scope = arena_calloc(sizeof(Scope), a->storage);
84 scope->parent = parent; 90 scope->parent = parent;
91 if (parent != NULL) {
92 scope->name = parent->name;
93 }
85 scope->id = a->typescope_gen++; 94 scope->id = a->typescope_gen++;
86 scope->depth = parent == NULL ? 0 : parent->depth + 1; 95 scope->depth = parent == NULL ? 0 : parent->depth + 1;
87 array_push(a->scopes, scope, a->storage); 96 array_push(a->scopes, scope, a->storage);
88 return scope; 97 return scope;
89} 98}
90 99
91SymbolMap * 100StrSet *
92find_type(Scope *scope, Str type) { 101find_type(Scope *scope, Str type) {
93 while (scope != NULL) { 102 while (scope != NULL) {
94 SymbolMap *val = symmap_lookup(&scope->symbols, type); 103 StrSet *val = strset_lookup(&scope->types, type);
95 if (val != NULL) { 104 if (val != NULL) {
96 return val; 105 return val;
97 } 106 }
@@ -276,7 +285,7 @@ Str type_inference(Analyzer *a, Node *node, Scope *scope);
276 285
277void 286void
278typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) { 287typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
279 if (node->field_type->kind == NODE_COMPOUND_TYPE) { 288 if (node->field.type->kind == NODE_COMPOUND_TYPE) {
280 Str field_name = str_concat(symbol, cstr("."), a->storage); 289 Str field_name = str_concat(symbol, cstr("."), a->storage);
281 field_name = str_concat(field_name, node->value.str, a->storage); 290 field_name = str_concat(field_name, node->value.str, a->storage);
282 if (structmap_lookup(&scope->structs, field_name)) { 291 if (structmap_lookup(&scope->structs, field_name)) {
@@ -285,8 +294,8 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
285 a->err = true; 294 a->err = true;
286 } 295 }
287 Str type = cstr("\\{ "); 296 Str type = cstr("\\{ ");
288 for (sz i = 0; i < array_size(node->field_type->elements); i++) { 297 for (sz i = 0; i < array_size(node->field.type->elements); i++) {
289 Node *field = node->field_type->elements[i]; 298 Node *field = node->field.type->elements[i];
290 typecheck_field(a, field, scope, field_name); 299 typecheck_field(a, field, scope, field_name);
291 type = str_concat(type, field->type, a->storage); 300 type = str_concat(type, field->type, a->storage);
292 type = str_concat(type, cstr(" "), a->storage); 301 type = str_concat(type, cstr(" "), a->storage);
@@ -296,25 +305,19 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
296 } else { 305 } else {
297 Str field_name = str_concat(symbol, cstr("."), a->storage); 306 Str field_name = str_concat(symbol, cstr("."), a->storage);
298 field_name = str_concat(field_name, node->value.str, a->storage); 307 field_name = str_concat(field_name, node->value.str, a->storage);
299 Str field_type = node->field_type->value.str; 308 Str field_type = node->field.type->value.str;
300 if (!find_type(scope, field_type)) { 309 if (!find_type(scope, field_type)) {
301 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name, 310 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name,
302 node->field_type->line, node->field_type->col, field_type); 311 node->field.type->line, node->field.type->col, field_type);
303 a->err = true; 312 a->err = true;
304 } 313 }
305 if (node->field_type->is_ptr) {
306 field_type = str_concat(cstr("@"), field_type, a->storage);
307 }
308 if (node->field_type->kind == NODE_ARR_TYPE) {
309 field_type = str_concat(cstr("@"), field_type, a->storage);
310 }
311 if (structmap_lookup(&scope->structs, field_name)) { 314 if (structmap_lookup(&scope->structs, field_name)) {
312 eprintln("%s:%d:%d: error: struct field '%s' already exists", 315 eprintln("%s:%d:%d: error: struct field '%s' already exists",
313 a->file_name, node->line, node->col, field_name); 316 a->file_name, node->line, node->col, field_name);
314 a->err = true; 317 a->err = true;
315 } 318 }
316 if (node->field_val) { 319 if (node->field.val) {
317 Str type = type_inference(a, node->field_val, scope); 320 Str type = type_inference(a, node->field.val, scope);
318 if (!str_eq(type, field_type)) { 321 if (!str_eq(type, field_type)) {
319 eprintln( 322 eprintln(
320 "%s:%d:%d: error: mismatched types in struct " 323 "%s:%d:%d: error: mismatched types in struct "
@@ -329,7 +332,7 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
329 (Struct){ 332 (Struct){
330 .name = field_name, 333 .name = field_name,
331 .type = field_type, 334 .type = field_type,
332 .val = node->field_val, 335 .val = node->field.val,
333 }, 336 },
334 a->storage); 337 a->storage);
335 symmap_insert(&scope->symbols, field_name, 338 symmap_insert(&scope->symbols, field_name,
@@ -341,10 +344,10 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
341 344
342void 345void
343typecheck_lit_field(Analyzer *a, Node *node, Scope *scope, Str symbol) { 346typecheck_lit_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
344 if (node->field_val->kind == NODE_COMPOUND_TYPE) { 347 if (node->field.val->kind == NODE_COMPOUND_TYPE) {
345 Str type = cstr("\\{ "); 348 Str type = cstr("\\{ ");
346 for (sz i = 0; i < array_size(node->field_val->elements); i++) { 349 for (sz i = 0; i < array_size(node->field.val->elements); i++) {
347 Node *field = node->field_val->elements[i]; 350 Node *field = node->field.val->elements[i];
348 Str field_name = str_concat(symbol, cstr("."), a->storage); 351 Str field_name = str_concat(symbol, cstr("."), a->storage);
349 field_name = str_concat(field_name, field->value.str, a->storage); 352 field_name = str_concat(field_name, field->value.str, a->storage);
350 typecheck_lit_field(a, field, scope, field_name); 353 typecheck_lit_field(a, field, scope, field_name);
@@ -362,7 +365,7 @@ typecheck_lit_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
362 return; 365 return;
363 } 366 }
364 Str field_type = s->val.type; 367 Str field_type = s->val.type;
365 Str type = type_inference(a, node->field_val, scope); 368 Str type = type_inference(a, node->field.val, scope);
366 if (!str_eq(type, field_type)) { 369 if (!str_eq(type, field_type)) {
367 eprintln( 370 eprintln(
368 "%s:%d:%d: error: mismatched types in struct " 371 "%s:%d:%d: error: mismatched types in struct "
@@ -384,17 +387,18 @@ typecheck_returns(Analyzer *a, Node *node, Str expected) {
384 switch (node->kind) { 387 switch (node->kind) {
385 case NODE_COND: 388 case NODE_COND:
386 case NODE_MATCH: { 389 case NODE_MATCH: {
387 for (sz i = 0; i < array_size(node->match_cases); i++) { 390 for (sz i = 0; i < array_size(node->match.cases); i++) {
388 Node *next = node->match_cases[i]; 391 Node *next = node->match.cases[i];
389 typecheck_returns(a, next, expected); 392 typecheck_returns(a, next, expected);
390 } 393 }
391 } break; 394 } break;
392 case NODE_RETURN: { 395 case NODE_RETURN: {
393 bool err = !str_eq(node->type, expected); 396 Str type = str_remove_prefix(node->type, cstr("ret:"));
397 bool err = !str_eq(type, expected);
394 if (err) { 398 if (err) {
395 eprintln( 399 eprintln(
396 "%s:%d:%d: error: mismatched return type %s, expected %s", 400 "%s:%d:%d: error: mismatched return type %s, expected %s",
397 a->file_name, node->line, node->col, node->type, expected); 401 a->file_name, node->line, node->col, type, expected);
398 a->err = true; 402 a->err = true;
399 } 403 }
400 } break; 404 } break;
@@ -405,17 +409,17 @@ typecheck_returns(Analyzer *a, Node *node, Str expected) {
405 } 409 }
406 } break; 410 } break;
407 case NODE_IF: { 411 case NODE_IF: {
408 if (node->cond_expr) { 412 if (node->ifelse.expr_true) {
409 typecheck_returns(a, node->cond_expr, expected); 413 typecheck_returns(a, node->ifelse.expr_true, expected);
410 } 414 }
411 if (node->cond_else) { 415 if (node->ifelse.expr_else) {
412 typecheck_returns(a, node->cond_else, expected); 416 typecheck_returns(a, node->ifelse.expr_else, expected);
413 } 417 }
414 } break; 418 } break;
415 case NODE_SET: 419 case NODE_SET:
416 case NODE_LET: { 420 case NODE_LET: {
417 if (node->var_val) { 421 if (node->var.val) {
418 typecheck_returns(a, node->var_val, expected); 422 typecheck_returns(a, node->var.val, expected);
419 } 423 }
420 } break; 424 } break;
421 case NODE_ADD: 425 case NODE_ADD:
@@ -435,13 +439,14 @@ typecheck_returns(Analyzer *a, Node *node, Str expected) {
435 case NODE_BITNOT: 439 case NODE_BITNOT:
436 case NODE_BITAND: 440 case NODE_BITAND:
437 case NODE_BITOR: 441 case NODE_BITOR:
442 case NODE_BITXOR:
438 case NODE_BITLSHIFT: 443 case NODE_BITLSHIFT:
439 case NODE_BITRSHIFT: { 444 case NODE_BITRSHIFT: {
440 if (node->left) { 445 if (node->binary.left) {
441 typecheck_returns(a, node->left, expected); 446 typecheck_returns(a, node->binary.left, expected);
442 } 447 }
443 if (node->right) { 448 if (node->binary.right) {
444 typecheck_returns(a, node->right, expected); 449 typecheck_returns(a, node->binary.right, expected);
445 } 450 }
446 } break; 451 } break;
447 default: break; 452 default: break;
@@ -452,66 +457,65 @@ Str
452type_inference(Analyzer *a, Node *node, Scope *scope) { 457type_inference(Analyzer *a, Node *node, Scope *scope) {
453 assert(a); 458 assert(a);
454 assert(scope); 459 assert(scope);
455 if (!node) { 460 if (!node || a->err) {
456 return cstr(""); 461 return cstr("");
457 } 462 }
458 // NOTE: For now we are not going to do implicit numeric conversions.
459 switch (node->kind) { 463 switch (node->kind) {
460 case NODE_LET: { 464 case NODE_LET: {
461 node->type = cstr("nil"); 465 node->type = cstr("nil");
462 Str symbol = node->var_name->value.str; 466 Str symbol = node->var.name->value.str;
463 if (symmap_lookup(&scope->symbols, symbol)) { 467 if (symmap_lookup(&scope->symbols, symbol)) {
464 eprintln( 468 eprintln(
465 "%s:%d:%d: error: symbol '%s' already exists in current " 469 "%s:%d:%d: error: symbol '%s' already exists in current "
466 "scope ", 470 "scope ",
467 a->file_name, node->var_name->line, node->var_name->col, 471 a->file_name, node->var.name->line, node->var.name->col,
468 symbol); 472 symbol);
469 a->err = true; 473 a->err = true;
470 return cstr(""); 474 return cstr("");
471 } 475 }
472 if (node->var_type) { 476 if (node->var.type) {
473 Str type_name = node->var_type->value.str; 477 Str type_name = type_inference(a, node->var.type, scope);
474 SymbolMap *type = find_type(scope, type_name); 478 if (node->var.val) {
475 if (type == NULL) { 479 Str type = type_inference(a, node->var.val, scope);
476 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name,
477 node->var_type->line, node->var_type->col,
478 type_name);
479 a->err = true;
480 return cstr("");
481 }
482 if (node->var_type->is_ptr) {
483 type_name = str_concat(cstr("@"), type_name, a->storage);
484 }
485 if (node->var_type->kind == NODE_ARR_TYPE) {
486 type_name = str_concat(cstr("@"), type_name, a->storage);
487 // TODO: typecheck size
488 // TODO: register array in scope
489 }
490 if (node->var_val) {
491 Str type = type_inference(a, node->var_val, scope);
492 if (!type.size) { 480 if (!type.size) {
493 eprintln( 481 eprintln(
494 "%s:%d:%d: error: can't bind `nil` to variable " 482 "%s:%d:%d: error: can't bind `nil` to variable "
495 "'%s'", 483 "'%s'",
496 a->file_name, node->var_type->line, 484 a->file_name, node->var.type->line,
497 node->var_type->col, symbol); 485 node->var.type->col, symbol);
498 a->err = true; 486 a->err = true;
499 return cstr(""); 487 return cstr("");
500 } 488 }
501 // TODO: Consider compatible types.
502 if (!str_eq(type, type_name)) { 489 if (!str_eq(type, type_name)) {
503 // Special case, enums can be treated as ints. 490 // TODO: ensure that we only assign compatible arrays,
504 FindEnumResult res = find_enum(scope, type_name); 491 // for pointers this was ok but not anymore.
505 if (!(res.map && str_eq(type, cstr("int")))) { 492 Str type_a = type;
506 eprintln( 493 Str type_b = type_name;
507 "%s:%d:%d: error: type mismatch, trying to " 494 if (str_has_prefix(type_a, cstr("@")) ||
508 "assing " 495 str_has_prefix(type_a, cstr("["))) {
509 "%s" 496 type_a = cstr("Ptr");
510 " to a variable of type %s", 497 }
511 a->file_name, node->var_type->line, 498 if (str_has_prefix(type_b, cstr("@")) ||
512 node->var_type->col, type, type_name); 499 str_has_prefix(type_b, cstr("["))) {
513 a->err = true; 500 type_b = cstr("Ptr");
514 return cstr(""); 501 }
502 if (!(strset_lookup(&a->integer_types, type_a) &&
503 strset_lookup(&a->integer_types, type_b)) ||
504 !(strset_lookup(&a->numeric_types, type_a) &&
505 strset_lookup(&a->numeric_types, type_b))) {
506 // Special case, enums can be treated as ints.
507 FindEnumResult res = find_enum(scope, type_name);
508 if (!(res.map && str_eq(type, cstr("Int")))) {
509 eprintln(
510 "%s:%d:%d: error: type mismatch, trying to "
511 "assing "
512 "%s"
513 " to a variable of type %s",
514 a->file_name, node->var.type->line,
515 node->var.type->col, type, type_name);
516 a->err = true;
517 return cstr("");
518 }
515 } 519 }
516 } 520 }
517 } 521 }
@@ -521,7 +525,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
521 .kind = SYM_VAR, 525 .kind = SYM_VAR,
522 }, 526 },
523 a->storage); 527 a->storage);
524 node->var_name->type = type_name; 528 node->var.name->type = type_name;
525 symbol = str_concat(cstr("."), symbol, a->storage); 529 symbol = str_concat(cstr("."), symbol, a->storage);
526 symbol = str_concat(symbol, str_from_int(scope->id, a->storage), 530 symbol = str_concat(symbol, str_from_int(scope->id, a->storage),
527 a->storage); 531 a->storage);
@@ -530,13 +534,19 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
530 } 534 }
531 535
532 // We don't know the type for this symbol, perform inference. 536 // We don't know the type for this symbol, perform inference.
533 Str type = type_inference(a, node->var_val, scope); 537 Str type = type_inference(a, node->var.val, scope);
534 if (type.size) { 538 if (!type.size || str_eq(type, cstr("nil")) ||
535 symmap_insert(&scope->symbols, symbol, 539 str_has_prefix(type, cstr("ret:"))) {
536 (Symbol){.name = type, .kind = SYM_VAR}, 540 eprintln(
537 a->storage); 541 "%s:%d:%d: error: can't bind `nil` to variable "
538 node->var_name->type = type; 542 "'%s'",
543 a->file_name, node->line, node->col, symbol);
544 a->err = true;
545 return cstr("");
539 } 546 }
547 symmap_insert(&scope->symbols, symbol,
548 (Symbol){.name = type, .kind = SYM_VAR}, a->storage);
549 node->var.name->type = type;
540 symbol = str_concat(cstr("."), symbol, a->storage); 550 symbol = str_concat(cstr("."), symbol, a->storage);
541 symbol = str_concat(symbol, str_from_int(scope->id, a->storage), 551 symbol = str_concat(symbol, str_from_int(scope->id, a->storage),
542 a->storage); 552 a->storage);
@@ -544,23 +554,38 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
544 return node->type; 554 return node->type;
545 } break; 555 } break;
546 case NODE_SET: { 556 case NODE_SET: {
547 Str name = type_inference(a, node->var_name, scope); 557 Str name = type_inference(a, node->var.name, scope);
548 Str val = type_inference(a, node->var_val, scope); 558 Str val = type_inference(a, node->var.val, scope);
559 if (str_has_prefix(name, cstr("@")) ||
560 str_has_prefix(name, cstr("["))) {
561 name = cstr("Ptr");
562 }
563 if (str_has_prefix(val, cstr("@")) ||
564 str_has_prefix(val, cstr("["))) {
565 val = cstr("Ptr");
566 }
549 if (!str_eq(name, val)) { 567 if (!str_eq(name, val)) {
550 eprintln( 568 if (!(strset_lookup(&a->integer_types, name) &&
551 "%s:%d:%d: error: type mismatch, trying to assing " 569 strset_lookup(&a->integer_types, val)) ||
552 "%s" 570 !(strset_lookup(&a->numeric_types, name) &&
553 " to a variable of type %s", 571 strset_lookup(&a->numeric_types, val))) {
554 a->file_name, node->line, node->col, val, name); 572 eprintln(
555 a->err = true; 573 "%s:%d:%d: error: type mismatch, trying to assing "
556 return cstr(""); 574 "%s"
575 " to a variable of type %s",
576 a->file_name, node->line, node->col, val, name);
577 a->err = true;
578 return cstr("");
579 }
557 } 580 }
558 Str symbol = node->var_name->value.str; 581 Str symbol = node->var.name->value.str;
559 FindSymbolResult sym = find_symbol(scope, symbol); 582 FindSymbolResult sym = find_symbol(scope, symbol);
560 node->unique_name = str_concat(cstr("."), symbol, a->storage); 583 if (sym.map) {
561 node->unique_name = 584 node->unique_name = str_concat(cstr("."), symbol, a->storage);
562 str_concat(node->unique_name, 585 node->unique_name = str_concat(
563 str_from_int(sym.scope->id, a->storage), a->storage); 586 node->unique_name, str_from_int(sym.scope->id, a->storage),
587 a->storage);
588 }
564 node->type = cstr("nil"); 589 node->type = cstr("nil");
565 return node->type; 590 return node->type;
566 } break; 591 } break;
@@ -600,7 +625,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
600 enummap_insert(&scope->enums, symbol, 625 enummap_insert(&scope->enums, symbol,
601 (Enum){ 626 (Enum){
602 .name = symbol, 627 .name = symbol,
603 .val = node->field_val, 628 .val = node->field.val,
604 }, 629 },
605 a->storage); 630 a->storage);
606 for (sz i = 0; i < array_size(node->struct_field); i++) { 631 for (sz i = 0; i < array_size(node->struct_field); i++) {
@@ -613,9 +638,9 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
613 a->file_name, field->line, field->col, field_name); 638 a->file_name, field->line, field->col, field_name);
614 a->err = true; 639 a->err = true;
615 } 640 }
616 if (field->field_val) { 641 if (field->field.val) {
617 Str type = type_inference(a, field->field_val, scope); 642 Str type = type_inference(a, field->field.val, scope);
618 if (!str_eq(type, cstr("int"))) { 643 if (!str_eq(type, cstr("Int"))) {
619 eprintln( 644 eprintln(
620 "%s:%d:%d: error: non int enum value for '%s.%s'", 645 "%s:%d:%d: error: non int enum value for '%s.%s'",
621 a->file_name, field->line, field->col, symbol, 646 a->file_name, field->line, field->col, symbol,
@@ -637,26 +662,31 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
637 return node->type; 662 return node->type;
638 } break; 663 } break;
639 case NODE_IF: { 664 case NODE_IF: {
640 Str cond_type = type_inference(a, node->cond_if, scope); 665 Str cond_type = type_inference(a, node->ifelse.cond, scope);
641 if (!str_eq(cond_type, cstr("bool"))) { 666 if (!str_eq(cond_type, cstr("Bool"))) {
642 emit_semantic_error( 667 emit_semantic_error(
643 a, node->cond_if, 668 a, node->ifelse.cond,
644 cstr("non boolean expression on if condition")); 669 cstr("non boolean expression on if condition"));
645 return cstr(""); 670 return cstr("");
646 } 671 }
647 if (node->cond_expr->kind == NODE_BLOCK) { 672 if (node->ifelse.expr_true->kind == NODE_BLOCK) {
648 node->type = type_inference(a, node->cond_expr, scope); 673 node->type = type_inference(a, node->ifelse.expr_true, scope);
649 } else { 674 } else {
650 Scope *next = typescope_alloc(a, scope); 675 Scope *next = typescope_alloc(a, scope);
651 node->type = type_inference(a, node->cond_expr, next); 676 node->type = type_inference(a, node->ifelse.expr_true, next);
652 } 677 }
653 if (node->cond_else) { 678 if (str_has_prefix(node->type, cstr("ret:")) ||
679 str_has_prefix(node->type, cstr("flow:"))) {
680 node->type = cstr("nil");
681 }
682 if (node->ifelse.expr_else) {
654 Str else_type; 683 Str else_type;
655 if (node->cond_else->kind == NODE_BLOCK) { 684 if (node->ifelse.expr_else->kind == NODE_BLOCK) {
656 else_type = type_inference(a, node->cond_else, scope); 685 else_type =
686 type_inference(a, node->ifelse.expr_else, scope);
657 } else { 687 } else {
658 Scope *next = typescope_alloc(a, scope); 688 Scope *next = typescope_alloc(a, scope);
659 else_type = type_inference(a, node->cond_else, next); 689 else_type = type_inference(a, node->ifelse.expr_else, next);
660 } 690 }
661 if (!str_eq(node->type, else_type)) { 691 if (!str_eq(node->type, else_type)) {
662 emit_semantic_error( 692 emit_semantic_error(
@@ -664,9 +694,10 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
664 return cstr(""); 694 return cstr("");
665 } 695 }
666 } 696 }
697
667 // If it returns a value, verify it contains an `else` statement. 698 // If it returns a value, verify it contains an `else` statement.
668 if (!str_eq(node->type, cstr("nil"))) { 699 if (!str_eq(node->type, cstr("nil"))) {
669 if (!node->cond_else) { 700 if (!node->ifelse.expr_else) {
670 emit_semantic_error( 701 emit_semantic_error(
671 a, node, 702 a, node,
672 cstr("missing else statement in if expression")); 703 cstr("missing else statement in if expression"));
@@ -676,25 +707,25 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
676 return node->type; 707 return node->type;
677 } break; 708 } break;
678 case NODE_WHILE: { 709 case NODE_WHILE: {
679 Str cond_type = type_inference(a, node->while_cond, scope); 710 Str cond_type = type_inference(a, node->loop.cond, scope);
680 if (!str_eq(cond_type, cstr("bool"))) { 711 if (!str_eq(cond_type, cstr("Bool"))) {
681 emit_semantic_error( 712 emit_semantic_error(
682 a, node->cond_if, 713 a, node->loop.cond,
683 cstr("non boolean expression on while condition")); 714 cstr("non boolean expression on while condition"));
684 return cstr(""); 715 return cstr("");
685 } 716 }
686 if (node->while_expr->kind != NODE_BLOCK) { 717 if (node->loop.expr->kind != NODE_BLOCK) {
687 scope = typescope_alloc(a, scope); 718 scope = typescope_alloc(a, scope);
688 } 719 }
689 type_inference(a, node->while_expr, scope); 720 type_inference(a, node->loop.expr, scope);
690 node->type = cstr("nil"); 721 node->type = cstr("nil");
691 return node->type; 722 return node->type;
692 } break; 723 } break;
693 case NODE_COND: { 724 case NODE_COND: {
694 Str previous = cstr(""); 725 Str previous = cstr("");
695 bool has_else = false; 726 bool has_else = false;
696 for (sz i = 0; i < array_size(node->match_cases); i++) { 727 for (sz i = 0; i < array_size(node->match.cases); i++) {
697 Node *expr = node->match_cases[i]; 728 Node *expr = node->match.cases[i];
698 Str next = type_inference(a, expr, scope); 729 Str next = type_inference(a, expr, scope);
699 if (i != 0 && !str_eq(next, previous)) { 730 if (i != 0 && !str_eq(next, previous)) {
700 emit_semantic_error( 731 emit_semantic_error(
@@ -702,13 +733,15 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
702 cstr("non-matching types for cond expressions")); 733 cstr("non-matching types for cond expressions"));
703 return cstr(""); 734 return cstr("");
704 } 735 }
705 if (!expr->case_value) { 736 if (!expr->case_entry.cond) {
706 has_else = true; 737 has_else = true;
707 } 738 }
708 previous = next; 739 previous = next;
709 } 740 }
710 // If it returns a value, verify it contains an `else` statement. 741 // If it returns a value, verify it contains an `else` statement.
711 if (!str_eq(previous, cstr("nil"))) { 742 if (!str_eq(node->type, cstr("nil")) &&
743 !str_has_prefix(node->type, cstr("ret:")) &&
744 !str_has_prefix(node->type, cstr("flow:"))) {
712 if (!has_else) { 745 if (!has_else) {
713 emit_semantic_error( 746 emit_semantic_error(
714 a, node, 747 a, node,
@@ -720,16 +753,16 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
720 return node->type; 753 return node->type;
721 } break; 754 } break;
722 case NODE_MATCH: { 755 case NODE_MATCH: {
723 Str e = type_inference(a, node->match_expr, scope); 756 Str e = type_inference(a, node->match.expr, scope);
724 if (str_eq(e, cstr("int"))) { 757 if (str_eq(e, cstr("Int"))) {
725 // Integer matching. 758 // Integer matching.
726 for (sz i = 0; i < array_size(node->match_cases); i++) { 759 for (sz i = 0; i < array_size(node->match.cases); i++) {
727 Node *field = node->match_cases[i]; 760 Node *field = node->match.cases[i];
728 if (field->case_value) { 761 if (field->case_entry.cond) {
729 if (field->case_value->kind != NODE_NUM_INT && 762 if (field->case_entry.cond->kind != NODE_NUM_INT &&
730 field->case_value->kind != NODE_NUM_UINT) { 763 field->case_entry.cond->kind != NODE_NUM_UINT) {
731 emit_semantic_error( 764 emit_semantic_error(
732 a, field->case_value, 765 a, field->case_entry.cond,
733 cstr( 766 cstr(
734 "non-integer or enum types on match case")); 767 "non-integer or enum types on match case"));
735 } 768 }
@@ -740,24 +773,24 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
740 FindEnumResult res = find_enum(scope, e); 773 FindEnumResult res = find_enum(scope, e);
741 Str enum_prefix = 774 Str enum_prefix =
742 str_concat(res.map->val.name, cstr("."), a->storage); 775 str_concat(res.map->val.name, cstr("."), a->storage);
743 for (sz i = 0; i < array_size(node->match_cases); i++) { 776 for (sz i = 0; i < array_size(node->match.cases); i++) {
744 Node *field = node->match_cases[i]; 777 Node *field = node->match.cases[i];
745 if (field->case_value) { 778 if (field->case_entry.cond) {
746 Str field_name = str_concat( 779 Str field_name = str_concat(
747 enum_prefix, field->case_value->value.str, 780 enum_prefix, field->case_entry.cond->value.str,
748 a->storage); 781 a->storage);
749 if (!enummap_lookup(&res.scope->enums, field_name)) { 782 if (!enummap_lookup(&res.scope->enums, field_name)) {
750 eprintln("%s:%d:%d: error: unknown enum field '%s'", 783 eprintln("%s:%d:%d: error: unknown enum field '%s'",
751 a->file_name, field->case_value->line, 784 a->file_name, field->case_entry.cond->line,
752 field->case_value->col, field_name); 785 field->case_entry.cond->col, field_name);
753 a->err = true; 786 a->err = true;
754 } 787 }
755 } 788 }
756 } 789 }
757 } 790 }
758 Str previous = cstr(""); 791 Str previous = cstr("");
759 for (sz i = 0; i < array_size(node->match_cases); i++) { 792 for (sz i = 0; i < array_size(node->match.cases); i++) {
760 Node *expr = node->match_cases[i]; 793 Node *expr = node->match.cases[i];
761 Str next = type_inference(a, expr, scope); 794 Str next = type_inference(a, expr, scope);
762 if (i != 0 && !str_eq(next, previous)) { 795 if (i != 0 && !str_eq(next, previous)) {
763 emit_semantic_error( 796 emit_semantic_error(
@@ -771,29 +804,29 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
771 return node->type; 804 return node->type;
772 } break; 805 } break;
773 case NODE_CASE_MATCH: { 806 case NODE_CASE_MATCH: {
774 if (node->case_expr->kind != NODE_BLOCK) { 807 if (node->case_entry.expr->kind != NODE_BLOCK) {
775 scope = typescope_alloc(a, scope); 808 scope = typescope_alloc(a, scope);
776 } 809 }
777 node->type = type_inference(a, node->case_expr, scope); 810 node->type = type_inference(a, node->case_entry.expr, scope);
778 return node->type; 811 return node->type;
779 } break; 812 } break;
780 case NODE_CASE_COND: { 813 case NODE_CASE_COND: {
781 if (node->case_value) { 814 if (node->case_entry.cond) {
782 Str cond = type_inference(a, node->case_value, scope); 815 Str cond = type_inference(a, node->case_entry.cond, scope);
783 if (!str_eq(cond, cstr("bool"))) { 816 if (!str_eq(cond, cstr("Bool"))) {
784 emit_semantic_error(a, node, 817 emit_semantic_error(a, node,
785 cstr("non-boolean case condition")); 818 cstr("non-boolean case condition"));
786 } 819 }
787 } 820 }
788 if (node->case_expr->kind != NODE_BLOCK) { 821 if (node->case_entry.expr->kind != NODE_BLOCK) {
789 scope = typescope_alloc(a, scope); 822 scope = typescope_alloc(a, scope);
790 } 823 }
791 node->type = type_inference(a, node->case_expr, scope); 824 node->type = type_inference(a, node->case_entry.expr, scope);
792 return node->type; 825 return node->type;
793 } break; 826 } break;
794 case NODE_TRUE: 827 case NODE_TRUE:
795 case NODE_FALSE: { 828 case NODE_FALSE: {
796 node->type = cstr("bool"); 829 node->type = cstr("Bool");
797 return node->type; 830 return node->type;
798 } break; 831 } break;
799 case NODE_NIL: { 832 case NODE_NIL: {
@@ -803,21 +836,21 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
803 case NODE_NOT: 836 case NODE_NOT:
804 case NODE_AND: 837 case NODE_AND:
805 case NODE_OR: { 838 case NODE_OR: {
806 Str left = type_inference(a, node->left, scope); 839 Str left = type_inference(a, node->binary.left, scope);
807 if (!str_eq(left, cstr("bool"))) { 840 if (!str_eq(left, cstr("Bool"))) {
808 emit_semantic_error(a, node, 841 emit_semantic_error(a, node,
809 cstr("expected bool on logic expression")); 842 cstr("expected bool on logic expression"));
810 return cstr(""); 843 return cstr("");
811 } 844 }
812 if (node->right) { 845 if (node->binary.right) {
813 Str right = type_inference(a, node->right, scope); 846 Str right = type_inference(a, node->binary.right, scope);
814 if (!str_eq(right, cstr("bool"))) { 847 if (!str_eq(right, cstr("Bool"))) {
815 emit_semantic_error( 848 emit_semantic_error(
816 a, node, cstr("expected bool on logic expression")); 849 a, node, cstr("expected bool on logic expression"));
817 return cstr(""); 850 return cstr("");
818 } 851 }
819 } 852 }
820 node->type = cstr("bool"); 853 node->type = cstr("Bool");
821 return node->type; 854 return node->type;
822 } break; 855 } break;
823 case NODE_EQ: 856 case NODE_EQ:
@@ -826,18 +859,23 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
826 case NODE_GT: 859 case NODE_GT:
827 case NODE_LE: 860 case NODE_LE:
828 case NODE_GE: { 861 case NODE_GE: {
829 Str left = type_inference(a, node->left, scope); 862 Str left = type_inference(a, node->binary.left, scope);
830 Str right = type_inference(a, node->right, scope); 863 Str right = type_inference(a, node->binary.right, scope);
831 if (!str_eq(left, right)) { 864 if (!str_eq(left, right)) {
832 emit_semantic_error( 865 if (!(strset_lookup(&a->integer_types, left) &&
833 a, node, cstr("mismatched types on binary expression")); 866 strset_lookup(&a->integer_types, right)) ||
834 return cstr(""); 867 !(strset_lookup(&a->numeric_types, left) &&
868 strset_lookup(&a->numeric_types, right))) {
869 emit_semantic_error(
870 a, node, cstr("mismatched types on binary expression"));
871 return cstr("");
872 }
835 } 873 }
836 node->type = cstr("bool"); 874 node->type = cstr("Bool");
837 return node->type; 875 return node->type;
838 } break; 876 } break;
839 case NODE_BITNOT: { 877 case NODE_BITNOT: {
840 Str left = type_inference(a, node->left, scope); 878 Str left = type_inference(a, node->binary.left, scope);
841 if (!strset_lookup(&a->integer_types, left)) { 879 if (!strset_lookup(&a->integer_types, left)) {
842 emit_semantic_error( 880 emit_semantic_error(
843 a, node, cstr("non integer type on bit twiddling expr")); 881 a, node, cstr("non integer type on bit twiddling expr"));
@@ -848,10 +886,11 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
848 } break; 886 } break;
849 case NODE_BITAND: 887 case NODE_BITAND:
850 case NODE_BITOR: 888 case NODE_BITOR:
889 case NODE_BITXOR:
851 case NODE_BITLSHIFT: 890 case NODE_BITLSHIFT:
852 case NODE_BITRSHIFT: { 891 case NODE_BITRSHIFT: {
853 Str left = type_inference(a, node->left, scope); 892 Str left = type_inference(a, node->binary.left, scope);
854 Str right = type_inference(a, node->right, scope); 893 Str right = type_inference(a, node->binary.right, scope);
855 if (!strset_lookup(&a->integer_types, left) || 894 if (!strset_lookup(&a->integer_types, left) ||
856 !strset_lookup(&a->integer_types, right)) { 895 !strset_lookup(&a->integer_types, right)) {
857 emit_semantic_error( 896 emit_semantic_error(
@@ -866,8 +905,15 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
866 case NODE_DIV: 905 case NODE_DIV:
867 case NODE_MUL: 906 case NODE_MUL:
868 case NODE_MOD: { 907 case NODE_MOD: {
869 Str left = type_inference(a, node->left, scope); 908 Str left = type_inference(a, node->binary.left, scope);
870 Str right = type_inference(a, node->right, scope); 909 Str right = type_inference(a, node->binary.right, scope);
910 // Enable pointer arithmetic.
911 if (str_has_prefix(left, cstr("@"))) {
912 left = cstr("Ptr");
913 }
914 if (str_has_prefix(right, cstr("@"))) {
915 right = cstr("Ptr");
916 }
871 if (!strset_lookup(&a->numeric_types, left) || 917 if (!strset_lookup(&a->numeric_types, left) ||
872 !strset_lookup(&a->numeric_types, right)) { 918 !strset_lookup(&a->numeric_types, right)) {
873 emit_semantic_error( 919 emit_semantic_error(
@@ -875,73 +921,149 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
875 return cstr(""); 921 return cstr("");
876 } 922 }
877 if (!str_eq(left, right)) { 923 if (!str_eq(left, right)) {
878 emit_semantic_error( 924 if (!((strset_lookup(&a->integer_types, left) &&
879 a, node, cstr("mismatched types on binary expression")); 925 strset_lookup(&a->integer_types, right)) ||
880 return cstr(""); 926 (strset_lookup(&a->float_types, left) &&
927 strset_lookup(&a->float_types, right)))) {
928 emit_semantic_error(
929 a, node, cstr("mismatched types on binary expression"));
930 return cstr("");
931 }
881 } 932 }
882 node->type = left; 933 node->type = left;
883 return node->type; 934 return node->type;
884 } break; 935 } break;
885 case NODE_NUM_UINT: { 936 case NODE_NUM_UINT: {
886 node->type = cstr("int"); 937 node->type = cstr("UInt");
887 return node->type; 938 return node->type;
888 } break; 939 } break;
889 case NODE_NUM_INT: { 940 case NODE_NUM_INT: {
890 node->type = cstr("int"); 941 node->type = cstr("Int");
891 return node->type; 942 return node->type;
892 } break; 943 } break;
893 case NODE_NUM_FLOAT: { 944 case NODE_NUM_FLOAT: {
894 node->type = cstr("f64"); 945 node->type = cstr("F64");
895 return node->type; 946 return node->type;
896 } break; 947 } break;
897 case NODE_STRING: { 948 case NODE_STRING: {
898 node->type = cstr("str"); 949 node->type = cstr("Str");
899 return node->type; 950 return node->type;
900 } break; 951 } break;
901 case NODE_ARR_TYPE:
902 case NODE_TYPE: { 952 case NODE_TYPE: {
903 SymbolMap *type = find_type(scope, node->value.str); 953 Str base_type = node->value.str;
904 if (!type) { 954 StrSet *set = find_type(scope, node->value.str);
955 if (!set) {
905 emit_semantic_error(a, node, cstr("unknown type")); 956 emit_semantic_error(a, node, cstr("unknown type"));
906 return cstr(""); 957 return cstr("");
907 } 958 }
908 node->type = type->val.name; 959 Node *next = node->t.next;
960 Str type = cstr("");
961 while (next) {
962 switch (next->kind) {
963 case NODE_PTR: {
964 Str suffix = cstr("@");
965 type = str_concat(type, suffix, a->storage);
966 } break;
967 case NODE_ARR: {
968 Str suffix = cstr("[");
969 switch (next->array.kind) {
970 case NODE_ARR_STATIC: {
971 suffix = str_concat(
972 suffix,
973 str_from_int(next->array.size->value.i,
974 a->storage),
975 a->storage);
976 suffix =
977 str_concat(suffix, cstr("]"), a->storage);
978 } break;
979 default: {
980 emit_semantic_error(a, node,
981 cstr("unimplemented"));
982 return cstr("");
983 } break;
984 }
985 type = str_concat(type, suffix, a->storage);
986 } break;
987 default: break;
988 }
989 next = next->t.next;
990 }
991 type = str_concat(type, base_type, a->storage);
992 node->type = type;
993 return node->type;
994 } break;
995 case NODE_DEREF: {
996 Node *next = node->deref.next;
997 Str amount = cstr("@");
998 while (next) {
999 if (next->kind == NODE_SYMBOL) {
1000 break;
1001 }
1002 next = next->deref.next;
1003 amount = str_concat(cstr("@"), amount, a->storage);
1004 }
1005 Str symbol = next->value.str;
1006 Str type = type_inference(a, next, scope);
1007 if (str_has_prefix(type, cstr("["))) {
1008 str_split(&type, cstr("]"));
1009 type = str_concat(cstr("@"), type, a->storage);
1010 }
1011 if (!str_has_prefix(type, amount)) {
1012 eprintln(
1013 "%s:%d:%d: error: invalid type dereference %s from type %s",
1014 a->file_name, node->line, node->col,
1015 str_concat(symbol, amount, a->storage), type);
1016 a->err = true;
1017 return cstr("");
1018 }
1019 type = str_remove_prefix(type, amount);
1020 node->value.str = next->value.str;
1021 node->unique_name = next->unique_name;
1022 node->type = type;
909 return node->type; 1023 return node->type;
910 } break; 1024 } break;
911 case NODE_SYMBOL_IDX:
912 case NODE_SYMBOL: { 1025 case NODE_SYMBOL: {
913 Str symbol = node->value.str; 1026 Str symbol = node->value.str;
914 SymbolMap *type = find_type(scope, symbol); 1027
915 if (!type) { 1028 FindSymbolResult sym = find_symbol(scope, symbol);
1029 if (!sym.map) {
916 eprintln("%s:%d:%d: error: couldn't resolve symbol '%s'", 1030 eprintln("%s:%d:%d: error: couldn't resolve symbol '%s'",
917 a->file_name, node->line, node->col, symbol); 1031 a->file_name, node->line, node->col, symbol);
918 a->err = true; 1032 a->err = true;
919 return cstr(""); 1033 return cstr("");
920 } 1034 }
921 1035
922 FindSymbolResult sym = find_symbol(scope, symbol); 1036 if (!str_eq(sym.scope->name, scope->name) && sym.scope->name.size) {
1037 eprintln(
1038 "%s:%d:%d: error: can't capture external local symbol '%s'",
1039 a->file_name, node->line, node->col, symbol);
1040 a->err = true;
1041 return cstr("");
1042 }
923 node->unique_name = str_concat(cstr("."), symbol, a->storage); 1043 node->unique_name = str_concat(cstr("."), symbol, a->storage);
924 node->unique_name = 1044 node->unique_name =
925 str_concat(node->unique_name, 1045 str_concat(node->unique_name,
926 str_from_int(sym.scope->id, a->storage), a->storage); 1046 str_from_int(sym.scope->id, a->storage), a->storage);
927 1047
928 Str type_name = type->val.name; 1048 Str type_name = sym.map->val.name;
929 if (node->kind == NODE_SYMBOL_IDX) { 1049 // if (node->kind == NODE_SYMBOL_IDX) {
930 Str idx_type = type_inference(a, node->arr_size, scope); 1050 // // TODO: get rid of NODE_SYMBOL_IDX, use deref instead
931 if (!strset_lookup(&a->integer_types, idx_type)) { 1051 // Str idx_type = type_inference(a, node->sym.arr_size, scope);
932 emit_semantic_error( 1052 // if (!strset_lookup(&a->integer_types, idx_type)) {
933 a, node, cstr("can't resolve non integer index")); 1053 // emit_semantic_error(
934 return cstr(""); 1054 // a, node, cstr("can't resolve non integer index"));
935 } 1055 // return cstr("");
936 type_name = str_remove_prefix(type_name, cstr("@")); 1056 // }
937 } 1057 // if (str_has_prefix(type_name, cstr("@"))) {
938 if (node->is_ptr) { 1058 // type_name = str_remove_prefix(type_name, cstr("@"));
939 type_name = str_concat(cstr("@"), type_name, a->storage); 1059 // } else if (str_has_prefix(type_name, cstr("["))) {
940 } 1060 // str_split(&type_name, cstr("]"));
1061 // }
1062 // }
941 1063
942 FindEnumResult e = find_enum(scope, type_name); 1064 FindEnumResult e = find_enum(scope, type_name);
943 if (e.map && str_eq(symbol, type_name)) { 1065 if (e.map && str_eq(symbol, type_name)) {
944 if (!node->next) { 1066 if (!node->sym.next) {
945 eprintln( 1067 eprintln(
946 "%s:%d:%d: error: unspecified enum field for symbol " 1068 "%s:%d:%d: error: unspecified enum field for symbol "
947 "'%s'", 1069 "'%s'",
@@ -951,20 +1073,21 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
951 } 1073 }
952 // Check if there is a next and it matches the enum field. 1074 // Check if there is a next and it matches the enum field.
953 Str field = str_concat(type_name, cstr("."), a->storage); 1075 Str field = str_concat(type_name, cstr("."), a->storage);
954 field = str_concat(field, node->next->value.str, a->storage); 1076 field =
1077 str_concat(field, node->sym.next->value.str, a->storage);
955 if (!enummap_lookup(&e.scope->enums, field)) { 1078 if (!enummap_lookup(&e.scope->enums, field)) {
956 eprintln( 1079 eprintln(
957 "%s:%d:%d: error: unknown enum field for " 1080 "%s:%d:%d: error: unknown enum field for "
958 "'%s': %s", 1081 "'%s': %s",
959 a->file_name, node->line, node->col, symbol, 1082 a->file_name, node->line, node->col, symbol,
960 node->next->value.str); 1083 node->sym.next->value.str);
961 a->err = true; 1084 a->err = true;
962 return cstr(""); 1085 return cstr("");
963 } 1086 }
964 1087
965 node->next->type = type_name; 1088 node->sym.next->type = type_name;
966 node->type = type_name; 1089 node->type = type_name;
967 return node->next->type; 1090 return node->sym.next->type;
968 } 1091 }
969 1092
970 FindStructResult s = find_struct(scope, type_name); 1093 FindStructResult s = find_struct(scope, type_name);
@@ -977,11 +1100,11 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
977 a->err = true; 1100 a->err = true;
978 return cstr(""); 1101 return cstr("");
979 } else { 1102 } else {
980 if (node->next) { 1103 if (node->sym.next) {
981 Str chain = type_name; 1104 Str chain = type_name;
982 Node *next = node; 1105 Node *next = node;
983 while (next->next) { 1106 while (next->sym.next) {
984 next = next->next; 1107 next = next->sym.next;
985 chain = str_concat(chain, cstr("."), a->storage); 1108 chain = str_concat(chain, cstr("."), a->storage);
986 chain = 1109 chain =
987 str_concat(chain, next->value.str, a->storage); 1110 str_concat(chain, next->value.str, a->storage);
@@ -996,18 +1119,18 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
996 return cstr(""); 1119 return cstr("");
997 } 1120 }
998 Str field_type = field->val.type; 1121 Str field_type = field->val.type;
999 if (next->kind == NODE_SYMBOL_IDX) { 1122 // if (next->kind == NODE_SYMBOL_IDX) {
1000 Str idx_type = 1123 // Str idx_type =
1001 type_inference(a, next->arr_size, scope); 1124 // type_inference(a, next->sym.arr_size, scope);
1002 if (!strset_lookup(&a->integer_types, idx_type)) { 1125 // if (!strset_lookup(&a->integer_types, idx_type)) {
1003 emit_semantic_error( 1126 // emit_semantic_error(
1004 a, next, 1127 // a, next,
1005 cstr("can't resolve non integer index")); 1128 // cstr("can't resolve non integer index"));
1006 return cstr(""); 1129 // return cstr("");
1007 } 1130 // }
1008 field_type = 1131 // field_type =
1009 str_remove_prefix(field_type, cstr("@")); 1132 // str_remove_prefix(field_type, cstr("@"));
1010 } 1133 // }
1011 node->type = field_type; 1134 node->type = field_type;
1012 return node->type; 1135 return node->type;
1013 } 1136 }
@@ -1016,6 +1139,12 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1016 node->type = type_name; 1139 node->type = type_name;
1017 return node->type; 1140 return node->type;
1018 } break; 1141 } break;
1142 case NODE_PTR: {
1143 Str type = type_inference(a, node->t.next, scope);
1144 type = str_concat(cstr("@"), type, a->storage);
1145 node->type = type;
1146 return node->type;
1147 } break;
1019 case NODE_STRUCT_LIT: { 1148 case NODE_STRUCT_LIT: {
1020 Str name = node->value.str; 1149 Str name = node->value.str;
1021 FindStructResult s = find_struct(scope, name); 1150 FindStructResult s = find_struct(scope, name);
@@ -1064,27 +1193,56 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1064 str_concat(node->unique_name, 1193 str_concat(node->unique_name,
1065 str_from_int(sym.scope->id, a->storage), a->storage); 1194 str_from_int(sym.scope->id, a->storage), a->storage);
1066 1195
1067 // Check that actual parameters typecheck 1196 // Check function aritiy.
1068 Str args = cstr(""); 1197 sz arity_fun = fun->val.param_arity;
1198 sz arity_call = array_size(node->elements);
1199 if (arity_fun != -1) {
1200 if (arity_fun != arity_call) {
1201 eprintln(
1202 "%s:%d:%d: error: wrong number of parameters for "
1203 "funcall: "
1204 "%s "
1205 "expected "
1206 "%d"
1207 " got %d",
1208 a->file_name, node->line, node->col, symbol, arity_fun,
1209 arity_call);
1210 a->err = true;
1211 return cstr("");
1212 }
1213 }
1214
1215 if (sym.map->val.kind == SYM_BUILTIN_FUN &&
1216 str_eq(fun->key, cstr("sizeof"))) {
1217 // Node *expr = node->elements[0];
1218 // Str type = type_inference(a, expr, scope);
1219 node->type = fun->val.return_type;
1220 return node->type;
1221 }
1222
1069 for (sz i = 0; i < array_size(node->elements); i++) { 1223 for (sz i = 0; i < array_size(node->elements); i++) {
1070 Node *expr = node->elements[i]; 1224 Node *expr = node->elements[i];
1071 Str type = type_inference(a, expr, scope); 1225 Str type = type_inference(a, expr, scope);
1072 args = str_concat(args, type, a->storage); 1226 if (!str_eq(fun->val.param_type, cstr("..."))) {
1073 if (i != array_size(node->elements) - 1) { 1227 Str expected = fun->val.param_types[i];
1074 args = str_concat(args, cstr(","), a->storage); 1228 if (!str_eq(type, expected)) {
1229 if (!(strset_lookup(&a->integer_types, type) &&
1230 strset_lookup(&a->integer_types, expected)) ||
1231 !(strset_lookup(&a->numeric_types, type) &&
1232 strset_lookup(&a->numeric_types, expected))) {
1233 eprintln(
1234 "%s:%d:%d: error: mismatched parameter types: "
1235 "%s "
1236 "expected "
1237 "%s",
1238 a->file_name, node->line, node->col, type,
1239 expected);
1240 a->err = true;
1241 return cstr("");
1242 }
1243 }
1075 } 1244 }
1076 } 1245 }
1077 if (!args.size) {
1078 args = cstr("nil");
1079 }
1080 Str expected = fun->val.param_type;
1081 if (!str_eq(args, expected) && !str_eq(expected, cstr("..."))) {
1082 eprintln(
1083 "%s:%d:%d: error: mismatched parameter types: %s expected "
1084 "%s",
1085 a->file_name, node->line, node->col, args, expected);
1086 a->err = true;
1087 }
1088 node->type = fun->val.return_type; 1246 node->type = fun->val.return_type;
1089 return node->type; 1247 return node->type;
1090 } break; 1248 } break;
@@ -1094,12 +1252,22 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1094 for (sz i = 0; i < array_size(node->elements); i++) { 1252 for (sz i = 0; i < array_size(node->elements); i++) {
1095 Node *expr = node->elements[i]; 1253 Node *expr = node->elements[i];
1096 type = type_inference(a, expr, scope); 1254 type = type_inference(a, expr, scope);
1255 if (str_has_prefix(type, cstr("ret:")) ||
1256 str_has_prefix(type, cstr("flow:"))) {
1257 break;
1258 }
1097 } 1259 }
1098 node->type = type; 1260 node->type = type;
1099 return node->type; 1261 return node->type;
1100 } break; 1262 } break;
1101 case NODE_RETURN: { 1263 case NODE_RETURN: {
1102 Str ret_type = cstr(""); 1264 if (!scope->name.size) {
1265 emit_semantic_error(
1266 a, node, cstr("return statement outside a function"));
1267 a->err = true;
1268 return cstr("");
1269 }
1270 Str ret_type = cstr("ret:");
1103 for (sz i = 0; i < array_size(node->elements); i++) { 1271 for (sz i = 0; i < array_size(node->elements); i++) {
1104 Node *expr = node->elements[i]; 1272 Node *expr = node->elements[i];
1105 Str type = type_inference(a, expr, scope); 1273 Str type = type_inference(a, expr, scope);
@@ -1114,123 +1282,156 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1114 node->type = ret_type; 1282 node->type = ret_type;
1115 return node->type; 1283 return node->type;
1116 } break; 1284 } break;
1285 case NODE_CONTINUE:
1286 case NODE_BREAK: {
1287 // Check if we are inside a loop.
1288 Node *parent = node->parent;
1289 bool inside_loop = false;
1290 while (parent != NULL) {
1291 if (parent->kind == NODE_WHILE) {
1292 inside_loop = true;
1293 break;
1294 }
1295 parent = parent->parent;
1296 }
1297 if (!inside_loop) {
1298 eprintln(
1299 "%s:%d:%d: error: control flow statement outside a "
1300 "loop",
1301 a->file_name, node->line, node->col);
1302 a->err = true;
1303 return cstr("");
1304 }
1305 node->type = cstr("flow:");
1306 return node->type;
1307 } break;
1117 case NODE_FUN: { 1308 case NODE_FUN: {
1118 node->type = cstr("nil"); 1309 node->type = cstr("nil");
1119 Scope *prev_scope = scope; 1310 Scope *prev_scope = scope;
1120 scope = typescope_alloc(a, scope); 1311 scope = typescope_alloc(a, scope);
1121 Str param_type = cstr(""); 1312 Str param_type = cstr("");
1122 for (sz i = 0; i < array_size(node->func_params); i++) { 1313 Str symbol = node->func.name->value.str;
1123 Node *param = node->func_params[i]; 1314 Fun fun = (Fun){.name = symbol};
1124 Str symbol = param->param_name->value.str; 1315 for (sz i = 0; i < array_size(node->func.params); i++) {
1125 Str type = param->param_type->value.str; 1316 Node *param = node->func.params[i];
1126 if (param->param_type->is_ptr) { 1317 Str symbol = param->param.name->value.str;
1127 type = str_concat(cstr("@"), type, a->storage); 1318 Str type = param->param.type->value.str;
1128 } 1319 param->param.name->type =
1129 if (param->param_type->kind == NODE_ARR_TYPE) { 1320 type_inference(a, param->param.type, scope);
1130 type = str_concat(cstr("@"), type, a->storage);
1131 }
1132 param->param_name->type =
1133 type_inference(a, param->param_type, scope);
1134 param->type = type; 1321 param->type = type;
1322 array_push(fun.param_types, type, a->storage);
1135 symmap_insert(&scope->symbols, symbol, 1323 symmap_insert(&scope->symbols, symbol,
1136 (Symbol){.name = type, .kind = SYM_PARAM}, 1324 (Symbol){.name = type, .kind = SYM_PARAM},
1137 a->storage); 1325 a->storage);
1138 param_type = str_concat(param_type, type, a->storage); 1326 param_type = str_concat(param_type, type, a->storage);
1139 if (i != array_size(node->func_params) - 1) { 1327 if (i != array_size(node->func.params) - 1) {
1140 param_type = str_concat(param_type, cstr(","), a->storage); 1328 param_type = str_concat(param_type, cstr(","), a->storage);
1141 } 1329 }
1330 symbol = str_concat(cstr("."), symbol, a->storage);
1331 symbol = str_concat(symbol, str_from_int(scope->id, a->storage),
1332 a->storage);
1333 param->unique_name = symbol;
1142 } 1334 }
1143 if (!param_type.size) { 1335 if (!param_type.size) {
1144 param_type = cstr("nil"); 1336 param_type = cstr("nil");
1145 } 1337 }
1146 node->fun_params = param_type; 1338 node->type_params = param_type;
1339 fun.param_arity = array_size(node->func.params);
1147 1340
1148 Str ret_type = cstr(""); 1341 Str ret_type = cstr("");
1149 for (sz i = 0; i < array_size(node->func_ret); i++) { 1342 for (sz i = 0; i < array_size(node->func.ret); i++) {
1150 Node *expr = node->func_ret[i]; 1343 Node *expr = node->func.ret[i];
1151 Str type = type_inference(a, expr, scope); 1344 Str type = type_inference(a, expr, scope);
1152 if (expr->is_ptr) {
1153 type = str_concat(cstr("@"), type, a->storage);
1154 }
1155 if (expr->kind == NODE_ARR_TYPE) {
1156 type = str_concat(cstr("@"), type, a->storage);
1157 }
1158 ret_type = str_concat(ret_type, type, a->storage); 1345 ret_type = str_concat(ret_type, type, a->storage);
1159 if (i != array_size(node->func_ret) - 1) { 1346 array_push(fun.return_types, ret_type, a->storage);
1347 if (i != array_size(node->func.ret) - 1) {
1160 ret_type = str_concat(ret_type, cstr(","), a->storage); 1348 ret_type = str_concat(ret_type, cstr(","), a->storage);
1161 } 1349 }
1162 } 1350 }
1351 fun.return_arity = array_size(node->func.ret);
1163 if (!ret_type.size) { 1352 if (!ret_type.size) {
1164 ret_type = cstr("nil"); 1353 ret_type = cstr("nil");
1165 } 1354 }
1166 node->fun_return = ret_type; 1355 node->type_returns = ret_type;
1167 1356
1168 Str symbol = node->func_name->value.str;
1169 if (prev_scope->parent != NULL) { 1357 if (prev_scope->parent != NULL) {
1170 if (symmap_lookup(&prev_scope->symbols, symbol)) { 1358 if (symmap_lookup(&prev_scope->symbols, symbol)) {
1171 eprintln( 1359 eprintln(
1172 "%s:%d:%d: error: function '%s' already defined in " 1360 "%s:%d:%d: error: function '%s' already defined in "
1173 "current " 1361 "current "
1174 "scope ", 1362 "scope ",
1175 a->file_name, node->var_name->line, node->var_name->col, 1363 a->file_name, node->var.name->line, node->var.name->col,
1176 symbol); 1364 symbol);
1177 a->err = true; 1365 a->err = true;
1178 return cstr(""); 1366 return cstr("");
1179 } 1367 }
1180 symmap_insert(&scope->symbols, symbol, 1368 symmap_insert(&prev_scope->symbols, symbol,
1181 (Symbol){.name = symbol, .kind = SYM_FUN}, 1369 (Symbol){.name = symbol, .kind = SYM_FUN},
1182 a->storage); 1370 a->storage);
1183 } 1371 }
1184 scope->name = symbol; 1372 scope->name = symbol;
1185 funmap_insert(&prev_scope->funcs, symbol, 1373 fun.param_type = param_type;
1186 (Fun){.name = symbol, 1374 fun.return_type = ret_type;
1187 .param_type = param_type, 1375 funmap_insert(&prev_scope->funcs, symbol, fun, a->storage);
1188 .return_type = ret_type},
1189 a->storage);
1190 symbol = str_concat(cstr("."), symbol, a->storage); 1376 symbol = str_concat(cstr("."), symbol, a->storage);
1191 symbol = str_concat(symbol, str_from_int(prev_scope->id, a->storage), 1377 symbol = str_concat(
1192 a->storage); 1378 symbol, str_from_int(prev_scope->id, a->storage), a->storage);
1193 node->unique_name = symbol; 1379 node->unique_name = symbol;
1194 1380
1195 if (node->func_body->kind == NODE_BLOCK) { 1381 if (node->func.body->kind == NODE_BLOCK) {
1196 Str type; 1382 Str type;
1197 for (sz i = 0; i < array_size(node->func_body->elements); i++) { 1383 for (sz i = 0; i < array_size(node->func.body->elements); i++) {
1198 Node *expr = node->func_body->elements[i]; 1384 Node *expr = node->func.body->elements[i];
1199 type = type_inference(a, expr, scope); 1385 type = type_inference(a, expr, scope);
1200 } 1386 }
1201 if (!type.size) { 1387 if (!type.size) {
1202 type = cstr("nil"); 1388 type = cstr("nil");
1203 } 1389 }
1204 node->func_body->type = type; 1390 node->func.body->type = type;
1205 } else { 1391 } else {
1206 type_inference(a, node->func_body, scope); 1392 type_inference(a, node->func.body, scope);
1207 } 1393 }
1208 1394
1209 // Ensure main body return matches the prototype. 1395 // Ensure main body return matches the prototype.
1210 if (!str_eq(node->func_body->type, ret_type)) { 1396 Str type = str_remove_prefix(node->func.body->type, cstr("ret:"));
1211 eprintln( 1397 node->func.body->type = type;
1212 "%s:%d:%d: error: mismatched return type %s, expected %s", 1398 if (!str_eq(type, ret_type)) {
1213 a->file_name, node->line, node->col, node->func_body->type, 1399 if (!(strset_lookup(&a->integer_types, type) &&
1214 ret_type); 1400 strset_lookup(&a->integer_types, ret_type)) ||
1215 a->err = true; 1401 !(strset_lookup(&a->numeric_types, type) &&
1402 strset_lookup(&a->numeric_types, ret_type))) {
1403 eprintln(
1404 "%s:%d:%d: error: mismatched return type %s, "
1405 "expected "
1406 "%s",
1407 a->file_name, node->line, node->col, type, ret_type);
1408 a->err = true;
1409 }
1216 } 1410 }
1217 1411
1218 // Ensure ALL return statements match the function prototype. 1412 // Ensure ALL return statements match the function prototype.
1219 typecheck_returns(a, node->func_body, ret_type); 1413 typecheck_returns(a, node->func.body, ret_type);
1220
1221 // TODO: should return statements be allowed on let blocks?
1222 return node->type; 1414 return node->type;
1223 } break; 1415 } break;
1224 default: { 1416 default: {
1225 emit_semantic_error(a, node, 1417 eprintln(
1226 cstr("type inference not implemented for this " 1418 "%s:%d:%d: error: type inference not implemented for node "
1227 "kind of expression")); 1419 "type: %s",
1228 println("KIND: %s", node_str[node->kind]); 1420 a->file_name, node->line, node->col, node_str[node->kind]);
1421 a->err = true;
1229 } break; 1422 } break;
1230 } 1423 }
1231 return cstr(""); 1424 return cstr("");
1232} 1425}
1233 1426
1427typedef struct BuiltinFun {
1428 Str name;
1429 Str param_type;
1430 Str return_type;
1431 sz param_arity;
1432 sz return_arity;
1433} BuiltinFun;
1434
1234void 1435void
1235symbolic_analysis(Analyzer *a, Parser *parser) { 1436symbolic_analysis(Analyzer *a, Parser *parser) {
1236 Scope *scope = typescope_alloc(a, NULL); 1437 Scope *scope = typescope_alloc(a, NULL);
@@ -1238,64 +1439,114 @@ symbolic_analysis(Analyzer *a, Parser *parser) {
1238 assert(parser); 1439 assert(parser);
1239 1440
1240 // Fill builtin tables. 1441 // Fill builtin tables.
1241 Str builtin_functions[] = { 1442 BuiltinFun builtin_functions[] = {
1242 cstr("print"), 1443 {cstr("print"), cstr("..."), cstr("nil"), -1, 0},
1243 cstr("println"), 1444 {cstr("println"), cstr("..."), cstr("nil"), -1, 0},
1445 {cstr("sizeof"), cstr(":"), cstr("Int"), 1, 1},
1244 }; 1446 };
1245 for (sz i = 0; i < LEN(builtin_functions); i++) { 1447 for (sz i = 0; i < LEN(builtin_functions); i++) {
1246 Str symbol = builtin_functions[i]; 1448 Str symbol = builtin_functions[i].name;
1449 Str param_type = builtin_functions[i].param_type;
1450 Str return_type = builtin_functions[i].return_type;
1451 sz param_arity = builtin_functions[i].param_arity;
1452 sz return_arity = builtin_functions[i].return_arity;
1247 symmap_insert(&scope->symbols, symbol, 1453 symmap_insert(&scope->symbols, symbol,
1248 (Symbol){.name = symbol, .kind = SYM_BUILTIN_FUN}, 1454 (Symbol){.name = symbol, .kind = SYM_BUILTIN_FUN},
1249 a->storage); 1455 a->storage);
1250 funmap_insert(&scope->funcs, symbol, 1456 funmap_insert(&scope->funcs, symbol,
1251 (Fun){.name = symbol, 1457 (Fun){
1252 .param_type = cstr("..."), 1458 .name = symbol,
1253 .return_type = cstr("nil")}, 1459 .param_type = param_type,
1460 .return_type = return_type,
1461 .param_arity = param_arity,
1462 .return_arity = return_arity,
1463 },
1254 a->storage); 1464 a->storage);
1255 } 1465 }
1256 Str builtin_types[] = { 1466 Str builtin_types[] = {
1257 cstr("u8"), cstr("s8"), cstr("u16"), cstr("s16"), 1467 cstr("U8"), cstr("S8"), cstr("U16"), cstr("S16"),
1258 cstr("u32"), cstr("s32"), cstr("u64"), cstr("s64"), 1468 cstr("U32"), cstr("S32"), cstr("U64"), cstr("S64"),
1259 cstr("f32"), cstr("f64"), cstr("ptr"), cstr("int"), 1469 cstr("F32"), cstr("F64"), cstr("Ptr"), cstr("Int"),
1260 cstr("uint"), cstr("str"), cstr("bool"), cstr("nil")}; 1470 cstr("UInt"), cstr("Str"), cstr("Bool"), cstr("Nil")};
1261 for (sz i = 0; i < LEN(builtin_types); i++) { 1471 for (sz i = 0; i < LEN(builtin_types); i++) {
1262 Str type = builtin_types[i]; 1472 Str type = builtin_types[i];
1263 symmap_insert(&scope->symbols, type, 1473 symmap_insert(&scope->symbols, type,
1264 (Symbol){.name = type, .kind = SYM_BUILTIN_TYPE}, 1474 (Symbol){.name = cstr("nil"), .kind = SYM_BUILTIN_TYPE},
1265 a->storage); 1475 a->storage);
1476 strset_insert(&scope->types, type, a->storage);
1266 } 1477 }
1267 Str numeric_types[] = { 1478 Str numeric_types[] = {
1268 cstr("u8"), cstr("s8"), cstr("u16"), cstr("s16"), cstr("u32"), 1479 cstr("U8"), cstr("S8"), cstr("U16"), cstr("S16"), cstr("U32"),
1269 cstr("s32"), cstr("u64"), cstr("s64"), cstr("f32"), cstr("f64"), 1480 cstr("S32"), cstr("U64"), cstr("S64"), cstr("F32"), cstr("F64"),
1270 cstr("ptr"), cstr("int"), cstr("uint"), 1481 cstr("Ptr"), cstr("Int"), cstr("UInt"),
1271 }; 1482 };
1272 for (sz i = 0; i < LEN(numeric_types); i++) { 1483 for (sz i = 0; i < LEN(numeric_types); i++) {
1273 Str type = numeric_types[i]; 1484 Str type = numeric_types[i];
1274 strset_insert(&a->numeric_types, type, a->storage); 1485 strset_insert(&a->numeric_types, type, a->storage);
1275 } 1486 }
1276 Str integer_types[] = { 1487 Str integer_types[] = {
1277 cstr("u8"), cstr("s8"), cstr("u16"), cstr("s16"), 1488 cstr("U8"), cstr("S8"), cstr("U16"), cstr("S16"),
1278 cstr("u32"), cstr("s32"), cstr("u64"), cstr("s64"), 1489 cstr("U32"), cstr("S32"), cstr("U64"), cstr("S64"),
1279 cstr("ptr"), cstr("int"), cstr("uint"), 1490 cstr("Ptr"), cstr("Int"), cstr("UInt"),
1280 }; 1491 };
1281 for (sz i = 0; i < LEN(integer_types); i++) { 1492 for (sz i = 0; i < LEN(integer_types); i++) {
1282 Str type = integer_types[i]; 1493 Str type = integer_types[i];
1283 strset_insert(&a->integer_types, type, a->storage); 1494 strset_insert(&a->integer_types, type, a->storage);
1284 } 1495 }
1496 Str float_types[] = {
1497 cstr("F32"),
1498 cstr("F64"),
1499 };
1500 for (sz i = 0; i < LEN(float_types); i++) {
1501 Str type = float_types[i];
1502 strset_insert(&a->float_types, type, a->storage);
1503 }
1285 // Find top level function declarations. 1504 // Find top level function declarations.
1286 for (sz i = 0; i < array_size(parser->nodes); i++) { 1505 for (sz i = 0; i < array_size(parser->nodes); i++) {
1287 Node *root = parser->nodes[i]; 1506 Node *root = parser->nodes[i];
1288 if (root->kind == NODE_FUN) { 1507 if (root->kind == NODE_FUN) {
1289 Str symbol = root->func_name->value.str; 1508 Str symbol = root->func.name->value.str;
1290 if (symmap_lookup(&scope->symbols, symbol)) { 1509 if (symmap_lookup(&scope->symbols, symbol)) {
1291 eprintln( 1510 eprintln(
1292 "%s:%d:%d: error: function '%s' already defined in " 1511 "%s:%d:%d: error: function '%s' already defined in "
1293 "current " 1512 "current "
1294 "scope ", 1513 "scope ",
1295 a->file_name, root->var_name->line, root->var_name->col, 1514 a->file_name, root->var.name->line, root->var.name->col,
1296 symbol); 1515 symbol);
1297 a->err = true; 1516 a->err = true;
1298 } 1517 }
1518 Fun fun = (Fun){.name = symbol};
1519 Str param_type = cstr("");
1520 for (sz i = 0; i < array_size(root->func.params); i++) {
1521 Node *param = root->func.params[i];
1522 Str type = param->param.type->value.str;
1523 array_push(fun.param_types, type, a->storage);
1524 param_type = str_concat(param_type, type, a->storage);
1525 if (i != array_size(root->func.params) - 1) {
1526 param_type = str_concat(param_type, cstr(","), a->storage);
1527 }
1528 }
1529 if (!param_type.size) {
1530 param_type = cstr("nil");
1531 }
1532 root->type_params = param_type;
1533
1534 Str ret_type = cstr("");
1535 for (sz i = 0; i < array_size(root->func.ret); i++) {
1536 Node *expr = root->func.ret[i];
1537 Str type = expr->value.str;
1538 array_push(fun.return_types, ret_type, a->storage);
1539 ret_type = str_concat(ret_type, type, a->storage);
1540 if (i != array_size(root->func.ret) - 1) {
1541 ret_type = str_concat(ret_type, cstr(","), a->storage);
1542 }
1543 }
1544 if (!ret_type.size) {
1545 ret_type = cstr("nil");
1546 }
1547 fun.param_type = param_type;
1548 fun.return_type = ret_type;
1549 funmap_insert(&scope->funcs, symbol, fun, a->storage);
1299 symmap_insert(&scope->symbols, symbol, 1550 symmap_insert(&scope->symbols, symbol,
1300 (Symbol){.name = symbol, .kind = SYM_FUN}, 1551 (Symbol){.name = symbol, .kind = SYM_FUN},
1301 a->storage); 1552 a->storage);
diff --git a/src/vm.c b/src/vm.c
index 2992a18..ed69498 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -5,8 +5,9 @@
5#include "compiler.c" 5#include "compiler.c"
6 6
7#define N_CONST 256 7#define N_CONST 256
8#define STACK_SIZE KB(64) 8#define STACK_SIZE MB(4)
9typedef struct VM { 9typedef struct VM {
10 Chunk *main;
10 Chunk *chunk; 11 Chunk *chunk;
11 u8 stack[STACK_SIZE]; 12 u8 stack[STACK_SIZE];
12 Instruction *ip; 13 Instruction *ip;
@@ -20,6 +21,7 @@ vm_init(VM *vm, Chunk *chunk) {
20 assert(vm); 21 assert(vm);
21 assert(chunk); 22 assert(chunk);
22 assert(chunk->code); 23 assert(chunk->code);
24 vm->main = chunk;
23 vm->chunk = chunk; 25 vm->chunk = chunk;
24 vm->ip = vm->chunk->code; 26 vm->ip = vm->chunk->code;
25 vm->fp = (u64 *)vm->stack; 27 vm->fp = (u64 *)vm->stack;
@@ -75,7 +77,7 @@ vm_run(VM *vm) {
75#endif 77#endif
76 78
77 switch (instruction.op) { 79 switch (instruction.op) {
78 case OP_LD64K: { 80 case OP_LDCONST: {
79 u8 dst = instruction.dst; 81 u8 dst = instruction.dst;
80 u8 src_a = instruction.a; 82 u8 src_a = instruction.a;
81 vm->regs[dst].i = vm->chunk->constants[src_a].i; 83 vm->regs[dst].i = vm->chunk->constants[src_a].i;
@@ -83,6 +85,7 @@ vm_run(VM *vm) {
83 case OP_NOT: OP_UNARY(!, i) break; 85 case OP_NOT: OP_UNARY(!, i) break;
84 case OP_BITNOT: OP_UNARY(~, i) break; 86 case OP_BITNOT: OP_UNARY(~, i) break;
85 case OP_BITOR: OP_BINARY(|, i) break; 87 case OP_BITOR: OP_BINARY(|, i) break;
88 case OP_BITXOR: OP_BINARY(^, i) break;
86 case OP_BITAND: OP_BINARY(&, i) break; 89 case OP_BITAND: OP_BINARY(&, i) break;
87 case OP_BITLSHIFT: OP_BINARY(<<, i) break; 90 case OP_BITLSHIFT: OP_BINARY(<<, i) break;
88 case OP_BITRSHIFT: OP_BINARY(>>, i) break; 91 case OP_BITRSHIFT: OP_BINARY(>>, i) break;
@@ -113,6 +116,7 @@ vm_run(VM *vm) {
113 case OP_NOTI: OP_UNARY_CONST(!, i) break; 116 case OP_NOTI: OP_UNARY_CONST(!, i) break;
114 case OP_BITNOTI: OP_UNARY_CONST(~, i) break; 117 case OP_BITNOTI: OP_UNARY_CONST(~, i) break;
115 case OP_BITORI: OP_BINARY_CONST(|, i) break; 118 case OP_BITORI: OP_BINARY_CONST(|, i) break;
119 case OP_BITXORI: OP_BINARY_CONST(^, i) break;
116 case OP_BITANDI: OP_BINARY_CONST(&, i) break; 120 case OP_BITANDI: OP_BINARY_CONST(&, i) break;
117 case OP_BITLSHIFTI: OP_BINARY_CONST(<<, i) break; 121 case OP_BITLSHIFTI: OP_BINARY_CONST(<<, i) break;
118 case OP_BITRSHIFTI: OP_BINARY_CONST(>>, i) break; 122 case OP_BITRSHIFTI: OP_BINARY_CONST(>>, i) break;
@@ -140,22 +144,66 @@ vm_run(VM *vm) {
140 vm->regs[dst].f = 144 vm->regs[dst].f =
141 fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f); 145 fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f);
142 } break; 146 } break;
147 case OP_STGVAR: {
148 u8 dst = instruction.dst;
149 u8 src = instruction.a;
150 Variable var = vm->main->vars[dst];
151 s64 *stack = (s64 *)&vm->stack[var.offset];
152 *stack = vm->regs[src].i;
153 } break;
154 case OP_STGVARI: {
155 u8 dst = instruction.dst;
156 u8 src = instruction.a;
157 Variable var = vm->main->vars[dst];
158 s64 *stack = (s64 *)&vm->stack[var.offset];
159 *stack = vm->chunk->constants[src].i;
160 } break;
143 case OP_LDGVAR: { 161 case OP_LDGVAR: {
144 u8 dst = instruction.dst; 162 u8 dst = instruction.dst;
145 u8 src = instruction.a; 163 u8 src = instruction.a;
146 Variable var = vm->chunk->vars[src]; 164 Variable var = vm->main->vars[src];
147 s64 *stack = (s64 *)&vm->stack[var.offset]; 165 s64 *stack = (s64 *)&vm->stack[var.offset];
148 vm->regs[dst].i = *stack; 166 vm->regs[dst].i = *stack;
149 } break; 167 } break;
150 case OP_LDGADDR: { 168 case OP_LDGADDR: {
151 u8 dst = instruction.dst; 169 u8 dst = instruction.dst;
152 u8 src = instruction.a; 170 u8 src = instruction.a;
153 Variable var = vm->chunk->vars[src]; 171 Variable var = vm->main->vars[src];
154 s64 *stack = (s64 *)&vm->stack[var.offset]; 172 s64 *stack = (s64 *)&vm->stack[var.offset];
155 vm->regs[dst].ptr = (ptrsize)stack; 173 vm->regs[dst].ptr = (ptrsize)stack;
156 } break; 174 } break;
175 case OP_STLVAR: {
176 u8 dst = instruction.dst;
177 u8 src = instruction.a;
178 Variable var = vm->chunk->vars[dst];
179 vm->fp[var.offset / 8] = vm->regs[src].i;
180 } break;
181 case OP_STLVARI: {
182 u8 dst = instruction.dst;
183 u8 src = instruction.a;
184 Variable var = vm->chunk->vars[dst];
185 vm->fp[var.offset / 8] = vm->chunk->constants[src].i;
186 } break;
187 case OP_LDLVAR: {
188 u8 dst = instruction.dst;
189 u8 src = instruction.a;
190 Variable var = vm->chunk->vars[src];
191 vm->regs[dst].i = vm->fp[var.offset / 8];
192 } break;
193 case OP_LDLADDR: {
194 u8 dst = instruction.dst;
195 u8 src = instruction.a;
196 Variable var = vm->chunk->vars[src];
197 vm->regs[dst].i = (ptrsize)&vm->fp[var.offset / 8];
198 } break;
199 case OP_LDSTR: {
200 u8 dst = instruction.dst;
201 u8 src = instruction.a;
202 Str *str = &vm->chunk->strings[src];
203 vm->regs[dst].ptr = (ptrsize)str;
204 } break;
157 case OP_ST64I: { 205 case OP_ST64I: {
158 sz value = vm->regs[instruction.dst].i; 206 sz value = vm->regs[instruction.dst].ptr;
159 s64 *addr = (s64 *)vm->regs[instruction.a].ptr; 207 s64 *addr = (s64 *)vm->regs[instruction.a].ptr;
160 sz offset = vm->chunk->constants[instruction.b].i; 208 sz offset = vm->chunk->constants[instruction.b].i;
161 addr[offset] = value; 209 addr[offset] = value;
@@ -166,6 +214,42 @@ vm_run(VM *vm) {
166 sz offset = vm->regs[instruction.b].i; 214 sz offset = vm->regs[instruction.b].i;
167 addr[offset] = value; 215 addr[offset] = value;
168 } break; 216 } break;
217 case OP_ST16I: {
218 sz value = vm->regs[instruction.dst].ptr;
219 s16 *addr = (s16 *)vm->regs[instruction.a].ptr;
220 sz offset = vm->chunk->constants[instruction.b].i;
221 addr[offset] = value;
222 } break;
223 case OP_ST16: {
224 sz value = vm->regs[instruction.dst].i;
225 s16 *addr = (s16 *)vm->regs[instruction.a].ptr;
226 sz offset = vm->regs[instruction.b].i;
227 addr[offset] = value;
228 } break;
229 case OP_ST8I: {
230 sz value = vm->regs[instruction.dst].ptr;
231 s8 *addr = (s8 *)vm->regs[instruction.a].ptr;
232 sz offset = vm->chunk->constants[instruction.b].i;
233 addr[offset] = value;
234 } break;
235 case OP_ST8: {
236 sz value = vm->regs[instruction.dst].i;
237 s8 *addr = (s8 *)vm->regs[instruction.a].ptr;
238 sz offset = vm->regs[instruction.b].i;
239 addr[offset] = value;
240 } break;
241 case OP_ST32I: {
242 sz value = vm->regs[instruction.dst].ptr;
243 s32 *addr = (s32 *)vm->regs[instruction.a].ptr;
244 sz offset = vm->chunk->constants[instruction.b].i;
245 addr[offset] = value;
246 } break;
247 case OP_ST32: {
248 sz value = vm->regs[instruction.dst].i;
249 s32 *addr = (s32 *)vm->regs[instruction.a].ptr;
250 sz offset = vm->regs[instruction.b].i;
251 addr[offset] = value;
252 } break;
169 case OP_LD64I: { 253 case OP_LD64I: {
170 s64 *addr = (s64 *)vm->regs[instruction.a].ptr; 254 s64 *addr = (s64 *)vm->regs[instruction.a].ptr;
171 sz offset = vm->chunk->constants[instruction.b].i; 255 sz offset = vm->chunk->constants[instruction.b].i;
@@ -176,19 +260,67 @@ vm_run(VM *vm) {
176 sz offset = vm->regs[instruction.b].i; 260 sz offset = vm->regs[instruction.b].i;
177 vm->regs[instruction.dst].i = addr[offset]; 261 vm->regs[instruction.dst].i = addr[offset];
178 } break; 262 } break;
179 case OP_STGVAR: { 263 case OP_LD32I: {
180 u8 dst = instruction.dst; 264 s32 *addr = (s32 *)vm->regs[instruction.a].ptr;
181 u8 src = instruction.a; 265 sz offset = vm->chunk->constants[instruction.b].i;
182 Variable var = vm->chunk->vars[dst]; 266 vm->regs[instruction.dst].i = addr[offset];
183 s64 *stack = (s64 *)&vm->stack[var.offset];
184 *stack = vm->regs[src].i;
185 } break; 267 } break;
186 case OP_STGVARI: { 268 case OP_LD32: {
187 u8 dst = instruction.dst; 269 s32 *addr = (s32 *)vm->regs[instruction.a].ptr;
188 u8 src = instruction.a; 270 sz offset = vm->regs[instruction.b].i;
189 Variable var = vm->chunk->vars[dst]; 271 vm->regs[instruction.dst].i = addr[offset];
190 s64 *stack = (s64 *)&vm->stack[var.offset]; 272 } break;
191 *stack = vm->chunk->constants[src].i; 273 case OP_LD16I: {
274 s16 *addr = (s16 *)vm->regs[instruction.a].ptr;
275 sz offset = vm->chunk->constants[instruction.b].i;
276 vm->regs[instruction.dst].i = addr[offset];
277 } break;
278 case OP_LD16: {
279 s16 *addr = (s16 *)vm->regs[instruction.a].ptr;
280 sz offset = vm->regs[instruction.b].i;
281 vm->regs[instruction.dst].i = addr[offset];
282 } break;
283 case OP_LD8I: {
284 s8 *addr = (s8 *)vm->regs[instruction.a].ptr;
285 sz offset = vm->chunk->constants[instruction.b].i;
286 vm->regs[instruction.dst].i = addr[offset];
287 } break;
288 case OP_LD8: {
289 s8 *addr = (s8 *)vm->regs[instruction.a].ptr;
290 sz offset = vm->regs[instruction.b].i;
291 vm->regs[instruction.dst].i = addr[offset];
292 } break;
293 case OP_LD8K: {
294 s8 *addr = (s8 *)vm->regs[instruction.a].ptr;
295 vm->regs[instruction.dst].i = *addr;
296 } break;
297 case OP_LD16K: {
298 s16 *addr = (s16 *)vm->regs[instruction.a].ptr;
299 vm->regs[instruction.dst].i = *addr;
300 } break;
301 case OP_LD32K: {
302 s32 *addr = (s32 *)vm->regs[instruction.a].ptr;
303 vm->regs[instruction.dst].i = *addr;
304 } break;
305 case OP_LD64K: {
306 s64 *addr = (s64 *)vm->regs[instruction.a].ptr;
307 vm->regs[instruction.dst].i = *addr;
308 } break;
309 case OP_ST8K: {
310 s8 *addr = (s8 *)vm->regs[instruction.a].ptr;
311 *addr = vm->regs[instruction.dst].i;
312 } break;
313 case OP_ST16K: {
314 s16 *addr = (s16 *)vm->regs[instruction.a].ptr;
315 *addr = vm->regs[instruction.dst].i;
316 } break;
317 case OP_ST32K: {
318 s32 *addr = (s32 *)vm->regs[instruction.a].ptr;
319 *addr = vm->regs[instruction.dst].i;
320 } break;
321 case OP_ST64K: {
322 s64 *addr = (s64 *)vm->regs[instruction.a].ptr;
323 *addr = vm->regs[instruction.dst].i;
192 } break; 324 } break;
193 case OP_JMP: { 325 case OP_JMP: {
194 u8 dst = instruction.dst; 326 u8 dst = instruction.dst;
@@ -247,14 +379,88 @@ vm_run(VM *vm) {
247 u8 src = instruction.a; 379 u8 src = instruction.a;
248 vm->regs[dst].i = vm->regs[src].i & 0xFF; 380 vm->regs[dst].i = vm->regs[src].i & 0xFF;
249 } break; 381 } break;
382 case OP_PRINTS8: {
383 u8 idx = instruction.dst;
384 print("%d", vm->regs[idx].i & 0xFF);
385 } break;
386 case OP_PRINTS16: {
387 u8 idx = instruction.dst;
388 print("%d", vm->regs[idx].i & 0xFFFF);
389 } break;
390 case OP_PRINTS32: {
391 u8 idx = instruction.dst;
392 print("%d", vm->regs[idx].i & 0xFFFFFFFF);
393 } break;
250 case OP_PRINTS64: { 394 case OP_PRINTS64: {
251 u8 idx = instruction.dst; 395 u8 idx = instruction.dst;
252 print("%d", vm->regs[idx].i); 396 print("%d", vm->regs[idx].i);
253 } break; 397 } break;
398 case OP_PRINTU8: {
399 u8 idx = instruction.dst;
400 print("%x", vm->regs[idx].u & 0xFF);
401 } break;
402 case OP_PRINTU16: {
403 u8 idx = instruction.dst;
404 print("%x", vm->regs[idx].u & 0xFFFF);
405 } break;
406 case OP_PRINTU32: {
407 u8 idx = instruction.dst;
408 print("%x", vm->regs[idx].u & 0xFFFFFFFF);
409 } break;
410 case OP_PRINTU64: {
411 u8 idx = instruction.dst;
412 print("%x", vm->regs[idx].u);
413 } break;
414 case OP_PRINTS8I: {
415 u8 idx = instruction.dst;
416 print("%d", vm->chunk->constants[idx].i & 0xFF);
417 } break;
418 case OP_PRINTS16I: {
419 u8 idx = instruction.dst;
420 print("%d", vm->chunk->constants[idx].i & 0xFFFF);
421 } break;
422 case OP_PRINTS32I: {
423 u8 idx = instruction.dst;
424 print("%d", vm->chunk->constants[idx].i & 0xFFFFFFFF);
425 } break;
254 case OP_PRINTS64I: { 426 case OP_PRINTS64I: {
255 u8 idx = instruction.dst; 427 u8 idx = instruction.dst;
256 print("%d", vm->chunk->constants[idx].i); 428 print("%d", vm->chunk->constants[idx].i);
257 } break; 429 } break;
430 case OP_PRINTU8I: {
431 u8 idx = instruction.dst;
432 print("%x", vm->chunk->constants[idx].u & 0xFF);
433 } break;
434 case OP_PRINTU16I: {
435 u8 idx = instruction.dst;
436 print("%x", vm->chunk->constants[idx].u & 0xFFFF);
437 } break;
438 case OP_PRINTU32I: {
439 u8 idx = instruction.dst;
440 print("%x", vm->chunk->constants[idx].u & 0xFFFFFFFF);
441 } break;
442 case OP_PRINTU64I: {
443 u8 idx = instruction.dst;
444 print("%x", vm->chunk->constants[idx].u);
445 } break;
446 case OP_PRINTBOOL: {
447 u8 idx = instruction.dst;
448 bool val = vm->regs[idx].i;
449 if (val) {
450 print("true");
451 } else {
452 print("false");
453 }
454 } break;
455 case OP_PRINTBOOLI: {
456 u8 idx = instruction.dst;
457 bool val = vm->chunk->constants[idx].i;
458 if (val) {
459 print("true");
460 } else {
461 print("false");
462 }
463 } break;
258 case OP_PRINTF64: { 464 case OP_PRINTF64: {
259 u8 idx = instruction.dst; 465 u8 idx = instruction.dst;
260 printf("%f", vm->regs[idx].f); 466 printf("%f", vm->regs[idx].f);
@@ -265,6 +471,11 @@ vm_run(VM *vm) {
265 } break; 471 } break;
266 case OP_PRINTSTR: { 472 case OP_PRINTSTR: {
267 u8 idx = instruction.dst; 473 u8 idx = instruction.dst;
474 Str *string = (Str *)vm->regs[idx].ptr;
475 print("%s", *string);
476 } break;
477 case OP_PRINTSTRI: {
478 u8 idx = instruction.dst;
268 Str string = vm->chunk->strings[idx]; 479 Str string = vm->chunk->strings[idx];
269 print("%s", string); 480 print("%s", string);
270 } break; 481 } break;
@@ -299,7 +510,7 @@ vm_run(VM *vm) {
299 } break; 510 } break;
300 case OP_CALL: { 511 case OP_CALL: {
301 u8 dst = instruction.dst; 512 u8 dst = instruction.dst;
302 Chunk *func = vm->chunk->functions[dst]; 513 Chunk *func = vm->main->functions[dst];
303 514
304 ptrsize chunk_addr = (ptrsize)vm->chunk; 515 ptrsize chunk_addr = (ptrsize)vm->chunk;
305 ptrsize ip_addr = (ptrsize)vm->ip; 516 ptrsize ip_addr = (ptrsize)vm->ip;
@@ -307,8 +518,9 @@ vm_run(VM *vm) {
307 ptrsize old_fp = (ptrsize)vm->fp; 518 ptrsize old_fp = (ptrsize)vm->fp;
308 519
309 // Allocate space for the locals. 520 // Allocate space for the locals.
310 vm->fp = (u64 *)vm->sp; 521 memset(vm->sp, 0, func->var_off - func->param_off);
311 vm->sp += func->var_off; // FIXME: - func->n_params! 522 vm->fp = (u64 *)(vm->sp - func->param_off);
523 vm->sp += func->var_off - func->param_off;
312 vm->chunk = func; 524 vm->chunk = func;
313 vm->ip = func->code; 525 vm->ip = func->code;
314 vm->regs = (Constant *)vm->sp; 526 vm->regs = (Constant *)vm->sp;
@@ -324,6 +536,9 @@ vm_run(VM *vm) {
324 p[3] = old_fp; 536 p[3] = old_fp;
325 vm->sp += sizeof(ptrsize) * 4; 537 vm->sp += sizeof(ptrsize) * 4;
326 } break; 538 } break;
539 case OP_RECUR: {
540 vm->ip = vm->chunk->code;
541 } break;
327 case OP_RET: { 542 case OP_RET: {
328 u64 *p = (u64 *)vm->sp; 543 u64 *p = (u64 *)vm->sp;
329 ptrsize chunk_addr = p[-4]; 544 ptrsize chunk_addr = p[-4];