Skip to content

Commit

Permalink
Adds bitwise operators: or, and, xor, and not
Browse files Browse the repository at this point in the history
  • Loading branch information
dasmoose committed Nov 30, 2012
1 parent 528f672 commit 40971cf
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 0 deletions.
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_not_equal.c \
expression/hklr_op_equal.c \ expression/hklr_op_equal.c \
expression/hklr_op_coalesce.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_integer.c \
expression/hklr_as_real.c \ expression/hklr_as_real.c \
expression/hklr_as_string.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_equal(HklValue* left_value, HklValue* right_value);
extern HklValue* hklr_op_coalesce(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, ...) HklrExpression* hklr_expression_new(HklExpressionType type, ...)
{ {
assert(type != HKL_EXPR_NONE); assert(type != HKL_EXPR_NONE);
Expand Down Expand Up @@ -372,6 +377,19 @@ HklValue* hklr_expression_eval(HklrExpression* expr)
return hklr_op_typeof(value); return hklr_op_typeof(value);
break; // HKL_OP_TYPE 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: default:
assert(false); assert(false);
break; break;
Expand Down Expand Up @@ -432,6 +450,18 @@ HklValue* hklr_expression_eval(HklrExpression* expr)
right_value->type = HKL_TYPE_NIL; right_value->type = HKL_TYPE_NIL;
} }
break; 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: case HKL_OP_AS:
{ {
assert(right_value->type == HKL_TYPE_TYPE); 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); $$ = 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 | HKL_T_MINUS expr %prec UNARY_OPS
{ {
$$ = hklr_expression_new(HKL_EXPR_UNARY, HKL_OP_UNARY_MINUS, $2); $$ = hklr_expression_new(HKL_EXPR_UNARY, HKL_OP_UNARY_MINUS, $2);
Expand Down

0 comments on commit 40971cf

Please sign in to comment.