Skip to content

Commit

Permalink
Add support for subscripted general expressions (#11448)
Browse files Browse the repository at this point in the history
- Add subscripted general expressions to the parser.
- Add parentheses to the output for subscripted expressions in
  `NFExpression.toString`, and fix the placement of the parentheses in
  `NFExpression.toFlatString`.
  • Loading branch information
perost committed Oct 25, 2023
1 parent c41724d commit 346282c
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 19 deletions.
4 changes: 2 additions & 2 deletions OMCompiler/Compiler/NFFrontEnd/NFExpression.mo
Expand Up @@ -1833,7 +1833,7 @@ public

case BOX() then "BOX(" + toString(exp.exp) + ")";
case UNBOX() then "UNBOX(" + toString(exp.exp) + ")";
case SUBSCRIPTED_EXP() then toString(exp.exp) + Subscript.toStringList(exp.subscripts);
case SUBSCRIPTED_EXP() then "(" + toString(exp.exp) + ")" + Subscript.toStringList(exp.subscripts);
case TUPLE_ELEMENT() then toString(exp.tupleExp) + "[" + intString(exp.index) + "]";
case RECORD_ELEMENT() then toString(exp.recordExp) + "[field: " + exp.fieldName + "]";
case MUTABLE() then toString(Mutable.access(exp.exp));
Expand Down Expand Up @@ -1980,7 +1980,7 @@ public
str := stringAppendList(strl);
end if;
else
str := "(" + toFlatString(exp) + Subscript.toFlatStringList(subscripts) + ")";
str := "(" + toFlatString(exp) + ")" + Subscript.toFlatStringList(subscripts);
end if;
end toFlatSubscriptedString;

Expand Down
Expand Up @@ -686,21 +686,21 @@ extern struct record_description NFType_NFType_ENUMERATION__desc;
#define NFType__ENUMERATION_3dBOX2 8
#define NFType__ENUMERATION(typePath,literals) (mmc_mk_box3(8,&NFType_NFType_ENUMERATION__desc,typePath,literals))
#ifdef ADD_METARECORD_DEFINITIONS
#ifndef NFType_NFType_ENUMERATION__ANY__desc_added
#define NFType_NFType_ENUMERATION__ANY__desc_added
ADD_METARECORD_DEFINITIONS const char* NFType_NFType_ENUMERATION__ANY__desc__fields[1] = {"no fields"};
ADD_METARECORD_DEFINITIONS struct record_description NFType_NFType_ENUMERATION__ANY__desc = {
"NFType_NFType_ENUMERATION__ANY",
"NFType.NFType.ENUMERATION_ANY",
NFType_NFType_ENUMERATION__ANY__desc__fields
#ifndef NFType_NFType_____ENUMERATION__ANY__NOT__USED______desc_added
#define NFType_NFType_____ENUMERATION__ANY__NOT__USED______desc_added
ADD_METARECORD_DEFINITIONS const char* NFType_NFType_____ENUMERATION__ANY__NOT__USED______desc__fields[1] = {"no fields"};
ADD_METARECORD_DEFINITIONS struct record_description NFType_NFType_____ENUMERATION__ANY__NOT__USED______desc = {
"NFType_NFType_____ENUMERATION__ANY__NOT__USED____",
"NFType.NFType.__ENUMERATION_ANY_NOT_USED__",
NFType_NFType_____ENUMERATION__ANY__NOT__USED______desc__fields
};
#endif
#else /* Only use the file as a header */
extern struct record_description NFType_NFType_ENUMERATION__ANY__desc;
extern struct record_description NFType_NFType_____ENUMERATION__ANY__NOT__USED______desc;
#endif
#define NFType__ENUMERATION_5fANY_3dBOX0 9
static const MMC_DEFSTRUCTLIT(NFType__ENUMERATION_5fANY__struct,1,9) {&NFType_NFType_ENUMERATION__ANY__desc}};
static void *NFType__ENUMERATION_5fANY = MMC_REFSTRUCTLIT(NFType__ENUMERATION_5fANY__struct);
#define NFType___5f_5fENUMERATION_5fANY_5fNOT_5fUSED_5f_5f_3dBOX0 9
static const MMC_DEFSTRUCTLIT(NFType___5f_5fENUMERATION_5fANY_5fNOT_5fUSED_5f_5f__struct,1,9) {&NFType_NFType_____ENUMERATION__ANY__NOT__USED______desc}};
static void *NFType___5f_5fENUMERATION_5fANY_5fNOT_5fUSED_5f_5f = MMC_REFSTRUCTLIT(NFType___5f_5fENUMERATION_5fANY_5fNOT_5fUSED_5f_5f__struct);
#ifdef ADD_METARECORD_DEFINITIONS
#ifndef NFType_NFType_ARRAY__desc_added
#define NFType_NFType_ARRAY__desc_added
Expand Down Expand Up @@ -870,6 +870,21 @@ extern struct record_description NFType_NFType_CONDITIONAL__ARRAY__desc;
#define NFType__CONDITIONAL_5fARRAY_3dBOX3 20
#define NFType__CONDITIONAL_5fARRAY(trueType,falseType,matchedBranch) (mmc_mk_box4(20,&NFType_NFType_CONDITIONAL__ARRAY__desc,trueType,falseType,matchedBranch))
#ifdef ADD_METARECORD_DEFINITIONS
#ifndef NFType_NFType_UNTYPED__desc_added
#define NFType_NFType_UNTYPED__desc_added
ADD_METARECORD_DEFINITIONS const char* NFType_NFType_UNTYPED__desc__fields[2] = {"typeNode","dimensions"};
ADD_METARECORD_DEFINITIONS struct record_description NFType_NFType_UNTYPED__desc = {
"NFType_NFType_UNTYPED",
"NFType.NFType.UNTYPED",
NFType_NFType_UNTYPED__desc__fields
};
#endif
#else /* Only use the file as a header */
extern struct record_description NFType_NFType_UNTYPED__desc;
#endif
#define NFType__UNTYPED_3dBOX2 21
#define NFType__UNTYPED(typeNode,dimensions) (mmc_mk_box3(21,&NFType_NFType_UNTYPED__desc,typeNode,dimensions))
#ifdef ADD_METARECORD_DEFINITIONS
#ifndef FMI_Info_INFO__desc_added
#define FMI_Info_INFO__desc_added
ADD_METARECORD_DEFINITIONS const char* FMI_Info_INFO__desc__fields[11] = {"fmiVersion","fmiType","fmiModelName","fmiModelIdentifier","fmiGuid","fmiDescription","fmiGenerationTool","fmiGenerationDateAndTime","fmiVariableNamingConvention","fmiNumberOfContinuousStates","fmiNumberOfEventIndicators"};
Expand Down Expand Up @@ -2848,6 +2863,21 @@ extern struct record_description Absyn_EqMod_NOMOD__desc;
static const MMC_DEFSTRUCTLIT(Absyn__NOMOD__struct,1,3) {&Absyn_EqMod_NOMOD__desc}};
static void *Absyn__NOMOD = MMC_REFSTRUCTLIT(Absyn__NOMOD__struct);
#ifdef ADD_METARECORD_DEFINITIONS
#ifndef Absyn_ElementArg_ELEMENTARGCOMMENT__desc_added
#define Absyn_ElementArg_ELEMENTARGCOMMENT__desc_added
ADD_METARECORD_DEFINITIONS const char* Absyn_ElementArg_ELEMENTARGCOMMENT__desc__fields[1] = {"comment"};
ADD_METARECORD_DEFINITIONS struct record_description Absyn_ElementArg_ELEMENTARGCOMMENT__desc = {
"Absyn_ElementArg_ELEMENTARGCOMMENT",
"Absyn.ElementArg.ELEMENTARGCOMMENT",
Absyn_ElementArg_ELEMENTARGCOMMENT__desc__fields
};
#endif
#else /* Only use the file as a header */
extern struct record_description Absyn_ElementArg_ELEMENTARGCOMMENT__desc;
#endif
#define Absyn__ELEMENTARGCOMMENT_3dBOX1 5
#define Absyn__ELEMENTARGCOMMENT(comment) (mmc_mk_box2(5,&Absyn_ElementArg_ELEMENTARGCOMMENT__desc,comment))
#ifdef ADD_METARECORD_DEFINITIONS
#ifndef Absyn_ElementArg_REDECLARATION__desc_added
#define Absyn_ElementArg_REDECLARATION__desc_added
ADD_METARECORD_DEFINITIONS const char* Absyn_ElementArg_REDECLARATION__desc__fields[6] = {"finalPrefix","redeclareKeywords","eachPrefix","elementSpec","constrainClass","info"};
Expand Down Expand Up @@ -3229,6 +3259,36 @@ extern struct record_description Absyn_Direction_INPUT__desc;
static const MMC_DEFSTRUCTLIT(Absyn__INPUT__struct,1,3) {&Absyn_Direction_INPUT__desc}};
static void *Absyn__INPUT = MMC_REFSTRUCTLIT(Absyn__INPUT__struct);
#ifdef ADD_METARECORD_DEFINITIONS
#ifndef Absyn_Exp_SUBSCRIPTED__EXP__desc_added
#define Absyn_Exp_SUBSCRIPTED__EXP__desc_added
ADD_METARECORD_DEFINITIONS const char* Absyn_Exp_SUBSCRIPTED__EXP__desc__fields[2] = {"exp","subscripts"};
ADD_METARECORD_DEFINITIONS struct record_description Absyn_Exp_SUBSCRIPTED__EXP__desc = {
"Absyn_Exp_SUBSCRIPTED__EXP",
"Absyn.Exp.SUBSCRIPTED_EXP",
Absyn_Exp_SUBSCRIPTED__EXP__desc__fields
};
#endif
#else /* Only use the file as a header */
extern struct record_description Absyn_Exp_SUBSCRIPTED__EXP__desc;
#endif
#define Absyn__SUBSCRIPTED_5fEXP_3dBOX2 28
#define Absyn__SUBSCRIPTED_5fEXP(exp,subscripts) (mmc_mk_box3(28,&Absyn_Exp_SUBSCRIPTED__EXP__desc,exp,subscripts))
#ifdef ADD_METARECORD_DEFINITIONS
#ifndef Absyn_Exp_EXPRESSIONCOMMENT__desc_added
#define Absyn_Exp_EXPRESSIONCOMMENT__desc_added
ADD_METARECORD_DEFINITIONS const char* Absyn_Exp_EXPRESSIONCOMMENT__desc__fields[3] = {"commentsBefore","exp","commentsAfter"};
ADD_METARECORD_DEFINITIONS struct record_description Absyn_Exp_EXPRESSIONCOMMENT__desc = {
"Absyn_Exp_EXPRESSIONCOMMENT",
"Absyn.Exp.EXPRESSIONCOMMENT",
Absyn_Exp_EXPRESSIONCOMMENT__desc__fields
};
#endif
#else /* Only use the file as a header */
extern struct record_description Absyn_Exp_EXPRESSIONCOMMENT__desc;
#endif
#define Absyn__EXPRESSIONCOMMENT_3dBOX3 27
#define Absyn__EXPRESSIONCOMMENT(commentsBefore,exp,commentsAfter) (mmc_mk_box4(27,&Absyn_Exp_EXPRESSIONCOMMENT__desc,commentsBefore,exp,commentsAfter))
#ifdef ADD_METARECORD_DEFINITIONS
#ifndef Absyn_Exp_DOT__desc_added
#define Absyn_Exp_DOT__desc_added
ADD_METARECORD_DEFINITIONS const char* Absyn_Exp_DOT__desc__fields[2] = {"exp","index"};
Expand Down
21 changes: 16 additions & 5 deletions OMCompiler/Parser/Modelica.g
Expand Up @@ -1696,7 +1696,7 @@ factor returns [void* ast]

