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,
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
";", // "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",
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);
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;
}
}
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;
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) {
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:
{