Commit 7d74dbb1 authored by Marius Bozga's avatar Marius Bozga
Browse files

added boolean xor, in array/string expressions

parent d9ade131
......@@ -311,6 +311,10 @@ inline void reset_func($1)
(type_name($1)& x);
inline int if_$1_length
(const type_name($1) x);
int if_$1_`index'
(const type_name($1) x, const type_name($2) e);
inline type_name(boolean) if_$1_in
(const type_name($2) e, const type_name($1) x);
`#define' iterate_func($1)(x)\
array_iterate($2,decr($4))')
......@@ -354,6 +358,18 @@ inline void reset_func($1)
inline int if_$1_length
(const type_name($1)) {
return $3;
}
int if_$1_`index'
(const type_name($1) x, const type_name($2) e) {
int idx = -1;
for(int i=0;i<$3 && idx<0;i++)
if (compare_func($2)(x[i],e)==0)
idx = i;
return idx;
}
inline type_name(boolean) if_$1_in
(const type_name($2) e, const type_name($1) x) {
return if_$1_`index'(x,e)==-1 ? if_boolean_false : if_boolean_true;
}')
......@@ -394,8 +410,8 @@ type_name($1) if_$1_remove
(const type_name($1) x, const int k);
type_name($1) if_$1_insert
(const type_name($1) x, const int k, const type_name($2) e);
int if_$1_`index'
(const type_name($1) x, const type_name($2) e);')
type_name(boolean) if_$1_in
(const type_name($2) e, const type_name($1) x);')
# string_type_impl(T,T1,n)
......@@ -437,7 +453,6 @@ inline void reset_func($1)
for(int i=0;i<$3;i++)
reset_func($2)(x.elem[i]);
}
inline int if_$1_length
(const type_name($1) x) {
return x.length;
......@@ -515,7 +530,12 @@ int if_$1_`index'
if (compare_func($2)(x.elem[i],e)==0)
idx = i;
return idx;
}')
}
inline type_name(boolean) if_$1_in
(const type_name($2) e, const type_name($1) x) {
return if_$1_`index'(x,e) == -1 ? if_boolean_false : if_boolean_true;
}
')
# ----------------------------------------------------------------#
......
......@@ -280,8 +280,10 @@ void IfCallExpression::PreCompile() {
m_pType = t0;
break;
case INDEX:
if (t0->IsString() &&
t1->Match(((IfStringType*) t0)->GetElement()))
if ((t0->IsString() &&
t1->Match(((IfStringType*) t0)->GetElement())) ||
(t0->IsArray() &&
t1->Match(((IfArrayType*) t1)->GetElement())))
m_pType = integer;
break;
case OBS_QLENGTH:
......@@ -1180,7 +1182,9 @@ IfBinaryExpression::OPERATOR[] = {
{ "=", "eq", 4, 2},
{ "<>", "ne", 4, 2},
{"and", "and", 5, 2},
{ "or", "or", 6, 2}
{ "or", "or", 6, 2},
{"xor", "xor", 6, 2},
{ "in", "in", 7, 2}
};
IfBinaryExpression::IfBinaryExpression(IfExpression* Left,
......@@ -1256,12 +1260,19 @@ void IfBinaryExpression::PreCompile() {
tl->GetBase() == tr->GetBase())
m_pType = boolean;
break;
case AND: case OR:
case AND: case OR: case XOR:
if (tl->Match(boolean) &&
tr->Match(boolean))
m_pType = boolean;
break;
}
case IN:
if ((tr->IsArray() &&
tl->Match(((IfArrayType*) tr)->GetElement())) ||
(tr->IsString() &&
tl->Match(((IfStringType*) tr)->GetElement())))
m_pType = boolean;
break;
}
/// time inference
......@@ -1291,6 +1302,9 @@ void IfBinaryExpression::Code(FILE* file) const {
else if (tl->Match(integer) || tr->Match(integer) || tl->Match(pid) || tr->Match(pid))
type = integer;
break;
case IN:
type = tr;
break;
default:
type = m_pType;
}
......
......@@ -504,7 +504,8 @@ class IfBinaryExpression : public IfExpression {
LT, LE, GE, GT,
EQ, NE,
AND,
OR,
OR, XOR,
IN
};
public:
......
......@@ -172,6 +172,7 @@ void { return VOID_K; }
with { return WITH_K; }
when { return WHEN_K; }
while { return WHILE_K; }
xor { return XOR_K; }
......
......@@ -291,7 +291,7 @@ void yywarning(const char* msg) {
%token VAR_K PUBLIC_K PRIVATE_K
%token VOID_K NOT_K UMIN_K ACTIVE_K TIMEVAL_K LENGTH_K
%token LE_K GE_K NE_K AND_K OR_K
%token LE_K GE_K NE_K AND_K OR_K XOR_K
%token INSTATE_K
%token INSTANCEOF_K
......@@ -327,7 +327,7 @@ void yywarning(const char* msg) {
%left ','
%left OR_K
%left OR_K XOR_K
%left AND_K
......@@ -616,6 +616,10 @@ expression :
{ $$ = new IfBinaryExpression($1, IfBinaryExpression::AND, $3); }
| expression OR_K expression
{ $$ = new IfBinaryExpression($1, IfBinaryExpression::OR, $3); }
| expression XOR_K expression
{ $$ = new IfBinaryExpression($1, IfBinaryExpression::XOR, $3); }
| expression IN_K expression
{ $$ = new IfBinaryExpression($1, IfBinaryExpression::IN, $3); }
| expression '?' expression ':' expression
{ $$ = new IfTernaryExpression(IfTernaryExpression::CONDITIONAL, $1, $3, $5); }
| '(' expression ')'
......
......@@ -68,6 +68,8 @@
#define if_boolean_or(x,y) (x)||(y)
#define if_boolean_xor(x,y) ((x)&&!(y))||(!(x)&&(y))
#define if_boolean_eq(x,y) (x)==(y)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment