diff options
-rw-r--r-- | src/compiler.c | 209 | ||||
-rw-r--r-- | src/main.c | 10 | ||||
-rw-r--r-- | src/parser.c | 1 | ||||
-rw-r--r-- | src/semantic.c | 9 | ||||
-rw-r--r-- | src/vm.c | 136 | ||||
-rw-r--r-- | tests/compilation.bad | 7 |
6 files changed, 246 insertions, 126 deletions
diff --git a/src/compiler.c b/src/compiler.c index e303cee..04afd5d 100644 --- a/src/compiler.c +++ b/src/compiler.c | |||
@@ -5,6 +5,15 @@ | |||
5 | 5 | ||
6 | #include "parser.c" | 6 | #include "parser.c" |
7 | 7 | ||
8 | typedef struct Variable { | ||
9 | Str name; | ||
10 | Str type; | ||
11 | sz size; | ||
12 | sz offset; | ||
13 | } Variable; | ||
14 | |||
15 | MAPDEF(StrVarMap, varmap, Str, Variable, str_hash, str_eq) | ||
16 | |||
8 | typedef struct Instruction { | 17 | typedef struct Instruction { |
9 | u8 dst; | 18 | u8 dst; |
10 | u8 a; | 19 | u8 a; |
@@ -33,6 +42,11 @@ typedef struct Chunk { | |||
33 | StrIntMap *strmap; | 42 | StrIntMap *strmap; |
34 | sz str_idx; | 43 | sz str_idx; |
35 | 44 | ||
45 | // Global/Local variables. | ||
46 | Variable *vars; | ||
47 | StrVarMap *varmap; | ||
48 | sz var_off; | ||
49 | |||
36 | // Number of registers currently used in this chunk. | 50 | // Number of registers currently used in this chunk. |
37 | sz reg_idx; | 51 | sz reg_idx; |
38 | 52 | ||
@@ -46,7 +60,9 @@ typedef enum OpCode { | |||
46 | // OP DST A B | 60 | // OP DST A B |
47 | // --------------------------------------------------------------- | 61 | // --------------------------------------------------------------- |
48 | // VM/high level instructions. | 62 | // VM/high level instructions. |
49 | OP_HALT, // halt | 63 | OP_HALT, // halt |
64 | OP_STVARI, // stvari vx, ca | ||
65 | OP_STVAR, // stvar vx, ra | ||
50 | // Load/Store instructions. | 66 | // Load/Store instructions. |
51 | OP_LD8K, // ld8k rx, ca -> u8 rx = ca | 67 | OP_LD8K, // ld8k rx, ca -> u8 rx = ca |
52 | OP_LD16K, // ld16k rx, ca -> u16 rx = ca | 68 | OP_LD16K, // ld16k rx, ca -> u16 rx = ca |
@@ -129,6 +145,8 @@ typedef enum OpCode { | |||
129 | 145 | ||
130 | Str op_str[] = { | 146 | Str op_str[] = { |
131 | [OP_HALT] = cstr("HALT "), | 147 | [OP_HALT] = cstr("HALT "), |
148 | [OP_STVAR] = cstr("STVAR "), | ||
149 | [OP_STVARI] = cstr("STVARI "), | ||
132 | // Load ops. | 150 | // Load ops. |
133 | [OP_LD8K] = cstr("LD8K "), | 151 | [OP_LD8K] = cstr("LD8K "), |
134 | [OP_LD16K] = cstr("LD16K "), | 152 | [OP_LD16K] = cstr("LD16K "), |
@@ -210,6 +228,7 @@ Str op_str[] = { | |||
210 | }; | 228 | }; |
211 | 229 | ||
212 | typedef enum { | 230 | typedef enum { |
231 | COMP_NIL, | ||
213 | COMP_CONST, | 232 | COMP_CONST, |
214 | COMP_STRING, | 233 | COMP_STRING, |
215 | COMP_REG, | 234 | COMP_REG, |
@@ -464,6 +483,54 @@ compile_expr(Chunk *chunk, Node *node) { | |||
464 | .idx = map->val, | 483 | .idx = map->val, |
465 | }; | 484 | }; |
466 | } break; | 485 | } break; |
486 | case NODE_LET: { | ||
487 | sz idx = array_size(chunk->vars); | ||
488 | Str name = node->unique_name; | ||
489 | Str type = node->var_name->type; | ||
490 | sz size = 8; | ||
491 | // TODO: get type storage from a table to consider all the basic | ||
492 | // types as well as user defined ones. | ||
493 | if (str_eq(type, cstr("str"))) { | ||
494 | size = 16; | ||
495 | } | ||
496 | Variable var = (Variable){ | ||
497 | .name = name, | ||
498 | .type = type, | ||
499 | .size = size, | ||
500 | .offset = chunk->var_off, | ||
501 | }; | ||
502 | varmap_insert(&chunk->varmap, name, var, chunk->storage); | ||
503 | array_push(chunk->vars, var, chunk->storage); | ||
504 | chunk->var_off += size; | ||
505 | |||
506 | // Value. | ||
507 | if (node->var_val) { | ||
508 | CompResult res = compile_expr(chunk, node->var_val); | ||
509 | switch (res.type) { | ||
510 | case COMP_CONST: { | ||
511 | EMIT_OP(OP_STVARI, idx, res.idx, 0, node->var_val, | ||
512 | chunk); | ||
513 | } break; | ||
514 | case COMP_REG: { | ||
515 | EMIT_OP(OP_STVAR, idx, res.idx, 0, node->var_val, | ||
516 | chunk); | ||
517 | } break; | ||
518 | default: { | ||
519 | return (CompResult){.type = COMP_ERR}; | ||
520 | } break; | ||
521 | } | ||
522 | } | ||
523 | |||
524 | return (CompResult){.type = COMP_NIL}; | ||
525 | } break; | ||
526 | case NODE_BLOCK: { | ||
527 | CompResult res; | ||
528 | for (sz i = 0; i < array_size(node->elements); i++) { | ||
529 | Node *root = node->elements[i]; | ||
530 | res = compile_expr(chunk, root); | ||
531 | } | ||
532 | return res; | ||
533 | } break; | ||
467 | default: { | 534 | default: { |
468 | eprintln("error: compilation not implemented for node %s", | 535 | eprintln("error: compilation not implemented for node %s", |
469 | node_str[node->kind]); | 536 | node_str[node->kind]); |
@@ -473,4 +540,144 @@ compile_expr(Chunk *chunk, Node *node) { | |||
473 | return (CompResult){.type = COMP_ERR}; | 540 | return (CompResult){.type = COMP_ERR}; |
474 | } | 541 | } |
475 | 542 | ||
543 | void | ||
544 | disassemble_instruction(Instruction instruction) { | ||
545 | switch (instruction.op) { | ||
546 | case OP_MOV8: | ||
547 | case OP_MOV16: | ||
548 | case OP_MOV32: | ||
549 | case OP_MOV64: | ||
550 | println("%s r%d, r%d", op_str[instruction.op], instruction.dst, | ||
551 | instruction.a, instruction.b); | ||
552 | break; | ||
553 | case OP_LD8K: | ||
554 | case OP_LD16K: | ||
555 | case OP_LD32K: | ||
556 | case OP_LD64K: | ||
557 | println("%s r%d, c%d", op_str[instruction.op], instruction.dst, | ||
558 | instruction.a, instruction.b); | ||
559 | break; | ||
560 | case OP_LD8I: | ||
561 | case OP_LD16I: | ||
562 | case OP_LD32I: | ||
563 | case OP_LD64I: | ||
564 | case OP_ST8I: | ||
565 | case OP_ST16I: | ||
566 | case OP_ST32I: | ||
567 | case OP_ST64I: | ||
568 | case OP_ADDI: | ||
569 | case OP_SUBI: | ||
570 | case OP_MULI: | ||
571 | case OP_DIVI: | ||
572 | case OP_MODI: | ||
573 | case OP_ADDFI: | ||
574 | case OP_SUBFI: | ||
575 | case OP_MULFI: | ||
576 | case OP_DIVFI: | ||
577 | case OP_MODFI: | ||
578 | case OP_EQI: | ||
579 | case OP_NEQI: | ||
580 | case OP_LTI: | ||
581 | case OP_GTI: | ||
582 | case OP_LEI: | ||
583 | case OP_GEI: | ||
584 | case OP_ANDI: | ||
585 | case OP_ORI: | ||
586 | case OP_BITLSHIFTI: | ||
587 | case OP_BITRSHIFTI: | ||
588 | case OP_BITANDI: | ||
589 | case OP_BITORI: | ||
590 | println("%s r%d, r%d, c%d", op_str[instruction.op], instruction.dst, | ||
591 | instruction.a, instruction.b); | ||
592 | break; | ||
593 | case OP_LD8: | ||
594 | case OP_LD16: | ||
595 | case OP_LD32: | ||
596 | case OP_LD64: | ||
597 | case OP_ST8: | ||
598 | case OP_ST16: | ||
599 | case OP_ST32: | ||
600 | case OP_ST64: | ||
601 | case OP_ADD: | ||
602 | case OP_SUB: | ||
603 | case OP_MUL: | ||
604 | case OP_DIV: | ||
605 | case OP_MOD: | ||
606 | case OP_ADDF: | ||
607 | case OP_SUBF: | ||
608 | case OP_MULF: | ||
609 | case OP_DIVF: | ||
610 | case OP_MODF: | ||
611 | case OP_EQ: | ||
612 | case OP_NEQ: | ||
613 | case OP_LT: | ||
614 | case OP_GT: | ||
615 | case OP_LE: | ||
616 | case OP_GE: | ||
617 | case OP_AND: | ||
618 | case OP_OR: | ||
619 | case OP_BITLSHIFT: | ||
620 | case OP_BITRSHIFT: | ||
621 | case OP_BITAND: | ||
622 | case OP_BITOR: | ||
623 | println("%s r%d, r%d, r%d", op_str[instruction.op], instruction.dst, | ||
624 | instruction.a, instruction.b); | ||
625 | break; | ||
626 | case OP_STVAR: | ||
627 | println("%s v%d, r%d", op_str[instruction.op], instruction.dst, | ||
628 | instruction.a, instruction.b); | ||
629 | break; | ||
630 | case OP_STVARI: | ||
631 | println("%s v%d, c%d", op_str[instruction.op], instruction.dst, | ||
632 | instruction.a, instruction.b); | ||
633 | break; | ||
634 | case OP_BITNOTI: | ||
635 | case OP_NOTI: | ||
636 | println("%s r%d, c%d", op_str[instruction.op], instruction.dst, | ||
637 | instruction.a, instruction.b); | ||
638 | break; | ||
639 | case OP_BITNOT: | ||
640 | case OP_NOT: | ||
641 | println("%s r%d, r%d", op_str[instruction.op], instruction.dst, | ||
642 | instruction.a, instruction.b); | ||
643 | break; | ||
644 | case OP_HALT: println("%s", op_str[instruction.op]); break; | ||
645 | default: println("Unknown opcode %d", instruction.op); break; | ||
646 | } | ||
647 | } | ||
648 | |||
649 | void | ||
650 | disassemble_chunk(Chunk chunk) { | ||
651 | println("%s: =========== code ===========", chunk.file_name); | ||
652 | for (sz i = 0; i < array_size(chunk.code); i++) { | ||
653 | print("%s: %x{4}: ", chunk.file_name, i); | ||
654 | disassemble_instruction(chunk.code[i]); | ||
655 | } | ||
656 | if (array_size(chunk.constants) > 0) { | ||
657 | println("%s: ========= constants ========", chunk.file_name); | ||
658 | for (sz i = 0; i < array_size(chunk.constants); i++) { | ||
659 | println("%s: %x{2}: %x{8}", chunk.file_name, i, | ||
660 | chunk.constants[i]); | ||
661 | } | ||
662 | } | ||
663 | if (array_size(chunk.strings) > 0) { | ||
664 | println("%s: ========== strings =========", chunk.file_name); | ||
665 | for (sz i = 0; i < array_size(chunk.strings); i++) { | ||
666 | println("%s: %x{2}: %s", chunk.file_name, i, chunk.strings[i]); | ||
667 | } | ||
668 | } | ||
669 | if (array_size(chunk.vars) > 0) { | ||
670 | println("%s: ========= variables ========", chunk.file_name); | ||
671 | for (sz i = 0; i < array_size(chunk.vars); i++) { | ||
672 | println("%s: %x{2}: [%x{4}:%x{4}] %s: %s", chunk.file_name, i, | ||
673 | chunk.vars[i].offset, | ||
674 | chunk.vars[i].offset + chunk.vars[i].size, | ||
675 | chunk.vars[i].name, chunk.vars[i].type); | ||
676 | } | ||
677 | } | ||
678 | println("n_regs: %d, n_vars: %d, n_strings: %d, n_consts: %d", | ||
679 | chunk.reg_idx, array_size(chunk.vars), chunk.str_idx, | ||
680 | chunk.const_idx); | ||
681 | } | ||
682 | |||
476 | #endif // COMPILER_C | 683 | #endif // COMPILER_C |
@@ -176,6 +176,10 @@ process_file(Str path) { | |||
176 | // The parser stores the root nodes as a stack. | 176 | // The parser stores the root nodes as a stack. |
177 | Node *root = parser.nodes[i]; | 177 | Node *root = parser.nodes[i]; |
178 | res = compile_expr(&chunk, root); | 178 | res = compile_expr(&chunk, root); |
179 | if (res.type == COMP_ERR) { | ||
180 | eprintln("compilation error..."); | ||
181 | exit(EXIT_FAILURE); | ||
182 | } | ||
179 | } | 183 | } |
180 | sz res_reg = 0; | 184 | sz res_reg = 0; |
181 | switch (res.type) { | 185 | switch (res.type) { |
@@ -215,8 +219,10 @@ process_file(Str path) { | |||
215 | // println("VM REGISTERS BEFORE:\n%{Mem}", | 219 | // println("VM REGISTERS BEFORE:\n%{Mem}", |
216 | // &(Array){.mem = (u8 *)&vm.regs, sizeof(vm.regs)}); | 220 | // &(Array){.mem = (u8 *)&vm.regs, sizeof(vm.regs)}); |
217 | vm_run(&vm); | 221 | vm_run(&vm); |
218 | // println("VM REGISTERS AFTER:\n%{Mem}", | 222 | println("VM REGISTERS AFTER:\n%{Mem}", |
219 | // &(Array){.mem = (u8 *)&vm.regs, sizeof(vm.regs)}); | 223 | &(Array){.mem = (u8 *)&vm.regs, sizeof(vm.regs)}); |
224 | println("VM MEMORY AFTER:\n%{Mem}", | ||
225 | &(Array){.mem = (u8 *)&vm.stack, sizeof(vm.stack)}); | ||
220 | 226 | ||
221 | #if DEBUG == 1 | 227 | #if DEBUG == 1 |
222 | println("Space used: %{Arena}", &lexer_arena); | 228 | println("Space used: %{Arena}", &lexer_arena); |
diff --git a/src/parser.c b/src/parser.c index f7d0d41..90adaf3 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -197,6 +197,7 @@ typedef struct Node { | |||
197 | Str type; | 197 | Str type; |
198 | Str fun_params; | 198 | Str fun_params; |
199 | Str fun_return; | 199 | Str fun_return; |
200 | Str unique_name; | ||
200 | } Node; | 201 | } Node; |
201 | 202 | ||
202 | // | 203 | // |
diff --git a/src/semantic.c b/src/semantic.c index 7158052..1b40723 100644 --- a/src/semantic.c +++ b/src/semantic.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #define SEMANTIC_C | 2 | #define SEMANTIC_C |
3 | 3 | ||
4 | #include "badlib.h" | 4 | #include "badlib.h" |
5 | #include "parser.c" | ||
5 | 6 | ||
6 | typedef enum { | 7 | typedef enum { |
7 | SYM_UNKNOWN, | 8 | SYM_UNKNOWN, |
@@ -514,6 +515,10 @@ type_inference(Analyzer *a, Node *node, Scope *scope) { | |||
514 | a->storage); | 515 | a->storage); |
515 | node->var_name->type = type; | 516 | node->var_name->type = type; |
516 | } | 517 | } |
518 | symbol = str_concat(cstr("."), symbol, a->storage); | ||
519 | symbol = str_concat(symbol, str_from_int(scope->id, a->storage), | ||
520 | a->storage); | ||
521 | node->unique_name = symbol; | ||
517 | return node->type; | 522 | return node->type; |
518 | } break; | 523 | } break; |
519 | case NODE_SET: { | 524 | case NODE_SET: { |
@@ -843,7 +848,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) { | |||
843 | node->type = cstr("str"); | 848 | node->type = cstr("str"); |
844 | return node->type; | 849 | return node->type; |
845 | } break; | 850 | } break; |
846 | case NODE_ARR_TYPE: | 851 | case NODE_ARR_TYPE: |
847 | case NODE_TYPE: { | 852 | case NODE_TYPE: { |
848 | SymbolMap *type = find_type(scope, node->value.str); | 853 | SymbolMap *type = find_type(scope, node->value.str); |
849 | if (!type) { | 854 | if (!type) { |
@@ -1235,4 +1240,4 @@ symbolic_analysis(Analyzer *a, Parser *parser) { | |||
1235 | } | 1240 | } |
1236 | } | 1241 | } |
1237 | 1242 | ||
1238 | #endif // SEMANTIC_C | 1243 | #endif // SEMANTIC_C |
@@ -4,130 +4,12 @@ | |||
4 | #include "badlib.h" | 4 | #include "badlib.h" |
5 | #include "compiler.c" | 5 | #include "compiler.c" |
6 | 6 | ||
7 | void | ||
8 | disassemble_instruction(Instruction instruction) { | ||
9 | switch (instruction.op) { | ||
10 | case OP_MOV8: | ||
11 | case OP_MOV16: | ||
12 | case OP_MOV32: | ||
13 | case OP_MOV64: | ||
14 | println("%s r%d, r%d", op_str[instruction.op], instruction.dst, | ||
15 | instruction.a, instruction.b); | ||
16 | break; | ||
17 | case OP_LD8K: | ||
18 | case OP_LD16K: | ||
19 | case OP_LD32K: | ||
20 | case OP_LD64K: | ||
21 | println("%s r%d, c%d", op_str[instruction.op], instruction.dst, | ||
22 | instruction.a, instruction.b); | ||
23 | break; | ||
24 | case OP_LD8I: | ||
25 | case OP_LD16I: | ||
26 | case OP_LD32I: | ||
27 | case OP_LD64I: | ||
28 | case OP_ST8I: | ||
29 | case OP_ST16I: | ||
30 | case OP_ST32I: | ||
31 | case OP_ST64I: | ||
32 | case OP_ADDI: | ||
33 | case OP_SUBI: | ||
34 | case OP_MULI: | ||
35 | case OP_DIVI: | ||
36 | case OP_MODI: | ||
37 | case OP_ADDFI: | ||
38 | case OP_SUBFI: | ||
39 | case OP_MULFI: | ||
40 | case OP_DIVFI: | ||
41 | case OP_MODFI: | ||
42 | case OP_EQI: | ||
43 | case OP_NEQI: | ||
44 | case OP_LTI: | ||
45 | case OP_GTI: | ||
46 | case OP_LEI: | ||
47 | case OP_GEI: | ||
48 | case OP_ANDI: | ||
49 | case OP_ORI: | ||
50 | case OP_BITLSHIFTI: | ||
51 | case OP_BITRSHIFTI: | ||
52 | case OP_BITANDI: | ||
53 | case OP_BITORI: | ||
54 | println("%s r%d, r%d, c%d", op_str[instruction.op], instruction.dst, | ||
55 | instruction.a, instruction.b); | ||
56 | break; | ||
57 | case OP_LD8: | ||
58 | case OP_LD16: | ||
59 | case OP_LD32: | ||
60 | case OP_LD64: | ||
61 | case OP_ST8: | ||
62 | case OP_ST16: | ||
63 | case OP_ST32: | ||
64 | case OP_ST64: | ||
65 | case OP_ADD: | ||
66 | case OP_SUB: | ||
67 | case OP_MUL: | ||
68 | case OP_DIV: | ||
69 | case OP_MOD: | ||
70 | case OP_ADDF: | ||
71 | case OP_SUBF: | ||
72 | case OP_MULF: | ||
73 | case OP_DIVF: | ||
74 | case OP_MODF: | ||
75 | case OP_EQ: | ||
76 | case OP_NEQ: | ||
77 | case OP_LT: | ||
78 | case OP_GT: | ||
79 | case OP_LE: | ||
80 | case OP_GE: | ||
81 | case OP_AND: | ||
82 | case OP_OR: | ||
83 | case OP_BITLSHIFT: | ||
84 | case OP_BITRSHIFT: | ||
85 | case OP_BITAND: | ||
86 | case OP_BITOR: | ||
87 | println("%s r%d, r%d, r%d", op_str[instruction.op], instruction.dst, | ||
88 | instruction.a, instruction.b); | ||
89 | break; | ||
90 | case OP_BITNOTI: | ||
91 | case OP_NOTI: | ||
92 | println("%s r%d, c%d", op_str[instruction.op], instruction.dst, | ||
93 | instruction.a, instruction.b); | ||
94 | break; | ||
95 | case OP_BITNOT: | ||
96 | case OP_NOT: | ||
97 | println("%s r%d, r%d", op_str[instruction.op], instruction.dst, | ||
98 | instruction.a, instruction.b); | ||
99 | break; | ||
100 | case OP_HALT: println("%s", op_str[instruction.op]); break; | ||
101 | default: println("Unknown opcode %d", instruction.op); break; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | void | ||
106 | disassemble_chunk(Chunk chunk) { | ||
107 | println("%s: =========== code ===========", chunk.file_name); | ||
108 | for (sz i = 0; i < array_size(chunk.code); i++) { | ||
109 | print("%s: %x{4}: ", chunk.file_name, i); | ||
110 | disassemble_instruction(chunk.code[i]); | ||
111 | } | ||
112 | if (array_size(chunk.constants) > 0) { | ||
113 | println("%s: ========= constants ========", chunk.file_name); | ||
114 | for (sz i = 0; i < array_size(chunk.constants); i++) { | ||
115 | println("%s: %x{2}: %x{8}", chunk.file_name, i, | ||
116 | chunk.constants[i]); | ||
117 | } | ||
118 | } | ||
119 | if (array_size(chunk.strings) > 0) { | ||
120 | println("%s: ========== strings =========", chunk.file_name); | ||
121 | for (sz i = 0; i < array_size(chunk.strings); i++) { | ||
122 | println("%s: %x{2}: %s", chunk.file_name, i, chunk.strings[i]); | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | |||
127 | #define N_CONST 256 | 7 | #define N_CONST 256 |
8 | #define STACK_SIZE KB(64) | ||
128 | typedef struct VM { | 9 | typedef struct VM { |
129 | Chunk *chunk; | 10 | Chunk *chunk; |
130 | Constant regs[N_CONST]; | 11 | Constant regs[N_CONST]; |
12 | u8 stack[STACK_SIZE]; | ||
131 | Instruction *ip; | 13 | Instruction *ip; |
132 | } VM; | 14 | } VM; |
133 | 15 | ||
@@ -252,6 +134,20 @@ vm_run(VM *vm) { | |||
252 | vm->regs[dst].f = | 134 | vm->regs[dst].f = |
253 | fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f); | 135 | fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f); |
254 | } break; | 136 | } break; |
137 | case OP_STVAR: { | ||
138 | u8 dst = instruction.dst; | ||
139 | u8 src = instruction.a; | ||
140 | Variable var = vm->chunk->vars[dst]; | ||
141 | s64 *stack = (s64*)&vm->stack[var.offset]; | ||
142 | *stack = vm->regs[src].i; | ||
143 | } break; | ||
144 | case OP_STVARI: { | ||
145 | u8 dst = instruction.dst; | ||
146 | u8 src = instruction.a; | ||
147 | Variable var = vm->chunk->vars[dst]; | ||
148 | s64 *stack = (s64*)&vm->stack[var.offset]; | ||
149 | *stack = vm->chunk->constants[src].i; | ||
150 | } break; | ||
255 | case OP_HALT: { | 151 | case OP_HALT: { |
256 | println("VM HALT (int) -> %d", vm->regs[instruction.dst]); | 152 | println("VM HALT (int) -> %d", vm->regs[instruction.dst]); |
257 | println("VM HALT (float) -> %f", vm->regs[instruction.dst]); | 153 | println("VM HALT (float) -> %f", vm->regs[instruction.dst]); |
diff --git a/tests/compilation.bad b/tests/compilation.bad index 9042242..120c020 100644 --- a/tests/compilation.bad +++ b/tests/compilation.bad | |||
@@ -1,8 +1,13 @@ | |||
1 | let a = 8 | ||
2 | { | ||
3 | let a = 1 + 2 * 4 | ||
4 | let b = 3.0 | ||
5 | } | ||
1 | ; 0xf | 0xf0 | 6 | ; 0xf | 0xf0 |
2 | ; 0xf & 0xff | 7 | ; 0xf & 0xff |
3 | ; 0x1 << 2 | 8 | ; 0x1 << 2 |
4 | ; 0x1 << 2 | 9 | ; 0x1 << 2 |
5 | ~0xf & 0xfff | 10 | ; (~0xf & 0xfff << 8) == 0xfff00 |
6 | ; 0xf << 4 | 0xf | 11 | ; 0xf << 4 | 0xf |
7 | ; 1 + 2 | 12 | ; 1 + 2 |
8 | ; 1 < 2 | 13 | ; 1 < 2 |