Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds bitwise operators: or, and, xor, and not #114

Merged
merged 1 commit into from Nov 30, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Makefile.am
Expand Up @@ -22,6 +22,9 @@ expression/hklr_op_mod.c \
expression/hklr_op_not_equal.c \
expression/hklr_op_equal.c \
expression/hklr_op_coalesce.c \
expression/hklr_op_bitwise_or.c \
expression/hklr_op_bitwise_and.c \
expression/hklr_op_bitwise_xor.c \
expression/hklr_as_integer.c \
expression/hklr_as_real.c \
expression/hklr_as_string.c \
Expand Down
56 changes: 56 additions & 0 deletions src/expression/hklr_op_bitwise_and.c
@@ -0,0 +1,56 @@
#include <assert.h>

#include "hkl_value.h"

HklValue* hklr_op_bitwise_and(HklValue* left_value, HklValue* right_value)
{
HklValue* result = NULL;
bool left_updated = false, right_updated = false;

// Dereference left and right sides
if (left_value->type == HKL_TYPE_REF)
{
left_updated = true;
left_value = hklr_object_dereference(left_value->as.object);
}

if (right_value->type == HKL_TYPE_REF)
{
right_updated = true;
right_value = hklr_object_dereference(right_value->as.object);
}

switch (left_value->type)
{
case HKL_TYPE_INT:
switch(right_value->type)
{
case HKL_TYPE_INT:
result = hkl_value_new(HKL_TYPE_INT,
left_value->as.integer & right_value->as.integer);
break;

case HKL_TYPE_REAL:
case HKL_TYPE_STRING:
default:
assert(false);
break;
}
break; // HKL_TYPE_INT
default:
assert(false);
break;
}

if (left_updated)
{
hkl_value_free(left_value);
}

if (right_updated)
{
hkl_value_free(right_value);
}

return result;
}
56 changes: 56 additions & 0 deletions src/expression/hklr_op_bitwise_or.c
@@ -0,0 +1,56 @@
#include <assert.h>

#include "hkl_value.h"

HklValue* hklr_op_bitwise_or(HklValue* left_value, HklValue* right_value)
{
HklValue* result = NULL;
bool left_updated = false, right_updated = false;

// Dereference left and right sides
if (left_value->type == HKL_TYPE_REF)
{
left_updated = true;
left_value = hklr_object_dereference(left_value->as.object);
}

if (right_value->type == HKL_TYPE_REF)
{
right_updated = true;
right_value = hklr_object_dereference(right_value->as.object);
}

switch (left_value->type)
{
case HKL_TYPE_INT:
switch(right_value->type)
{
case HKL_TYPE_INT:
result = hkl_value_new(HKL_TYPE_INT,
left_value->as.integer | right_value->as.integer);
break;

case HKL_TYPE_REAL:
case HKL_TYPE_STRING:
default:
assert(false);
break;
}
break; // HKL_TYPE_INT
default:
assert(false);
break;
}

if (left_updated)
{
hkl_value_free(left_value);
}

if (right_updated)
{
hkl_value_free(right_value);
}

return result;
}
56 changes: 56 additions & 0 deletions src/expression/hklr_op_bitwise_xor.c
@@ -0,0 +1,56 @@
#include <assert.h>

#include "hkl_value.h"

HklValue* hklr_op_bitwise_xor(HklValue* left_value, HklValue* right_value)
{
HklValue* result = NULL;
bool left_updated = false, right_updated = false;

// Dereference left and right sides
if (left_value->type == HKL_TYPE_REF)
{
left_updated = true;
left_value = hklr_object_dereference(left_value->as.object);
}

if (right_value->type == HKL_TYPE_REF)
{
right_updated = true;
right_value = hklr_object_dereference(right_value->as.object);
}

switch (left_value->type)
{
case HKL_TYPE_INT:
switch(right_value->type)
{
case HKL_TYPE_INT:
result = hkl_value_new(HKL_TYPE_INT,
left_value->as.integer ^ right_value->as.integer);
break;

case HKL_TYPE_REAL:
case HKL_TYPE_STRING:
default:
assert(false);
break;
}
break; // HKL_TYPE_INT
default:
assert(false);
break;
}

if (left_updated)
{
hkl_value_free(left_value);
}

if (right_updated)
{
hkl_value_free(right_value);
}

return result;
}
30 changes: 30 additions & 0 deletions src/hklr_expression.c
Expand Up @@ -30,6 +30,11 @@ extern HklValue* hklr_op_not_equal(HklValue* left_value, HklValue* right_value);
extern HklValue* hklr_op_equal(HklValue* left_value, HklValue* right_value);
extern HklValue* hklr_op_coalesce(HklValue* left_value, HklValue* right_value);

extern HklValue* hklr_op_bitwise_or(HklValue* left_value, HklValue* right_value);
extern HklValue* hklr_op_bitwise_and(HklValue* left_value, HklValue* right_value);
extern HklValue* hklr_op_bitwise_xor(HklValue* left_value, HklValue* right_value);


HklrExpression* hklr_expression_new(HklExpressionType type, ...)
{
assert(type != HKL_EXPR_NONE);
Expand Down Expand Up @@ -372,6 +377,19 @@ HklValue* hklr_expression_eval(HklrExpression* expr)
return hklr_op_typeof(value);
break; // HKL_OP_TYPE

case HKL_OP_BITWISE_NOT:
switch (value->type)
{
case HKL_TYPE_INT:
value->as.integer = ~value->as.integer;
return value;
break;

default:
assert(false);
break;
}

default:
assert(false);
break;
Expand Down Expand Up @@ -432,6 +450,18 @@ HklValue* hklr_expression_eval(HklrExpression* expr)
right_value->type = HKL_TYPE_NIL;
}
break;

case HKL_OP_BITWISE_AND:
result = hklr_op_bitwise_and(left_value, right_value);
break;
case HKL_OP_BITWISE_OR:
result = hklr_op_bitwise_or(left_value, right_value);
break;

case HKL_OP_BITWISE_XOR:
result = hklr_op_bitwise_xor(left_value, right_value);
break;

case HKL_OP_AS:
{
assert(right_value->type == HKL_TYPE_TYPE);
Expand Down
19 changes: 19 additions & 0 deletions src/y.tab.y
Expand Up @@ -442,6 +442,25 @@ expr:
{
$$ = hklr_expression_new(HKL_EXPR_BINARY, $1, HKL_OP_AS, $3);
}

| expr HKL_T_BITWISE_AND expr
{
$$ = hklr_expression_new(HKL_EXPR_BINARY, $1, HKL_OP_BITWISE_AND, $3);
}
| expr HKL_T_BITWISE_OR expr
{
$$ = hklr_expression_new(HKL_EXPR_BINARY, $1, HKL_OP_BITWISE_OR, $3);
}
| expr HKL_T_BITWISE_XOR expr
{
$$ = hklr_expression_new(HKL_EXPR_BINARY, $1, HKL_OP_BITWISE_XOR, $3);
}
| HKL_T_BITWISE_NOT expr %prec UNARY_OPS
{
$$ = hklr_expression_new(HKL_EXPR_UNARY, HKL_OP_BITWISE_NOT, $2);
}


| HKL_T_MINUS expr %prec UNARY_OPS
{
$$ = hklr_expression_new(HKL_EXPR_UNARY, HKL_OP_UNARY_MINUS, $2);
Expand Down