Added logical comparison operators
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 20 Jun 2020 20:38:29 +0000 (15:38 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 20 Jun 2020 20:38:29 +0000 (15:38 -0500)
Still need to add boolean types

include/onyxlex.h
onyx
progs/minimal.onyx
src/onyxlex.c
src/onyxparser.c
src/onyxutils.c
src/onyxwasm.c

index c9a4632ad8f0b7388fa1a7e58c0c7a8bdf66f1ba..7c502c7694fca4da5e64762eda848f9f206bd3a5 100644 (file)
@@ -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 20ab66431676508fa008c72cdaa70068536b9c33..1c15f82624dea9d2e6bdb843f4bea638577c6a7a 100755 (executable)
Binary files a/onyx and b/onyx differ
index 818a598a76ec6a4811c33c7c1b22b541273748cb..03ebfcb2d5cf601470960b94f1b0efa0d7df40b3 100644 (file)
@@ -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
index 3ed4c58fb36fb12fb65906b61fabdd89fcdde418..6c969bfaa6d57c1f2b8b8a8b1d3148ee142c0ffe 100644 (file)
@@ -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);
index 0eaa4db1d0850fb1a737007e7e6cdb62e167f780..bfe4a3c639543dc70e67017bb5442eadf6f783fa 100644 (file)
@@ -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;
index 5070e721cdc0277b8257a468749b44eda0690795..732be5859934d4910709b0042d4a70356bc71f6d 100644 (file)
@@ -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) {
index 090919920a2fbe1bf175684b669ba486e507d284..d5016649f68b87fba662c96143e3224bd7543833 100644 (file)
@@ -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:
                        {