From b07ece568d8d62ca80a8ba3b43fb46a98e117d5a Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sat, 23 Oct 2021 18:19:14 +0200 Subject: Add logic operations --- src/bytecode/compiler.h | 88 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 14 deletions(-) (limited to 'src/bytecode/compiler.h') diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h index fd5cdbc..6f43416 100755 --- a/src/bytecode/compiler.h +++ b/src/bytecode/compiler.h @@ -58,7 +58,7 @@ parse_fixnum(Chunk *chunk, Token tok) { void parse_tree(Chunk *chunk, Visitor *vs); void -compile_list_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) { +compile_list_binary_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) { size_t n = 0; while (has_next_token(vs)) { Token tok = peek_token(vs); @@ -73,7 +73,15 @@ compile_list_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) { } if (tok.type == TOKEN_RPAREN) { next_token(vs); - break; + if (n <= 1) { + error_push((Error){ + .type = ERR_TYPE_COMPILER, + .value = ERR_NOT_ENOUGH_ARGS, + .line = list_start.line, + .col = list_start.column, + }); + } + return; } parse_tree(chunk, vs); n++; @@ -81,14 +89,58 @@ compile_list_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) { add_code(chunk, op, list_start.line, list_start.column); } } - if (n == 0) { - error_push((Error){ - .type = ERR_TYPE_COMPILER, - .value = ERR_NOT_ENOUGH_ARGS, - .line = list_start.line, - .col = list_start.column, - }); + error_push((Error){ + .type = ERR_TYPE_COMPILER, + .value = ERR_NOT_ENOUGH_ARGS, + .line = list_start.line, + .col = list_start.column, + }); +} + +void +compile_list_unary_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) { + size_t n = 0; + while (has_next_token(vs)) { + Token tok = peek_token(vs); + if (tok.type == TOKEN_EOF) { + error_push((Error){ + .type = ERR_TYPE_COMPILER, + .value = ERR_UNBALANCED_PAREN, + .line = list_start.line, + .col = list_start.column, + }); + return; + } + if (tok.type == TOKEN_RPAREN) { + next_token(vs); + if (n == 0) { + error_push((Error){ + .type = ERR_TYPE_COMPILER, + .value = ERR_NOT_ENOUGH_ARGS, + .line = list_start.line, + .col = list_start.column, + }); + } + return; + } + parse_tree(chunk, vs); + add_code(chunk, op, list_start.line, list_start.column); + n++; + if (n > 1) { + error_push((Error){ + .type = ERR_TYPE_COMPILER, + .value = ERR_TOO_MANY_ARGS, + .line = list_start.line, + .col = list_start.column, + }); + } } + error_push((Error){ + .type = ERR_TYPE_COMPILER, + .value = ERR_UNBALANCED_PAREN, + .line = list_start.line, + .col = list_start.column, + }); } void @@ -103,11 +155,19 @@ parse_list(Chunk *chunk, Visitor *vs, Token list_start) { } Token tok = next_token(vs); switch (tok.type) { - case TOKEN_ADD: { compile_list_op(chunk, vs, list_start, OP_SUM); } break; - case TOKEN_SUB: { compile_list_op(chunk, vs, list_start, OP_SUB); } break; - case TOKEN_MUL: { compile_list_op(chunk, vs, list_start, OP_MUL); } break; - case TOKEN_DIV: { compile_list_op(chunk, vs, list_start, OP_DIV); } break; - case TOKEN_MOD: { compile_list_op(chunk, vs, list_start, OP_MOD); } break; + case TOKEN_ADD: { compile_list_binary_op(chunk, vs, list_start, OP_SUM); } break; + case TOKEN_SUB: { compile_list_binary_op(chunk, vs, list_start, OP_SUB); } break; + case TOKEN_MUL: { compile_list_binary_op(chunk, vs, list_start, OP_MUL); } break; + case TOKEN_DIV: { compile_list_binary_op(chunk, vs, list_start, OP_DIV); } break; + case TOKEN_MOD: { compile_list_binary_op(chunk, vs, list_start, OP_MOD); } break; + case TOKEN_NOT: { compile_list_unary_op(chunk, vs, list_start, OP_NOT); } break; + case TOKEN_AND: { compile_list_binary_op(chunk, vs, list_start, OP_AND); } break; + case TOKEN_OR: { compile_list_binary_op(chunk, vs, list_start, OP_OR); } break; + case TOKEN_EQUAL: { compile_list_binary_op(chunk, vs, list_start, OP_EQUAL); } break; + case TOKEN_LESS: { compile_list_binary_op(chunk, vs, list_start, OP_LESS); } break; + case TOKEN_GREATER: { compile_list_binary_op(chunk, vs, list_start, OP_GREATER); } break; + case TOKEN_LESS_EQUAL: { compile_list_binary_op(chunk, vs, list_start, OP_LESS_EQUAL); } break; + case TOKEN_GREATER_EQUAL: { compile_list_binary_op(chunk, vs, list_start, OP_GREATER_EQUAL); } break; default: { error_push((Error){ .type = ERR_TYPE_COMPILER, -- cgit v1.2.1