From d9ade1311788dc619b84f1ee2c0ec21827563cc2 Mon Sep 17 00:00:00 2001 From: Marius Bozga <Marius.Bozga@univ-grenoble-alpes.fr> Date: Wed, 31 Mar 2021 16:24:10 +0200 Subject: [PATCH] Merge from IF2-B-Open:- allows for negative bounds in range types- implement the length operator for array types- fix type checking of call and conditional expressions --- src/code/type.m4 | 6 ++++++ src/model/expression.C | 36 ++++++++++++++++++------------------ src/model/expression.h | 4 ++-- src/model/if.yacc.y | 13 +++++++++++-- 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/code/type.m4 b/src/code/type.m4 index 0d6fea8..b5c6e17 100644 --- a/src/code/type.m4 +++ b/src/code/type.m4 @@ -309,6 +309,8 @@ inline void print_func($1) (const type_name($1) x, FILE* f); inline void reset_func($1) (type_name($1)& x); +inline int if_$1_length + (const type_name($1) x); `#define' iterate_func($1)(x)\ array_iterate($2,decr($4))') @@ -348,6 +350,10 @@ inline void reset_func($1) (type_name($1)& x) { for(int i=0;i<$3;i++) reset_func($2)(x[i]); +} +inline int if_$1_length + (const type_name($1)) { + return $3; }') diff --git a/src/model/expression.C b/src/model/expression.C index e0f4559..b5c3353 100644 --- a/src/model/expression.C +++ b/src/model/expression.C @@ -331,7 +331,7 @@ void IfCallExpression::PreCompile() { IfType* type = entity->GetTypes()->Find(m_pName); if (type != NULL) { m_eOperator = CONSTRUCTOR; - if (Match(type)) + if (Fulfil(type)) m_pType = type; else Protest("type mismatch"); @@ -349,7 +349,7 @@ void IfCallExpression::PreCompile() { IfAbstractType* abstract = (IfAbstractType*) type; for(int i = 0; i < abstract->GetFunctions()->GetCount(); i++) { IfFunction* function = abstract->GetFunctions()->GetAt(i); - if (MatchFunc(function)) { + if (Fulfil(function)) { if (m_pType == NULL) { m_eOperator = FUNCTION; m_pFunction = function; @@ -364,43 +364,43 @@ void IfCallExpression::PreCompile() { } } -int IfCallExpression::Match(const IfType* type) { - int match = 0; +int IfCallExpression::Fulfil(const IfType* type) { + int fulfil = 0; if (type->IsString()) { IfStringType* string = (IfStringType*) type; if (m_pParameters->GetCount() == 0) - match = 1; + fulfil = 1; if (m_pParameters->GetCount() == 1) { IfType* ptype = m_pParameters->GetAt(0)->GetType(); IfType* etype = string->GetElement(); - match = ptype->Match(etype); + fulfil = ptype->Match(etype); } } if (type->IsRecord()) { IfRecordType* record = (IfRecordType*) type; - match = m_pParameters->GetCount() == record->GetFields()->GetCount(); - for(int i = 0; i < m_pParameters->GetCount() && match; i++) { + fulfil = m_pParameters->GetCount() == record->GetFields()->GetCount(); + for(int i = 0; i < m_pParameters->GetCount() && fulfil; i++) { IfType* ptype = m_pParameters->GetAt(i)->GetType(); IfType* ftype = record->GetFields()->GetAt(i)->GetType(); - match &= ptype->Match(ftype); + fulfil &= ptype->Match(ftype); } } - return match; + return fulfil; } -int IfCallExpression::MatchFunc(const IfFunction* function) { - int match = +int IfCallExpression::Fulfil(const IfFunction* function) { + int fulfil = m_pParameters->GetCount() == function->GetParameters()->GetCount(); - for(int i = 0; i < m_pParameters->GetCount() && match; i++) { + for(int i = 0; i < m_pParameters->GetCount() && fulfil; i++) { IfType* ptype = m_pParameters->GetAt(i)->GetType(); IfType* ftype = function->GetParameters()->GetAt(i); - match &= ptype->Match(ftype); + fulfil &= ptype->Match(ftype); } - match &= strcmp(m_pName, function->GetName()) == 0; - return match; + fulfil &= strcmp(m_pName, function->GetName()) == 0; + return fulfil; } void IfCallExpression::Code(FILE* file) const { @@ -1114,7 +1114,7 @@ void IfUnaryExpression::PreCompile() { m_pType = (m_eOperator == ACTIVE) ? boolean : integer; break; case LENGTH: - if (tr->IsString()) + if (tr->IsArray() || tr->IsString()) m_pType = integer; break; case PLUS: case MINUS: @@ -1372,7 +1372,7 @@ void IfTernaryExpression::PreCompile() { switch (m_eOperator) { case CONDITIONAL: if (m_pTop->GetType()->Match(boolean) && - m_pLeft->GetType() == m_pRight->GetType()) + m_pLeft->GetType()->Match(m_pRight->GetType())) m_pType = m_pLeft->GetType(); break; case SUBSTRING: diff --git a/src/model/expression.h b/src/model/expression.h index 04c8305..7c4079b 100644 --- a/src/model/expression.h +++ b/src/model/expression.h @@ -243,8 +243,8 @@ class IfCallExpression : public IfExpression { virtual int Use(const IfVariable* Variable) const; protected: - virtual int Match(const IfType* Type); - virtual int MatchFunc(const IfFunction* Function); + int Fulfil(const IfType* Type); + int Fulfil(const IfFunction* Function); public: static Operator OPERATOR[]; diff --git a/src/model/if.yacc.y b/src/model/if.yacc.y index b356d82..e055253 100644 --- a/src/model/if.yacc.y +++ b/src/model/if.yacc.y @@ -211,7 +211,7 @@ void yywarning(const char* msg) { float probability; } -%type <constant> constant constant_decl constant_body constant_value +%type <constant> constant constant_decl constant_body constant_value range_bound %type <literal> enum_decl %type <literal_list> enum_decl_list @@ -418,7 +418,7 @@ type_body : type_value : ENUM_K enum_decl_list ENDENUM_K { $$ = new IfEnumType($2, NULL); } -| RANGE_K constant_body DDOT_K constant_body +| RANGE_K range_bound DDOT_K range_bound { $$ = new IfRangeType($2, $4, NULL); } | RECORD_K field_decl_set ENDRECORD_K { $$ = new IfRecordType($2, NULL); } @@ -456,6 +456,15 @@ type_list : -------------------------------------------------------------------- */ +range_bound : + constant_body { $$ = $1; } +| '-' integer { $$ = new IfIntegerConstant(-$2, NULL); } +; + +/* +-------------------------------------------------------------------- +*/ + enum_decl : constant_name { $$ = new IfEnumConstant($1); } ; -- GitLab