primary returns [void* ast]
@declarations { int tupleExpressionIsTuple = 0; }
@init { v = 0; for_or_el.isFor = 0; OM_PUSHZ3(ptr.ast, el, for_or_el.ast) } :
@init { v = 0; for_or_el.isFor = 0; OM_PUSHZ4(ptr.ast, el, subs, for_or_el.ast) } :
( v=UNSIGNED_INTEGER
{
char* chars = (char*)$v.text->chars;
Expand Down Expand Up @@ -1785,14 +1785,25 @@ primary returns [void* ast]
| ptr=component_reference__function_call { $ast = ptr.ast; }
| DER el=function_call { $ast = Absyn__CALL(Absyn__CREF_5fIDENT(mmc_mk_scon("der"), mmc_mk_nil()),el,mmc_mk_nil()); }
| PURE el=function_call { $ast = Absyn__CALL(Absyn__CREF_5fIDENT(mmc_mk_scon("pure"), mmc_mk_nil()),el,mmc_mk_nil()); }
| LPAR el=output_expression_list[&tupleExpressionIsTuple]
| LPAR el=output_expression_list[&tupleExpressionIsTuple] subs=array_subscripts?
{
$ast = tupleExpressionIsTuple ? Absyn__TUPLE(el) :
if (subs) {
if (tupleExpressionIsTuple) {
ModelicaParser_lexerError = ANTLR3_TRUE;
c_add_source_message(NULL, 2, ErrorType_syntax, ErrorLevel_error, "Tuple expression can not be subscripted.",
NULL, 0, $start->line, $start->charPosition+1, LT(1)->line, LT(1)->charPosition,
ModelicaParser_readonly, ModelicaParser_filename_C_testsuiteFriendly);
} else {
$ast = Absyn__SUBSCRIPTED_5fEXP(el, subs);
}
} else {
$ast = tupleExpressionIsTuple ? Absyn__TUPLE(el) :
#if defined(OMC_BOOTSTRAPPING)
el;
el;
#else
Absyn__TUPLE(mmc_mk_cons(el, mmc_mk_nil()));
Absyn__TUPLE(mmc_mk_cons(el, mmc_mk_nil()));
#endif
}
}
| LBRACK el=matrix_expression_list RBRACK { $ast = Absyn__MATRIX(el); }
| LBRACE for_or_el=for_or_expression_list RBRACE
Expand Down
4 changes: 4 additions & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Expand Up @@ -1085,6 +1085,10 @@ SubscriptCevalIndexRange1.mo \
SubscriptCevalSlice1.mo \
SubscriptCevalSlice2.mo \
SubscriptCevalWhole1.mo \
SubscriptedExp1.mo \
SubscriptedExp2.mo \
SubscriptedExp3.mo \
SubscriptedExp4.mo \
SubscriptEnum1.mo \
SubscriptIterator1.mo \
SubscriptReduction1.mo \
Expand Down
15 changes: 15 additions & 0 deletions testsuite/flattening/modelica/scodeinst/SubscriptedExp1.mo
@@ -0,0 +1,15 @@
// name: SubscriptedExp1
// status: correct
// cflags: -d=newInst
//
//

model SubscriptedExp1
Real y = ({1, 2, 3})[2];
end SubscriptedExp1;

// Result:
// class SubscriptedExp1
// Real y = 2.0;
// end SubscriptedExp1;
// endResult
22 changes: 22 additions & 0 deletions testsuite/flattening/modelica/scodeinst/SubscriptedExp2.mo
@@ -0,0 +1,22 @@
// name: SubscriptedExp2
// status: incorrect
// cflags: -d=newInst
//
//

model SubscriptedExp2
Real y = (1, 2, 3)[2];
end SubscriptedExp2;

// Result:
// Error processing file: SubscriptedExp2.mo
// Failed to parse file: SubscriptedExp2.mo!
//
// [flattening/modelica/scodeinst/SubscriptedExp2.mo:8:12-8:23:writable] Error: Tuple expression can not be subscripted.
//
// # Error encountered! Exiting...
// # Please check the error message and the flags.
// Failed to parse file: SubscriptedExp2.mo!
//
// Execution failed!
// endResult
19 changes: 19 additions & 0 deletions testsuite/flattening/modelica/scodeinst/SubscriptedExp3.mo
@@ -0,0 +1,19 @@
// name: SubscriptedExp3
// status: correct
// cflags: -d=newInst
//
//

model SubscriptedExp3
Real y;
equation
({1, 2, 3})[3] = y;
end SubscriptedExp3;

// Result:
// class SubscriptedExp3
// Real y;
// equation
// 3.0 = y;
// end SubscriptedExp3;
// endResult
25 changes: 25 additions & 0 deletions testsuite/flattening/modelica/scodeinst/SubscriptedExp4.mo
@@ -0,0 +1,25 @@
// name: SubscriptedExp4
// status: correct
// cflags: -d=newInst
//
//

model SubscriptedExp4
Real x[:] = {1, 2, 3};
Integer n;
Real y = ({1, 2 ,3})[n];
Real z = (x)[n];
end SubscriptedExp4;

// Result:
// class SubscriptedExp4
// Real x[1];
// Real x[2];
// Real x[3];
// Integer n;
// Real y = {1.0, 2.0, 3.0}[n];
// Real z = x[n];
// equation
// x = {1.0, 2.0, 3.0};
// end SubscriptedExp4;
// endResult
2 changes: 1 addition & 1 deletion testsuite/openmodelica/flatmodelica/SD.mo
Expand Up @@ -58,7 +58,7 @@ end SD;
// 'c.x'[:,'c.N'[:]] = 'c.c.f'[:];
//
// for '$i1' in 1:3 loop
// for 'i' in 2:({3, 4, 5}['$i1']) loop
// for 'i' in 2:({3, 4, 5})['$i1'] loop
// 'c.x'['$i1','i'] = 'c.x'['$i1','i' - 1] + 'c.p'['$i1'];
// end for;
// end for;
Expand Down

0 comments on commit 346282c

Please sign in to comment.