diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-24 09:52:09 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-24 09:52:09 +0200 |
commit | b743e03fc6042e3e2d55cfa0387c092824de64c5 (patch) | |
tree | 1c74213017e20fc5bf675f571de2a264cf104cd3 | |
parent | f372586069ea0a92db65bc90cf844c1a35187430 (diff) | |
download | bdl-b743e03fc6042e3e2d55cfa0387c092824de64c5.tar.gz bdl-b743e03fc6042e3e2d55cfa0387c092824de64c5.zip |
Add print/display/newline ops
-rw-r--r-- | examples/arithmetic.bdl | 58 | ||||
-rwxr-xr-x | src/bytecode/compiler.h | 103 | ||||
-rwxr-xr-x | src/bytecode/debug.h | 35 | ||||
-rwxr-xr-x | src/bytecode/lexer.c | 6 | ||||
-rwxr-xr-x | src/bytecode/lexer.h | 3 | ||||
-rwxr-xr-x | src/bytecode/main.c | 2 | ||||
-rwxr-xr-x | src/bytecode/ops.h | 9 | ||||
-rwxr-xr-x | src/bytecode/vm.h | 31 |
8 files changed, 192 insertions, 55 deletions
diff --git a/examples/arithmetic.bdl b/examples/arithmetic.bdl index c3ff230..c313dbb 100644 --- a/examples/arithmetic.bdl +++ b/examples/arithmetic.bdl | |||
@@ -3,26 +3,58 @@ | |||
3 | ;; | 3 | ;; |
4 | 4 | ||
5 | ;; Addition. | 5 | ;; Addition. |
6 | (print "(+ 10 100) -> ") (+ 10 100) | 6 | (print "(+ 10 100) -> ") |
7 | (print "(+ 1 -2 3 4) -> ") (+ 1 -2 3 4) | 7 | (display (+ 10 100)) |
8 | (newline) | ||
9 | |||
10 | (print "(+ 1 -2 3 4) -> ") | ||
11 | (display (+ 1 -2 3 4)) | ||
12 | (newline) | ||
8 | 13 | ||
9 | ;; Substraction. | 14 | ;; Substraction. |
10 | (print "(- 100 75) -> ") (- 100 75) | 15 | (print "(- 100 75) -> ") |
11 | (print "(- 10 20 30) -> ") (- 10 20 30) | 16 | (display (- 100 75)) |
17 | (newline) | ||
18 | |||
19 | (print "(- 10 20 30) -> ") | ||
20 | (display (- 10 20 30)) | ||
21 | (newline) | ||
12 | 22 | ||
13 | ;; Multiplication. | 23 | ;; Multiplication. |
14 | (print "(* 10 7) -> ") (* 10 7) | 24 | (print "(* 10 7) -> ") |
15 | (print "(* -1 66) -> ") (* -1 66) | 25 | (display (* 10 7)) |
26 | (newline) | ||
27 | |||
28 | (print "(* -1 66) -> ") | ||
29 | (display (* -1 66)) | ||
30 | (newline) | ||
16 | 31 | ||
17 | ;; Division. | 32 | ;; Division. |
18 | (print "(/ 45 5) -> ") (/ 45 5) | 33 | (print "(/ 45 5) -> ") |
19 | (print "(/ 10 5 2) -> ") (/ 10 5 2) | 34 | (display (/ 45 5)) |
35 | (newline) | ||
36 | |||
37 | (print "(/ 10 5 2) -> ") | ||
38 | (display (/ 10 5 2)) | ||
39 | (newline) | ||
20 | 40 | ||
21 | ;; Remainder/modulo. | 41 | ;; Remainder/modulo. |
22 | (print "(% 45 5) -> ") (% 45 5) | 42 | (print "(% 45 5) -> ") |
23 | (print "(% 45 7) -> ") (% 45 7) | 43 | (display (% 45 5)) |
24 | (print "(% 120 45) -> ") (% 120 45) | 44 | (newline) |
25 | (print "(% 120 45 8) -> ") (% 120 45 8) | 45 | |
46 | (print "(% 45 7) -> ") | ||
47 | (display (% 45 7)) | ||
48 | (newline) | ||
49 | |||
50 | (print "(% 120 45) -> ") | ||
51 | (display (% 120 45)) | ||
52 | (newline) | ||
53 | |||
54 | (print "(% 120 45 8) -> ") | ||
55 | (display (% 120 45 8)) | ||
56 | (newline) | ||
26 | 57 | ||
27 | ;; Nesting operations. | 58 | ;; Nesting operations. |
28 | (print "(* 20 (+ 100 (- 50 30) (/ 300 3)) 10) -> ") (* 20 (+ 100 (- 50 30) (/ 300 3)) 10) | 59 | (print "(* 20 (+ 100 (- 50 30) (/ 300 3)) 10) -> ") |
60 | (display (* 20 (+ 100 (- 50 30) (/ 300 3)) 10)) | ||
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h index 02d938f..d404a5a 100755 --- a/src/bytecode/compiler.h +++ b/src/bytecode/compiler.h | |||
@@ -58,7 +58,7 @@ parse_fixnum(Chunk *chunk, Token tok) { | |||
58 | void parse_tree(Chunk *chunk, Visitor *vs); | 58 | void parse_tree(Chunk *chunk, Visitor *vs); |
59 | 59 | ||
60 | void | 60 | void |
61 | compile_list_binary_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) { | 61 | compile_list_binary_op(Chunk *chunk, Visitor *vs, Token start, Ops op) { |
62 | size_t n = 0; | 62 | size_t n = 0; |
63 | while (has_next_token(vs)) { | 63 | while (has_next_token(vs)) { |
64 | Token tok = peek_token(vs); | 64 | Token tok = peek_token(vs); |
@@ -66,8 +66,8 @@ compile_list_binary_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) { | |||
66 | error_push((Error){ | 66 | error_push((Error){ |
67 | .type = ERR_TYPE_COMPILER, | 67 | .type = ERR_TYPE_COMPILER, |
68 | .value = ERR_UNBALANCED_PAREN, | 68 | .value = ERR_UNBALANCED_PAREN, |
69 | .line = list_start.line, | 69 | .line = start.line, |
70 | .col = list_start.column, | 70 | .col = start.column, |
71 | }); | 71 | }); |
72 | return; | 72 | return; |
73 | } | 73 | } |
@@ -77,8 +77,8 @@ compile_list_binary_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) { | |||
77 | error_push((Error){ | 77 | error_push((Error){ |
78 | .type = ERR_TYPE_COMPILER, | 78 | .type = ERR_TYPE_COMPILER, |
79 | .value = ERR_NOT_ENOUGH_ARGS, | 79 | .value = ERR_NOT_ENOUGH_ARGS, |
80 | .line = list_start.line, | 80 | .line = start.line, |
81 | .col = list_start.column, | 81 | .col = start.column, |
82 | }); | 82 | }); |
83 | return; | 83 | return; |
84 | } | 84 | } |
@@ -87,12 +87,12 @@ compile_list_binary_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) { | |||
87 | parse_tree(chunk, vs); | 87 | parse_tree(chunk, vs); |
88 | n++; | 88 | n++; |
89 | } | 89 | } |
90 | emit_constant(chunk, list_start, FIXNUM_VAL(n)); | 90 | emit_constant(chunk, start, FIXNUM_VAL(n)); |
91 | add_code(chunk, op, list_start.line, list_start.column); | 91 | add_code(chunk, op, start.line, start.column); |
92 | } | 92 | } |
93 | 93 | ||
94 | void | 94 | void |
95 | compile_list_unary_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) { | 95 | compile_list_unary_op(Chunk *chunk, Visitor *vs, Token start, Ops op) { |
96 | size_t n = 0; | 96 | size_t n = 0; |
97 | while (has_next_token(vs)) { | 97 | while (has_next_token(vs)) { |
98 | Token tok = peek_token(vs); | 98 | Token tok = peek_token(vs); |
@@ -100,8 +100,8 @@ compile_list_unary_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) { | |||
100 | error_push((Error){ | 100 | error_push((Error){ |
101 | .type = ERR_TYPE_COMPILER, | 101 | .type = ERR_TYPE_COMPILER, |
102 | .value = ERR_UNBALANCED_PAREN, | 102 | .value = ERR_UNBALANCED_PAREN, |
103 | .line = list_start.line, | 103 | .line = start.line, |
104 | .col = list_start.column, | 104 | .col = start.column, |
105 | }); | 105 | }); |
106 | return; | 106 | return; |
107 | } | 107 | } |
@@ -111,57 +111,94 @@ compile_list_unary_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) { | |||
111 | error_push((Error){ | 111 | error_push((Error){ |
112 | .type = ERR_TYPE_COMPILER, | 112 | .type = ERR_TYPE_COMPILER, |
113 | .value = ERR_NOT_ENOUGH_ARGS, | 113 | .value = ERR_NOT_ENOUGH_ARGS, |
114 | .line = list_start.line, | 114 | .line = start.line, |
115 | .col = list_start.column, | 115 | .col = start.column, |
116 | }); | 116 | }); |
117 | } | 117 | } |
118 | return; | 118 | return; |
119 | } | 119 | } |
120 | parse_tree(chunk, vs); | 120 | parse_tree(chunk, vs); |
121 | add_code(chunk, op, list_start.line, list_start.column); | 121 | add_code(chunk, op, start.line, start.column); |
122 | n++; | 122 | n++; |
123 | if (n > 1) { | 123 | if (n > 1) { |
124 | error_push((Error){ | 124 | error_push((Error){ |
125 | .type = ERR_TYPE_COMPILER, | 125 | .type = ERR_TYPE_COMPILER, |
126 | .value = ERR_TOO_MANY_ARGS, | 126 | .value = ERR_TOO_MANY_ARGS, |
127 | .line = list_start.line, | 127 | .line = start.line, |
128 | .col = list_start.column, | 128 | .col = start.column, |
129 | }); | 129 | }); |
130 | } | 130 | } |
131 | } | 131 | } |
132 | error_push((Error){ | 132 | error_push((Error){ |
133 | .type = ERR_TYPE_COMPILER, | 133 | .type = ERR_TYPE_COMPILER, |
134 | .value = ERR_UNBALANCED_PAREN, | 134 | .value = ERR_UNBALANCED_PAREN, |
135 | .line = list_start.line, | 135 | .line = start.line, |
136 | .col = list_start.column, | 136 | .col = start.column, |
137 | }); | 137 | }); |
138 | } | 138 | } |
139 | 139 | ||
140 | void | 140 | void |
141 | parse_list(Chunk *chunk, Visitor *vs, Token list_start) { | 141 | compile_list_simple_op(Chunk *chunk, Visitor *vs, Token start, Ops op) { |
142 | if (has_next_token(vs)) { | ||
143 | Token tok = peek_token(vs); | ||
144 | if (tok.type == TOKEN_EOF) { | ||
145 | error_push((Error){ | ||
146 | .type = ERR_TYPE_COMPILER, | ||
147 | .value = ERR_UNBALANCED_PAREN, | ||
148 | .line = start.line, | ||
149 | .col = start.column, | ||
150 | }); | ||
151 | return; | ||
152 | } | ||
153 | if (tok.type != TOKEN_RPAREN) { | ||
154 | error_push((Error){ | ||
155 | .type = ERR_TYPE_COMPILER, | ||
156 | .value = ERR_TOO_MANY_ARGS, | ||
157 | .line = start.line, | ||
158 | .col = start.column, | ||
159 | }); | ||
160 | return; | ||
161 | } | ||
162 | next_token(vs); | ||
163 | add_code(chunk, op, start.line, start.column); | ||
164 | return; | ||
165 | } | ||
166 | error_push((Error){ | ||
167 | .type = ERR_TYPE_COMPILER, | ||
168 | .value = ERR_UNBALANCED_PAREN, | ||
169 | .line = start.line, | ||
170 | .col = start.column, | ||
171 | }); | ||
172 | } | ||
173 | |||
174 | void | ||
175 | parse_list(Chunk *chunk, Visitor *vs, Token start) { | ||
142 | if (!has_next_token(vs)) { | 176 | if (!has_next_token(vs)) { |
143 | error_push((Error){ | 177 | error_push((Error){ |
144 | .type = ERR_TYPE_COMPILER, | 178 | .type = ERR_TYPE_COMPILER, |
145 | .value = ERR_UNBALANCED_PAREN, | 179 | .value = ERR_UNBALANCED_PAREN, |
146 | .line = list_start.line, | 180 | .line = start.line, |
147 | .col = list_start.column, | 181 | .col = start.column, |
148 | }); | 182 | }); |
149 | } | 183 | } |
150 | Token tok = next_token(vs); | 184 | Token tok = next_token(vs); |
151 | switch (tok.type) { | 185 | switch (tok.type) { |
152 | case TOKEN_ADD: { compile_list_binary_op(chunk, vs, list_start, OP_SUM); } break; | 186 | case TOKEN_ADD: { compile_list_binary_op(chunk, vs, start, OP_SUM); } break; |
153 | case TOKEN_SUB: { compile_list_binary_op(chunk, vs, list_start, OP_SUB); } break; | 187 | case TOKEN_SUB: { compile_list_binary_op(chunk, vs, start, OP_SUB); } break; |
154 | case TOKEN_MUL: { compile_list_binary_op(chunk, vs, list_start, OP_MUL); } break; | 188 | case TOKEN_MUL: { compile_list_binary_op(chunk, vs, start, OP_MUL); } break; |
155 | case TOKEN_DIV: { compile_list_binary_op(chunk, vs, list_start, OP_DIV); } break; | 189 | case TOKEN_DIV: { compile_list_binary_op(chunk, vs, start, OP_DIV); } break; |
156 | case TOKEN_MOD: { compile_list_binary_op(chunk, vs, list_start, OP_MOD); } break; | 190 | case TOKEN_MOD: { compile_list_binary_op(chunk, vs, start, OP_MOD); } break; |
157 | case TOKEN_NOT: { compile_list_unary_op(chunk, vs, list_start, OP_NOT); } break; | 191 | case TOKEN_NOT: { compile_list_unary_op(chunk, vs, start, OP_NOT); } break; |
158 | case TOKEN_AND: { compile_list_binary_op(chunk, vs, list_start, OP_AND); } break; | 192 | case TOKEN_AND: { compile_list_binary_op(chunk, vs, start, OP_AND); } break; |
159 | case TOKEN_OR: { compile_list_binary_op(chunk, vs, list_start, OP_OR); } break; | 193 | case TOKEN_OR: { compile_list_binary_op(chunk, vs, start, OP_OR); } break; |
160 | case TOKEN_EQUAL: { compile_list_binary_op(chunk, vs, list_start, OP_EQUAL); } break; | 194 | case TOKEN_EQUAL: { compile_list_binary_op(chunk, vs, start, OP_EQUAL); } break; |
161 | case TOKEN_LESS: { compile_list_binary_op(chunk, vs, list_start, OP_LESS); } break; | 195 | case TOKEN_LESS: { compile_list_binary_op(chunk, vs, start, OP_LESS); } break; |
162 | case TOKEN_GREATER: { compile_list_binary_op(chunk, vs, list_start, OP_GREATER); } break; | 196 | case TOKEN_GREATER: { compile_list_binary_op(chunk, vs, start, OP_GREATER); } break; |
163 | case TOKEN_LESS_EQUAL: { compile_list_binary_op(chunk, vs, list_start, OP_LESS_EQUAL); } break; | 197 | case TOKEN_LESS_EQUAL: { compile_list_binary_op(chunk, vs, start, OP_LESS_EQUAL); } break; |
164 | case TOKEN_GREATER_EQUAL: { compile_list_binary_op(chunk, vs, list_start, OP_GREATER_EQUAL); } break; | 198 | case TOKEN_GREATER_EQUAL: { compile_list_binary_op(chunk, vs, start, OP_GREATER_EQUAL); } break; |
199 | case TOKEN_PRINT: { compile_list_unary_op(chunk, vs, start, OP_PRINT); } break; | ||
200 | case TOKEN_DISPLAY: { compile_list_unary_op(chunk, vs, start, OP_DISPLAY); } break; | ||
201 | case TOKEN_NEWLINE: { compile_list_simple_op(chunk, vs, start, OP_NEWLINE); } break; | ||
165 | default: { | 202 | default: { |
166 | error_push((Error){ | 203 | error_push((Error){ |
167 | .type = ERR_TYPE_COMPILER, | 204 | .type = ERR_TYPE_COMPILER, |
diff --git a/src/bytecode/debug.h b/src/bytecode/debug.h index 42b5b93..52cf431 100755 --- a/src/bytecode/debug.h +++ b/src/bytecode/debug.h | |||
@@ -6,6 +6,33 @@ | |||
6 | void disassemble_chunk(Chunk *chunk, const char *name); | 6 | void disassemble_chunk(Chunk *chunk, const char *name); |
7 | size_t disassemble_instruction(Chunk *chunk, size_t offset); | 7 | size_t disassemble_instruction(Chunk *chunk, size_t offset); |
8 | 8 | ||
9 | static const char* ops_str[] = { | ||
10 | // Load/store ops. | ||
11 | [OP_CONSTANT] = "OP_CONSTANT", | ||
12 | // Arithmetic ops. | ||
13 | [OP_SUM] = "OP_SUM", | ||
14 | [OP_SUB] = "OP_SUB", | ||
15 | [OP_MUL] = "OP_MUL", | ||
16 | [OP_DIV] = "OP_DIV", | ||
17 | [OP_MOD] = "OP_MOD", | ||
18 | // Logic ops. | ||
19 | [OP_NOT] = "OP_NOT", | ||
20 | [OP_AND] = "OP_AND", | ||
21 | [OP_OR] = "OP_OR", | ||
22 | // Numerical comparison ops. | ||
23 | [OP_EQUAL] = "OP_EQUAL", | ||
24 | [OP_LESS] = "OP_LESS", | ||
25 | [OP_GREATER] = "OP_GREATER", | ||
26 | [OP_LESS_EQUAL] = "OP_LESS_EQUAL", | ||
27 | [OP_GREATER_EQUAL] = "OP_GREATER_EQUAL", | ||
28 | // Display ops. | ||
29 | [OP_DISPLAY] = "OP_DISPLAY", | ||
30 | [OP_PRINT] = "OP_PRINT", | ||
31 | [OP_NEWLINE] = "OP_NEWLINE", | ||
32 | // Return. | ||
33 | [OP_RETURN] = "OP_RETURN", | ||
34 | }; | ||
35 | |||
9 | void | 36 | void |
10 | disassemble_chunk(Chunk *chunk, const char *name) { | 37 | disassemble_chunk(Chunk *chunk, const char *name) { |
11 | printf("== %s ==\n", name); | 38 | printf("== %s ==\n", name); |
@@ -43,14 +70,8 @@ disassemble_instruction(Chunk *chunk, size_t offset) { | |||
43 | printf("\n"); | 70 | printf("\n"); |
44 | return offset + 2; | 71 | return offset + 2; |
45 | } break; | 72 | } break; |
46 | case OP_SUM: { printf("OP_SUM\n"); return offset + 1; } break; | ||
47 | case OP_SUB: { printf("OP_SUB\n"); return offset + 1; } break; | ||
48 | case OP_MUL: { printf("OP_MUL\n"); return offset + 1; } break; | ||
49 | case OP_DIV: { printf("OP_DIV\n"); return offset + 1; } break; | ||
50 | case OP_MOD: { printf("OP_MOD\n"); return offset + 1; } break; | ||
51 | case OP_RETURN: { printf("OP_RETURN\n"); return offset + 1; } break; | ||
52 | default: { | 73 | default: { |
53 | printf("Unknown OP: %d\n", instruction); | 74 | printf("%s\n", ops_str[instruction]); |
54 | return offset + 1; | 75 | return offset + 1; |
55 | } break; | 76 | } break; |
56 | } | 77 | } |
diff --git a/src/bytecode/lexer.c b/src/bytecode/lexer.c index 207cebb..d157111 100755 --- a/src/bytecode/lexer.c +++ b/src/bytecode/lexer.c | |||
@@ -16,6 +16,9 @@ static const char* token_str[] = { | |||
16 | [TOKEN_DEF] = "TOKEN_DEF", | 16 | [TOKEN_DEF] = "TOKEN_DEF", |
17 | [TOKEN_FUN] = "TOKEN_FUN", | 17 | [TOKEN_FUN] = "TOKEN_FUN", |
18 | [TOKEN_LAMBDA] = "TOKEN_LAMBDA", | 18 | [TOKEN_LAMBDA] = "TOKEN_LAMBDA", |
19 | [TOKEN_DISPLAY] = "TOKEN_DISPLAY", | ||
20 | [TOKEN_PRINT] = "TOKEN_PRINT", | ||
21 | [TOKEN_NEWLINE] = "TOKEN_NEWLINE", | ||
19 | [TOKEN_ADD] = "TOKEN_ADD", | 22 | [TOKEN_ADD] = "TOKEN_ADD", |
20 | [TOKEN_SUB] = "TOKEN_SUB", | 23 | [TOKEN_SUB] = "TOKEN_SUB", |
21 | [TOKEN_MUL] = "TOKEN_MUL", | 24 | [TOKEN_MUL] = "TOKEN_MUL", |
@@ -146,6 +149,9 @@ find_primitive_type(const StringView value) { | |||
146 | if (TOKEN_IS_KEYWORD(value, "def")) { return TOKEN_DEF; } | 149 | if (TOKEN_IS_KEYWORD(value, "def")) { return TOKEN_DEF; } |
147 | if (TOKEN_IS_KEYWORD(value, "fun")) { return TOKEN_FUN; } | 150 | if (TOKEN_IS_KEYWORD(value, "fun")) { return TOKEN_FUN; } |
148 | if (TOKEN_IS_KEYWORD(value, "lambda")) { return TOKEN_LAMBDA; } | 151 | if (TOKEN_IS_KEYWORD(value, "lambda")) { return TOKEN_LAMBDA; } |
152 | if (TOKEN_IS_KEYWORD(value, "display")) { return TOKEN_DISPLAY; } | ||
153 | if (TOKEN_IS_KEYWORD(value, "print")) { return TOKEN_PRINT; } | ||
154 | if (TOKEN_IS_KEYWORD(value, "newline")) { return TOKEN_NEWLINE; } | ||
149 | if (TOKEN_IS_KEYWORD(value, "+")) { return TOKEN_ADD; } | 155 | if (TOKEN_IS_KEYWORD(value, "+")) { return TOKEN_ADD; } |
150 | if (TOKEN_IS_KEYWORD(value, "-")) { return TOKEN_SUB; } | 156 | if (TOKEN_IS_KEYWORD(value, "-")) { return TOKEN_SUB; } |
151 | if (TOKEN_IS_KEYWORD(value, "*")) { return TOKEN_MUL; } | 157 | if (TOKEN_IS_KEYWORD(value, "*")) { return TOKEN_MUL; } |
diff --git a/src/bytecode/lexer.h b/src/bytecode/lexer.h index cee2915..7f9eb24 100755 --- a/src/bytecode/lexer.h +++ b/src/bytecode/lexer.h | |||
@@ -25,6 +25,9 @@ typedef enum TokenType { | |||
25 | TOKEN_DEF, | 25 | TOKEN_DEF, |
26 | TOKEN_FUN, | 26 | TOKEN_FUN, |
27 | TOKEN_LAMBDA, | 27 | TOKEN_LAMBDA, |
28 | TOKEN_DISPLAY, | ||
29 | TOKEN_PRINT, | ||
30 | TOKEN_NEWLINE, | ||
28 | 31 | ||
29 | // Arithmetic. | 32 | // Arithmetic. |
30 | TOKEN_ADD, | 33 | TOKEN_ADD, |
diff --git a/src/bytecode/main.c b/src/bytecode/main.c index bad150c..f7d1f74 100755 --- a/src/bytecode/main.c +++ b/src/bytecode/main.c | |||
@@ -8,7 +8,7 @@ | |||
8 | // Config. | 8 | // Config. |
9 | // | 9 | // |
10 | 10 | ||
11 | #define DEBUG_TRACE_EXECUTION | 11 | // #define DEBUG_TRACE_EXECUTION |
12 | 12 | ||
13 | #include "vm.h" | 13 | #include "vm.h" |
14 | #include "compiler.h" | 14 | #include "compiler.h" |
diff --git a/src/bytecode/ops.h b/src/bytecode/ops.h index b59d65a..348df84 100755 --- a/src/bytecode/ops.h +++ b/src/bytecode/ops.h | |||
@@ -2,20 +2,29 @@ | |||
2 | #define BDL_OPS_H | 2 | #define BDL_OPS_H |
3 | 3 | ||
4 | typedef enum Ops { | 4 | typedef enum Ops { |
5 | // Load/store ops. | ||
5 | OP_CONSTANT, | 6 | OP_CONSTANT, |
7 | // Arithmetic ops. | ||
6 | OP_SUM, | 8 | OP_SUM, |
7 | OP_SUB, | 9 | OP_SUB, |
8 | OP_MUL, | 10 | OP_MUL, |
9 | OP_DIV, | 11 | OP_DIV, |
10 | OP_MOD, | 12 | OP_MOD, |
13 | // Logic ops. | ||
11 | OP_NOT, | 14 | OP_NOT, |
12 | OP_AND, | 15 | OP_AND, |
13 | OP_OR, | 16 | OP_OR, |
17 | // Numerical comparison ops. | ||
14 | OP_EQUAL, | 18 | OP_EQUAL, |
15 | OP_LESS, | 19 | OP_LESS, |
16 | OP_GREATER, | 20 | OP_GREATER, |
17 | OP_LESS_EQUAL, | 21 | OP_LESS_EQUAL, |
18 | OP_GREATER_EQUAL, | 22 | OP_GREATER_EQUAL, |
23 | // Display ops. | ||
24 | OP_DISPLAY, | ||
25 | OP_PRINT, | ||
26 | OP_NEWLINE, | ||
27 | // Return. | ||
19 | OP_RETURN, | 28 | OP_RETURN, |
20 | } Ops; | 29 | } Ops; |
21 | 30 | ||
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h index b3dd8c3..f1886ec 100755 --- a/src/bytecode/vm.h +++ b/src/bytecode/vm.h | |||
@@ -159,8 +159,37 @@ vm_interpret(VM *vm, Chunk *chunk) { | |||
159 | case OP_GREATER: { FIXNUM_COMPARE_OP(>); } break; | 159 | case OP_GREATER: { FIXNUM_COMPARE_OP(>); } break; |
160 | case OP_LESS_EQUAL: { FIXNUM_COMPARE_OP(<=); } break; | 160 | case OP_LESS_EQUAL: { FIXNUM_COMPARE_OP(<=); } break; |
161 | case OP_GREATER_EQUAL: { FIXNUM_COMPARE_OP(>=); } break; | 161 | case OP_GREATER_EQUAL: { FIXNUM_COMPARE_OP(>=); } break; |
162 | case OP_RETURN: { | 162 | case OP_DISPLAY: { |
163 | display(array_pop(vm->stack)); | 163 | display(array_pop(vm->stack)); |
164 | } break; | ||
165 | case OP_PRINT: { | ||
166 | Object obj = array_pop(vm->stack); | ||
167 | if (!IS_STRING(obj)) { | ||
168 | WRONG_ARG_ERR(); | ||
169 | } | ||
170 | StringView scanner = (StringView) { | ||
171 | .start = obj.text, | ||
172 | .n = array_size(obj.text), | ||
173 | }; | ||
174 | while (scanner.n != 0) { | ||
175 | char c = sv_next(&scanner); | ||
176 | if (c == '\\' && sv_peek(&scanner) == 'n') { | ||
177 | putchar('\n'); | ||
178 | sv_next(&scanner); | ||
179 | continue; | ||
180 | } | ||
181 | if (c == '\\' && sv_peek(&scanner) == '"') { | ||
182 | putchar('"'); | ||
183 | sv_next(&scanner); | ||
184 | continue; | ||
185 | } | ||
186 | putchar(c); | ||
187 | } | ||
188 | } break; | ||
189 | case OP_NEWLINE: { | ||
190 | printf("\n"); | ||
191 | } break; | ||
192 | case OP_RETURN: { | ||
164 | printf("\n"); | 193 | printf("\n"); |
165 | return; | 194 | return; |
166 | } break; | 195 | } break; |