typedef struct AstDereference AstDereference;
typedef struct AstArrayAccess AstArrayAccess;
typedef struct AstFieldAccess AstFieldAccess;
-typedef struct AstUfc AstUfc;
typedef struct AstSizeOf AstSizeOf;
typedef struct AstAlignOf AstAlignOf;
typedef struct AstFileContents AstFileContents;
Binary_Op_Assign_Shr = 30,
Binary_Op_Assign_Sar = 31,
Binary_Op_Assign_End = 32,
+
+ Binary_Op_Pipe = 33,
} BinaryOp;
typedef enum OnyxIntrinsic {
struct AstDereference { AstTyped_base; AstTyped *expr; };
struct AstArrayAccess { AstTyped_base; AstTyped *addr; AstTyped *expr; u64 elem_size; };
struct AstFieldAccess { AstTyped_base; AstTyped *expr; u64 offset; };
-struct AstUfc { AstTyped_base; AstTyped *object; AstTyped *call; };
struct AstSizeOf { AstTyped_base; AstType *so_type; u64 size; };
struct AstAlignOf { AstTyped_base; AstType *ao_type; u64 alignment; };
struct AstFileContents { AstTyped_base; OnyxToken *filename; };
break;
}
- case Token_Type_Pipe: {
- AstUfc* ufc_node = make_node(AstUfc, Ast_Kind_Ufc);
- ufc_node->token = expect_token(parser, Token_Type_Pipe);
- ufc_node->object = retval;
-
- AstTyped* right = parse_factor(parser);
-
- if (right->kind == Ast_Kind_Ufc) {
- ufc_node->call = ((AstUfc *) right)->object;
- ((AstUfc *) right)->object = (AstTyped *) ufc_node;
- retval = right;
-
- } else {
- ufc_node->call = right;
- retval = (AstTyped *) ufc_node;
- }
-
- break;
- }
-
default: goto factor_parsed;
}
}
case Binary_Op_Assign_Shr: return 1;
case Binary_Op_Assign_Sar: return 1;
- case Binary_Op_Bool_And: return 2;
- case Binary_Op_Bool_Or: return 2;
+ case Binary_Op_Pipe: return 2;
- case Binary_Op_Equal: return 3;
- case Binary_Op_Not_Equal: return 3;
+ case Binary_Op_Bool_And: return 3;
+ case Binary_Op_Bool_Or: return 3;
- case Binary_Op_Less_Equal: return 4;
- case Binary_Op_Less: return 4;
- case Binary_Op_Greater_Equal: return 4;
- case Binary_Op_Greater: return 4;
+ case Binary_Op_Equal: return 4;
+ case Binary_Op_Not_Equal: return 4;
- case Binary_Op_And: return 5;
- case Binary_Op_Or: return 5;
- case Binary_Op_Xor: return 5;
- case Binary_Op_Shl: return 5;
- case Binary_Op_Shr: return 5;
- case Binary_Op_Sar: return 5;
+ case Binary_Op_Less_Equal: return 5;
+ case Binary_Op_Less: return 5;
+ case Binary_Op_Greater_Equal: return 5;
+ case Binary_Op_Greater: return 5;
- case Binary_Op_Add: return 6;
- case Binary_Op_Minus: return 6;
+ case Binary_Op_And: return 6;
+ case Binary_Op_Or: return 6;
+ case Binary_Op_Xor: return 6;
+ case Binary_Op_Shl: return 6;
+ case Binary_Op_Shr: return 6;
+ case Binary_Op_Sar: return 6;
- case Binary_Op_Multiply: return 7;
- case Binary_Op_Divide: return 7;
+ case Binary_Op_Add: return 7;
+ case Binary_Op_Minus: return 7;
- case Binary_Op_Modulus: return 8;
+ case Binary_Op_Multiply: return 8;
+ case Binary_Op_Divide: return 8;
+
+ case Binary_Op_Modulus: return 9;
default: return -1;
}
case Token_Type_Shl_Equal: bin_op_kind = Binary_Op_Assign_Shl; break;
case Token_Type_Shr_Equal: bin_op_kind = Binary_Op_Assign_Shr; break;
case Token_Type_Sar_Equal: bin_op_kind = Binary_Op_Assign_Sar; break;
+
+ case Token_Type_Pipe: bin_op_kind = Binary_Op_Pipe; break;
default: goto expression_done;
}
bin_op_tok = parser->curr;
consume_token(parser);
- AstBinaryOp* bin_op = make_node(AstBinaryOp, Ast_Kind_Binary_Op);
- bin_op->operation = bin_op_kind;
- bin_op->token = bin_op_tok;
+ AstBinaryOp* bin_op;
+ if (bin_op_kind != Binary_Op_Pipe) {
+ bin_op = make_node(AstBinaryOp, Ast_Kind_Binary_Op);
+ bin_op->operation = bin_op_kind;
+ bin_op->token = bin_op_tok;
+
+ } else {
+ bin_op = make_node(AstBinaryOp, Ast_Kind_Ufc);
+ bin_op->token = bin_op_tok;
+ }
while ( !bh_arr_is_empty(tree_stack) &&
get_precedence(bh_arr_last(tree_stack)->operation) >= get_precedence(bin_op_kind))
}
}
-static void symres_ufc(AstUfc** ufc) {
- AstCall* call_node = (AstCall *) (*ufc)->call;
+static void symres_ufc(AstBinaryOp** ufc) {
+ AstCall* call_node = (AstCall *) (*ufc)->right;
symres_expression((AstTyped **) &call_node);
- symres_expression(&(*ufc)->object);
+ symres_expression(&(*ufc)->left);
- if ((*ufc)->call->kind != Ast_Kind_Call) {
+ if (call_node->kind != Ast_Kind_Call) {
onyx_message_add(Msg_Type_Literal,
(*ufc)->token->pos,
"universal function call expected call on right side");
return;
}
- if ((*ufc)->object == NULL) return;
+ if ((*ufc)->left == NULL) return;
AstArgument* implicit_arg = onyx_ast_node_new(semstate.node_allocator,
sizeof(AstArgument),
Ast_Kind_Argument);
- implicit_arg->value = (*ufc)->object;
+ implicit_arg->value = (*ufc)->left;
implicit_arg->next = (AstNode *) call_node->arguments;
call_node->arguments = implicit_arg;
call_node->arg_count++;
call_node->next = (*ufc)->next;
- // NOTE: Not a UFC node
- *ufc = (AstUfc *) call_node;
+ // NOTE: Not a BinaryOp node
+ *ufc = (AstBinaryOp *) call_node;
}
static void symres_unaryop(AstUnaryOp** unaryop) {
case Ast_Kind_Address_Of: symres_expression(&((AstAddressOf *)(*expr))->expr); break;
case Ast_Kind_Dereference: symres_expression(&((AstDereference *)(*expr))->expr); break;
case Ast_Kind_Field_Access: symres_field_access((AstFieldAccess **) expr); break;
- case Ast_Kind_Ufc: symres_ufc((AstUfc **) expr); break;
+ case Ast_Kind_Ufc: symres_ufc((AstBinaryOp **) expr); break;
case Ast_Kind_Size_Of: symres_size_of((AstSizeOf *)*expr); break;
case Ast_Kind_Align_Of: symres_align_of((AstAlignOf *)*expr); break;