From: Brendan Hansen Date: Sat, 20 Jun 2020 20:38:29 +0000 (-0500) Subject: Added logical comparison operators X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=84b53a855daf61fd14cc13a543c4899b859cc22c;p=onyx.git Added logical comparison operators Still need to add boolean types --- diff --git a/include/onyxlex.h b/include/onyxlex.h index c9a4632a..7c502c76 100644 --- a/include/onyxlex.h +++ b/include/onyxlex.h @@ -46,6 +46,8 @@ typedef enum OnyxTokenType { TOKEN_TYPE_SYM_GREATER_EQUAL, TOKEN_TYPE_SYM_LESS, TOKEN_TYPE_SYM_LESS_EQUAL, + TOKEN_TYPE_SYM_EQUAL_EQUAL, + TOKEN_TYPE_SYM_NOT_EQUAL, TOKEN_TYPE_SYM_EQUALS, TOKEN_TYPE_SYM_TILDE, TOKEN_TYPE_SYM_BANG, diff --git a/onyx b/onyx index 20ab6643..1c15f826 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/minimal.onyx b/progs/minimal.onyx index 818a598a..03ebfcb2 100644 --- a/progs/minimal.onyx +++ b/progs/minimal.onyx @@ -11,6 +11,14 @@ add :: proc (a i32, b i32) -> i32 { return a + b; } +abs :: proc (val i32) -> i32 { + if val <= 0 { + return -val; + } else { + return val; + }; +} + diff_square :: proc (a i32, b i32) -> i32 { // Typechecked c := a - b; // Mutable diff --git a/src/onyxlex.c b/src/onyxlex.c index 3ed4c58f..6c969bfa 100644 --- a/src/onyxlex.c +++ b/src/onyxlex.c @@ -41,9 +41,11 @@ static const char* onyx_token_type_names[] = { ";", // "TOKEN_TYPE_SYM_SEMICOLON", ",", // "TOKEN_TYPE_SYM_COMMA", ">", // "TOKEN_TYPE_SYM_GREATER", - ">=", // "TOKEN_TYPE_SYM_GREATER_EQUAL", + ">=", // "TOKEN_TYPE_SYM_GREATER_EQUAL", "<", // "TOKEN_TYPE_SYM_LESS", - "<=", // "TOKEN_TYPE_SYM_LESS_EQUAL", + "<=", // "TOKEN_TYPE_SYM_LESS_EQUAL", + "==", // "TOKEN_TYPE_SYM_EQUALS_EQUALS", + "!=", // "TOKEN_TYPE_SYM_NOT_EQUAL", "=", // "TOKEN_TYPE_SYM_EQUALS", "~", // "TOKEN_TYPE_SYM_TILDE", "!", // "TOKEN_TYPE_SYM_BANG", @@ -152,6 +154,8 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) { LITERAL_TOKEN("<-", 0, TOKEN_TYPE_RIGHT_ARROW); LITERAL_TOKEN("<=", 0, TOKEN_TYPE_SYM_LESS_EQUAL); LITERAL_TOKEN(">=", 0, TOKEN_TYPE_SYM_GREATER_EQUAL); + LITERAL_TOKEN("==", 0, TOKEN_TYPE_SYM_EQUAL_EQUAL); + LITERAL_TOKEN("!=", 0, TOKEN_TYPE_SYM_NOT_EQUAL); LITERAL_TOKEN("(", 0, TOKEN_TYPE_OPEN_PAREN); LITERAL_TOKEN(")", 0, TOKEN_TYPE_CLOSE_PAREN); LITERAL_TOKEN("{", 0, TOKEN_TYPE_OPEN_BRACE); diff --git a/src/onyxparser.c b/src/onyxparser.c index 0eaa4db1..bfe4a3c6 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -329,12 +329,23 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) { static inline i32 get_precedence(OnyxAstNodeKind kind) { switch (kind) { - case ONYX_AST_NODE_KIND_ADD: return 1; - case ONYX_AST_NODE_KIND_MINUS: return 1; - case ONYX_AST_NODE_KIND_MULTIPLY: return 2; - case ONYX_AST_NODE_KIND_DIVIDE: return 2; - case ONYX_AST_NODE_KIND_MODULUS: return 3; - case ONYX_AST_NODE_KIND_CAST: return 4; + case ONYX_AST_NODE_KIND_EQUAL: return 3; + case ONYX_AST_NODE_KIND_NOT_EQUAL: return 3; + + case ONYX_AST_NODE_KIND_LESS_EQUAL: return 4; + case ONYX_AST_NODE_KIND_LESS: return 4; + case ONYX_AST_NODE_KIND_GREATER_EQUAL: return 4; + case ONYX_AST_NODE_KIND_GREATER: return 4; + + case ONYX_AST_NODE_KIND_ADD: return 5; + case ONYX_AST_NODE_KIND_MINUS: return 5; + + case ONYX_AST_NODE_KIND_MULTIPLY: return 6; + case ONYX_AST_NODE_KIND_DIVIDE: return 6; + + case ONYX_AST_NODE_KIND_MODULUS: return 7; + + case ONYX_AST_NODE_KIND_CAST: return 8; default: return -1; } } @@ -354,6 +365,13 @@ static OnyxAstNode* parse_expression(OnyxParser* parser) { while (1) { bin_op_kind = -1; switch (parser->curr_token->type) { + case TOKEN_TYPE_SYM_EQUAL_EQUAL: bin_op_kind = ONYX_AST_NODE_KIND_EQUAL; break; + case TOKEN_TYPE_SYM_NOT_EQUAL: bin_op_kind = ONYX_AST_NODE_KIND_NOT_EQUAL; break; + case TOKEN_TYPE_SYM_LESS_EQUAL: bin_op_kind = ONYX_AST_NODE_KIND_LESS_EQUAL; break; + case TOKEN_TYPE_SYM_LESS: bin_op_kind = ONYX_AST_NODE_KIND_LESS; break; + case TOKEN_TYPE_SYM_GREATER_EQUAL: bin_op_kind = ONYX_AST_NODE_KIND_GREATER_EQUAL; break; + case TOKEN_TYPE_SYM_GREATER: bin_op_kind = ONYX_AST_NODE_KIND_GREATER; break; + case TOKEN_TYPE_SYM_PLUS: bin_op_kind = ONYX_AST_NODE_KIND_ADD; break; case TOKEN_TYPE_SYM_MINUS: bin_op_kind = ONYX_AST_NODE_KIND_MINUS; break; case TOKEN_TYPE_SYM_STAR: bin_op_kind = ONYX_AST_NODE_KIND_MULTIPLY; break; diff --git a/src/onyxutils.c b/src/onyxutils.c index 5070e721..732be585 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -146,12 +146,18 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) { case ONYX_AST_NODE_KIND_IF: { OnyxAstNodeIf* if_node = &node->as_if; if (if_node->cond) { + print_indent; + bh_printf("Condition:"); onyx_ast_print(if_node->cond, indent + 1); } if (if_node->true_block) { + print_indent; + bh_printf("True block:"); onyx_ast_print(if_node->true_block, indent + 1); } if (if_node->false_block) { + print_indent; + bh_printf("False block:"); onyx_ast_print(if_node->false_block, indent + 1); } if (if_node->next) { diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 09091992..d5016649 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -305,36 +305,45 @@ static void process_assignment(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* break; \ } +#define BIN_OP_SIGNED_PROCESS(ast_binop, wasm_binop) \ + case ONYX_AST_NODE_KIND_##ast_binop: \ + { \ + WasmInstructionType instr_type; \ + switch (expr->type->kind) { \ + case ONYX_TYPE_INFO_KIND_UINT32: \ + case ONYX_TYPE_INFO_KIND_INT32: \ + if (expr->type->is_unsigned) instr_type = WI_I32_##wasm_binop##_U; \ + else instr_type = WI_I32_##wasm_binop##_S; \ + break; \ + case ONYX_TYPE_INFO_KIND_UINT64: \ + case ONYX_TYPE_INFO_KIND_INT64: \ + if (expr->type->is_unsigned) instr_type = WI_I64_##wasm_binop##_U; \ + else instr_type = WI_I64_##wasm_binop##_S; \ + break; \ + case ONYX_TYPE_INFO_KIND_FLOAT32: instr_type = WI_F32_##wasm_binop; break; \ + case ONYX_TYPE_INFO_KIND_FLOAT64: instr_type = WI_F64_##wasm_binop; break; \ + default: assert(("Invalid type", 0)); \ + } \ + \ + process_expression(mod, func, expr->left); \ + process_expression(mod, func, expr->right); \ + bh_arr_push(func->code, ((WasmInstruction){ instr_type, 0x00 })); \ + break; \ + } + static void process_expression(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* expr) { switch (expr->kind) { BIN_OP_PROCESS(ADD, ADD); BIN_OP_PROCESS(MINUS, SUB); BIN_OP_PROCESS(MULTIPLY, MUL); - - case ONYX_AST_NODE_KIND_DIVIDE: - { - WasmInstructionType instr_type; - switch (expr->type->kind) { - case ONYX_TYPE_INFO_KIND_UINT32: - case ONYX_TYPE_INFO_KIND_INT32: - if (expr->type->is_unsigned) instr_type = WI_I32_DIV_U; - else instr_type = WI_I32_DIV_S; - break; - case ONYX_TYPE_INFO_KIND_UINT64: - case ONYX_TYPE_INFO_KIND_INT64: - if (expr->type->is_unsigned) instr_type = WI_I64_DIV_U; - else instr_type = WI_I64_DIV_S; - break; - case ONYX_TYPE_INFO_KIND_FLOAT32: instr_type = WI_F32_DIV; break; - case ONYX_TYPE_INFO_KIND_FLOAT64: instr_type = WI_F64_DIV; break; - default: assert(("Invalid type", 0)); - } - - process_expression(mod, func, expr->left); - process_expression(mod, func, expr->right); - bh_arr_push(func->code, ((WasmInstruction){ instr_type, 0x00 })); - break; - } + BIN_OP_SIGNED_PROCESS(DIVIDE, DIV); + + BIN_OP_SIGNED_PROCESS(LESS, LT); + BIN_OP_SIGNED_PROCESS(LESS_EQUAL, LE); + BIN_OP_SIGNED_PROCESS(GREATER, GT); + BIN_OP_SIGNED_PROCESS(GREATER_EQUAL, GE); + BIN_OP_PROCESS(EQUAL, EQ); + BIN_OP_PROCESS(NOT_EQUAL, NE); case ONYX_AST_NODE_KIND_MODULUS: {