From: Brendan Hansen Date: Sat, 19 Sep 2020 12:52:12 +0000 (-0500) Subject: added bitwise not operator X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=a1186025449f9a1c247b873376c454a1b96b0bf3;p=onyx.git added bitwise not operator --- diff --git a/CHANGELOG b/CHANGELOG index 1b18ec8e..8493ae48 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,10 +2,13 @@ Release v0.0.4 -------------- 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: diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 603b5a26..995b927e 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -193,6 +193,7 @@ typedef enum AstFlags { typedef enum UnaryOp { Unary_Op_Negate, Unary_Op_Not, + Unary_Op_Bitwise_Not, Unary_Op_Cast, } UnaryOp; diff --git a/onyx b/onyx index cf796673..9304849e 100755 Binary files a/onyx and b/onyx differ diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 7c238aff..107e469b 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -762,6 +762,15 @@ b32 check_unaryop(AstUnaryOp** punop) { 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 diff --git a/src/onyxparser.c b/src/onyxparser.c index 5519ee02..bdc363f5 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -306,6 +306,16 @@ static AstTyped* parse_factor(OnyxParser* parser) { 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, '*'); diff --git a/src/onyxutils.c b/src/onyxutils.c index f1099fb8..1d21ecba 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -293,6 +293,13 @@ AstNumLit* ast_reduce_binop(bh_allocator a, AstBinaryOp* node) { } \ 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); @@ -312,6 +319,7 @@ AstTyped* ast_reduce_unaryop(bh_allocator a, AstUnaryOp* unop) { 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; } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 2ea7e1bc..fa03b7d2 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -1289,6 +1289,26 @@ EMIT_FUNC(unaryop, AstUnaryOp* 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; } diff --git a/tests/i32map.onyx b/tests/i32map.onyx index 92385c87..a6f3e6f1 100644 --- a/tests/i32map.onyx +++ b/tests/i32map.onyx @@ -11,7 +11,6 @@ main :: proc (args: [] cstring) { print("Freeing map\n"); i32map_free(^imap); } - i32map_put(^imap, 50, "Hello "); i32map_put(^imap, 1234, "World!");