aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-26 09:56:18 +0200
committerBad Diode <bd@badd10de.dev>2021-10-26 09:56:18 +0200
commitda84e7e731de39ff385ae675a023ddcb9c58d06a (patch)
tree901f69a55de73fbbca15300a6638dab230d5835c
parent9f1f2ff307bb3da8bfc6809ae05be589e1e37ed9 (diff)
downloadbdl-da84e7e731de39ff385ae675a023ddcb9c58d06a.tar.gz
bdl-da84e7e731de39ff385ae675a023ddcb9c58d06a.zip
Add support for lambda functions
-rwxr-xr-xsrc/bytecode/compiler.h95
-rwxr-xr-xsrc/bytecode/string_view.h2
2 files changed, 49 insertions, 48 deletions
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h
index 9fefd2a..ca187b3 100755
--- a/src/bytecode/compiler.h
+++ b/src/bytecode/compiler.h
@@ -248,21 +248,8 @@ compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) {
248} 248}
249 249
250void 250void
251compile_fun_op(Chunk *chunk, Compiler *compiler, Token start) { 251compile_lambda(Chunk *chunk, Compiler *compiler, Token start, StringView name) {
252 Token name = peek_token(compiler); 252 Object fun = make_lambda(name);
253 if (name.type != TOKEN_SYMBOL) {
254 error_push((Error){
255 .type = ERR_TYPE_COMPILER,
256 .value = ERR_WRONG_ARG_TYPE,
257 .line = start.line,
258 .col = start.column,
259 });
260 return;
261 }
262 parse_tree(chunk, compiler);
263
264 // TODO: compile lambda expression.
265 Object fun = make_lambda(name.value);
266 // FIXME: skipping arguments for now. Assuming nil. 253 // FIXME: skipping arguments for now. Assuming nil.
267 next_token(compiler); 254 next_token(compiler);
268 255
@@ -285,13 +272,12 @@ compile_fun_op(Chunk *chunk, Compiler *compiler, Token start) {
285 parse_tree(fun.chunk, compiler); 272 parse_tree(fun.chunk, compiler);
286 } 273 }
287 add_code(fun.chunk, OP_RETURN, start.line, start.column); 274 add_code(fun.chunk, OP_RETURN, start.line, start.column);
288
289 emit_constant(chunk, start, fun); 275 emit_constant(chunk, start, fun);
290 add_code(chunk, OP_DEF, start.line, start.column);
291} 276}
292 277
293void 278void
294compile_call_op(Chunk *chunk, Compiler *compiler, Token start, Token name) { 279compile_fun_op(Chunk *chunk, Compiler *compiler, Token start) {
280 Token name = peek_token(compiler);
295 if (name.type != TOKEN_SYMBOL) { 281 if (name.type != TOKEN_SYMBOL) {
296 error_push((Error){ 282 error_push((Error){
297 .type = ERR_TYPE_COMPILER, 283 .type = ERR_TYPE_COMPILER,
@@ -301,7 +287,13 @@ compile_call_op(Chunk *chunk, Compiler *compiler, Token start, Token name) {
301 }); 287 });
302 return; 288 return;
303 } 289 }
290 parse_tree(chunk, compiler);
291 compile_lambda(chunk, compiler, start, name.value);
292 add_code(chunk, OP_DEF, start.line, start.column);
293}
304 294
295void
296compile_call_op(Chunk *chunk, Compiler *compiler, Token start, Token name) {
305 // FIXME: skipping arguments for now. Assuming nil. 297 // FIXME: skipping arguments for now. Assuming nil.
306 298
307 // Compile body. 299 // Compile body.
@@ -321,9 +313,11 @@ compile_call_op(Chunk *chunk, Compiler *compiler, Token start, Token name) {
321 break; 313 break;
322 } 314 }
323 } 315 }
324 Object obj = make_symbol(name.value); 316 if (name.type == TOKEN_SYMBOL) {
325 emit_constant(chunk, start, obj); 317 Object obj = make_symbol(name.value);
326 add_code(chunk, OP_GET, start.line, start.column); 318 emit_constant(chunk, start, obj);
319 add_code(chunk, OP_GET, start.line, start.column);
320 }
327 add_code(chunk, OP_CALL, start.line, start.column); 321 add_code(chunk, OP_CALL, start.line, start.column);
328} 322}
329 323
@@ -392,33 +386,38 @@ parse_list(Chunk *chunk, Compiler *compiler, Token start) {
392 }); 386 });
393 return; 387 return;
394 } 388 }
395 Token tok = next_token(compiler); 389 while (has_next_token(compiler)) {
396 switch (tok.type) { 390 Token tok = next_token(compiler);
397 case TOKEN_ADD: { compile_list_binary_op(chunk, compiler, start, OP_SUM); } break; 391 if (tok.type == TOKEN_LPAREN) {
398 case TOKEN_SUB: { compile_list_binary_op(chunk, compiler, start, OP_SUB); } break; 392 parse_list(chunk, compiler, tok);
399 case TOKEN_MUL: { compile_list_binary_op(chunk, compiler, start, OP_MUL); } break; 393 }
400 case TOKEN_DIV: { compile_list_binary_op(chunk, compiler, start, OP_DIV); } break; 394 switch (tok.type) {
401 case TOKEN_MOD: { compile_list_binary_op(chunk, compiler, start, OP_MOD); } break; 395 case TOKEN_ADD: { compile_list_binary_op(chunk, compiler, start, OP_SUM); } break;
402 case TOKEN_NOT: { compile_list_unary_op(chunk, compiler, start, OP_NOT); } break; 396 case TOKEN_SUB: { compile_list_binary_op(chunk, compiler, start, OP_SUB); } break;
403 case TOKEN_AND: { compile_list_binary_op(chunk, compiler, start, OP_AND); } break; 397 case TOKEN_MUL: { compile_list_binary_op(chunk, compiler, start, OP_MUL); } break;
404 case TOKEN_OR: { compile_list_binary_op(chunk, compiler, start, OP_OR); } break; 398 case TOKEN_DIV: { compile_list_binary_op(chunk, compiler, start, OP_DIV); } break;
405 case TOKEN_EQUAL: { compile_list_binary_op(chunk, compiler, start, OP_EQUAL); } break; 399 case TOKEN_MOD: { compile_list_binary_op(chunk, compiler, start, OP_MOD); } break;
406 case TOKEN_LESS: { compile_list_binary_op(chunk, compiler, start, OP_LESS); } break; 400 case TOKEN_NOT: { compile_list_unary_op(chunk, compiler, start, OP_NOT); } break;
407 case TOKEN_GREATER: { compile_list_binary_op(chunk, compiler, start, OP_GREATER); } break; 401 case TOKEN_AND: { compile_list_binary_op(chunk, compiler, start, OP_AND); } break;
408 case TOKEN_LESS_EQUAL: { compile_list_binary_op(chunk, compiler, start, OP_LESS_EQUAL); } break; 402 case TOKEN_OR: { compile_list_binary_op(chunk, compiler, start, OP_OR); } break;
409 case TOKEN_GREATER_EQUAL: { compile_list_binary_op(chunk, compiler, start, OP_GREATER_EQUAL); } break; 403 case TOKEN_EQUAL: { compile_list_binary_op(chunk, compiler, start, OP_EQUAL); } break;
410 case TOKEN_PRINT: { compile_list_unary_op(chunk, compiler, start, OP_PRINT); } break; 404 case TOKEN_LESS: { compile_list_binary_op(chunk, compiler, start, OP_LESS); } break;
411 case TOKEN_DISPLAY: { compile_list_unary_op(chunk, compiler, start, OP_DISPLAY); } break; 405 case TOKEN_GREATER: { compile_list_binary_op(chunk, compiler, start, OP_GREATER); } break;
412 case TOKEN_NEWLINE: { compile_list_simple_op(chunk, compiler, start, OP_NEWLINE); } break; 406 case TOKEN_LESS_EQUAL: { compile_list_binary_op(chunk, compiler, start, OP_LESS_EQUAL); } break;
413 case TOKEN_DEF: { compile_declare_op(chunk, compiler, start, OP_DEF); } break; 407 case TOKEN_GREATER_EQUAL: { compile_list_binary_op(chunk, compiler, start, OP_GREATER_EQUAL); } break;
414 case TOKEN_SET: { compile_declare_op(chunk, compiler, start, OP_SET); } break; 408 case TOKEN_PRINT: { compile_list_unary_op(chunk, compiler, start, OP_PRINT); } break;
415 case TOKEN_FUN: { compile_fun_op(chunk, compiler, start); } break; 409 case TOKEN_DISPLAY: { compile_list_unary_op(chunk, compiler, start, OP_DISPLAY); } break;
416 case TOKEN_IF: { compile_if_op(chunk, compiler, start); } break; 410 case TOKEN_NEWLINE: { compile_list_simple_op(chunk, compiler, start, OP_NEWLINE); } break;
417 default: { 411 case TOKEN_DEF: { compile_declare_op(chunk, compiler, start, OP_DEF); } break;
418 // TODO: Emit error if compiler knows there hasn't been 412 case TOKEN_SET: { compile_declare_op(chunk, compiler, start, OP_SET); } break;
419 // a function delcared with that name. 413 case TOKEN_FUN: { compile_fun_op(chunk, compiler, start); } break;
420 compile_call_op(chunk, compiler, start, tok); 414 case TOKEN_LAMBDA: { compile_lambda(chunk, compiler, start, STRING("lambda")); } break;
421 } break; 415 case TOKEN_IF: { compile_if_op(chunk, compiler, start); } break;
416 default: {
417 compile_call_op(chunk, compiler, start, tok);
418 } break;
419 }
420 return;
422 } 421 }
423} 422}
424 423
diff --git a/src/bytecode/string_view.h b/src/bytecode/string_view.h
index 64c8d8e..79d8305 100755
--- a/src/bytecode/string_view.h
+++ b/src/bytecode/string_view.h
@@ -18,4 +18,6 @@ bool sv_equal(const StringView *a, const StringView *b);
18// Write a character to the given output stream. 18// Write a character to the given output stream.
19void sv_write(const StringView *sv); 19void sv_write(const StringView *sv);
20 20
21#define STRING(STR) (StringView){(STR), sizeof(STR)}
22
21#endif // BDL_STRINGVIEW_H 23#endif // BDL_STRINGVIEW_H