diff --git a/src/code/type.m4 b/src/code/type.m4 index b5c6e17259161bf1b47ee37052ff15c2cff12ebf..7844fe3d08734fbebc8e746ff5daed746da83aed 100644 --- a/src/code/type.m4 +++ b/src/code/type.m4 @@ -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; +} +') # ----------------------------------------------------------------# diff --git a/src/model/expression.C b/src/model/expression.C index b5c3353065377e92e2476571d1f3def8bb48b71c..b33f6b86e4625ae7a2b6e60a9588d6c69de24719 100644 --- a/src/model/expression.C +++ b/src/model/expression.C @@ -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; } diff --git a/src/model/expression.h b/src/model/expression.h index 7c4079b6cf2dfefda284277258e6db586894db79..6a1f4c6dd4e80e2918a8bc08ffc82748d6d8e6a7 100644 --- a/src/model/expression.h +++ b/src/model/expression.h @@ -504,7 +504,8 @@ class IfBinaryExpression : public IfExpression { LT, LE, GE, GT, EQ, NE, AND, - OR, + OR, XOR, + IN }; public: diff --git a/src/model/if.lex.l b/src/model/if.lex.l index 4a670bcc68f5051e2c742f1d21c603a0c71dba48..d99bdea974a3185871d856973b77a9bd3fece86b 100644 --- a/src/model/if.lex.l +++ b/src/model/if.lex.l @@ -172,6 +172,7 @@ void { return VOID_K; } with { return WITH_K; } when { return WHEN_K; } while { return WHILE_K; } +xor { return XOR_K; } diff --git a/src/model/if.yacc.y b/src/model/if.yacc.y index e055253d91a6353b0b1f4e76affa3d8b8768f850..e8e1c925b6e0bde002720e7387bafae2a589964c 100644 --- a/src/model/if.yacc.y +++ b/src/model/if.yacc.y @@ -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 ')' diff --git a/src/simulator/base.i b/src/simulator/base.i index 14028662126f18c608246cbda9c780650b101444..2fccdbcb9dd5ea2873cc4c0dfe0f127c3f5f3b2b 100644 --- a/src/simulator/base.i +++ b/src/simulator/base.i @@ -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)