--------------
Additions:
* Ability to pass complicated structs by value. Very useful in polymorphic data types.
+* bitwise not operator, ~
Removals:
Changes:
+* Procedure definitions now require parentheses, even if there are no arguments. This was
+ done to allow for `proc { foo, bar }` to be the overload syntax.
Bug fixes:
typedef enum UnaryOp {
Unary_Op_Negate,
Unary_Op_Not,
+ Unary_Op_Bitwise_Not,
Unary_Op_Cast,
} UnaryOp;
unaryop->type = unaryop->expr->type;
}
+ if (unaryop->operation == Unary_Op_Bitwise_Not) {
+ if (!type_is_integer(unaryop->expr->type)) {
+ onyx_report_error(unaryop->token->pos,
+ "Bitwise operator expected integer type, got '%s'.",
+ type_get_name(unaryop->expr->type));
+ return 1;
+ }
+ }
+
if (unaryop->expr->flags & Ast_Flag_Comptime) {
unaryop->flags |= Ast_Flag_Comptime;
// NOTE: Not a unary op
break;
}
+ case '~': {
+ AstUnaryOp* not_node = make_node(AstUnaryOp, Ast_Kind_Unary_Op);
+ not_node->operation = Unary_Op_Bitwise_Not;
+ not_node->token = expect_token(parser, '~');
+ not_node->expr = parse_factor(parser);
+
+ retval = (AstTyped *) not_node;
+ break;
+ }
+
case '*': {
AstDereference* deref_node = make_node(AstDereference, Ast_Kind_Dereference);
deref_node->token = expect_token(parser, '*');
} \
break;
+#define REDUCE_UNOP_INT(op) \
+ if (type_is_small_integer(unop->type) || type_is_bool(unop->type)) { \
+ res->value.i = op ((AstNumLit *) unop->expr)->value.i; \
+ } else if (type_is_integer(unop->type)) { \
+ res->value.l = op ((AstNumLit *) unop->expr)->value.l; \
+ }
+
AstTyped* ast_reduce_unaryop(bh_allocator a, AstUnaryOp* unop) {
unop->expr = ast_reduce(a, unop->expr);
if (type_is_bool(res->type)) res->value.i = ! ((AstNumLit *) unop->expr)->value.i;
break;
}
+ case Unary_Op_Bitwise_Not: REDUCE_UNOP_INT(~);
default: return (AstTyped *) unop;
}
WI(WI_I32_EQZ);
break;
+ case Unary_Op_Bitwise_Not: {
+ emit_expression(mod, &code, unop->expr);
+
+ TypeBasic* type = &unop->type->Basic;
+
+ if (type->kind == Basic_Kind_I32
+ || type->kind == Basic_Kind_I16
+ || type->kind == Basic_Kind_I8) {
+ WID(WI_I32_CONST, 0xffffffff);
+ WI(WI_I32_XOR);
+
+ }
+ else if (type->kind == Basic_Kind_I64) {
+ WIL(WI_I64_CONST, 0xffffffffffffffff);
+ WI(WI_I64_XOR);
+ }
+
+ break;
+ }
+
case Unary_Op_Cast: emit_cast(mod, &code, unop); break;
}
print("Freeing map\n");
i32map_free(^imap);
}
-
i32map_put(^imap, 50, "Hello ");
i32map_put(^imap, 1234, "World!");