From 7e8eeef2477346dfe3fbc75482a5c588c1c79623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 7 Mar 2016 11:44:00 +0100 Subject: [PATCH] Add support for type variables in uniontypes --- Compiler/FrontEnd/Absyn.mo | 1 + Compiler/FrontEnd/ClassInf.mo | 39 +++------- Compiler/FrontEnd/DAE.mo | 8 ++- Compiler/FrontEnd/Expression.mo | 26 ++++--- Compiler/FrontEnd/Inst.mo | 94 +++++++++++-------------- Compiler/FrontEnd/Lookup.mo | 8 ++- Compiler/FrontEnd/MetaUtil.mo | 41 +++++++---- Compiler/FrontEnd/Patternm.mo | 17 ++--- Compiler/FrontEnd/SCode.mo | 2 + Compiler/FrontEnd/SCodeDump.mo | 2 +- Compiler/FrontEnd/SCodeUtil.mo | 18 +++-- Compiler/FrontEnd/Static.mo | 21 ++++-- Compiler/FrontEnd/Types.mo | 93 ++++++++++++++++-------- Compiler/FrontEnd/ValuesUtil.mo | 2 +- Compiler/Template/AbsynDumpTV.mo | 1 + Compiler/Template/AbsynDumpTpl.tpl | 2 +- Compiler/Template/CodegenCFunctions.tpl | 2 +- Compiler/Util/Error.mo | 6 ++ Compiler/Util/GC.mo | 5 ++ Compiler/boot/LoadCompilerSources.mos | 1 + 20 files changed, 224 insertions(+), 165 deletions(-) diff --git a/Compiler/FrontEnd/Absyn.mo b/Compiler/FrontEnd/Absyn.mo index d85b2ac32f1..6980d1e51b5 100644 --- a/Compiler/FrontEnd/Absyn.mo +++ b/Compiler/FrontEnd/Absyn.mo @@ -1041,6 +1041,7 @@ uniontype Restriction "These constructors each correspond to a different kind of Integer index; //Index in the uniontype Boolean singleton; Boolean moved; // true if moved outside uniontype, otherwise false. + list typeVars; end R_METARECORD; record R_UNKNOWN "Helper restriction" end R_UNKNOWN; /* added by simbj */ end Restriction; diff --git a/Compiler/FrontEnd/ClassInf.mo b/Compiler/FrontEnd/ClassInf.mo index 0254fdba510..a3686ca3bda 100644 --- a/Compiler/FrontEnd/ClassInf.mo +++ b/Compiler/FrontEnd/ClassInf.mo @@ -153,6 +153,7 @@ uniontype State "- Machine states, the string contains the classname." record META_UNIONTYPE Absyn.Path path; + list typeVars; end META_UNIONTYPE; record META_ARRAY @@ -435,7 +436,7 @@ algorithm then TYPE_CLOCK(p); case (SCode.R_PREDEFINED_ENUMERATION(),p) then TYPE_ENUM(p); /* Meta Modelica extensions */ - case (SCode.R_UNIONTYPE(),p) then META_UNIONTYPE(p); + case (SCode.R_UNIONTYPE(),p) then META_UNIONTYPE(p, inRestriction.typeVars); case (SCode.R_METARECORD(),p) then META_RECORD(p); end match; end start_dispatch; @@ -767,39 +768,15 @@ algorithm end match; end isRecord; -public function stateToSCodeRestriction -"@author: adrpo - ClassInf.State -> SCode.Restriction" +public function isMetaRecord input State inState; - output SCode.Restriction outRestriction; - output Absyn.Path outPath; + output Boolean outIsRecord; algorithm - (outRestriction, outPath) := match (inState) - local Absyn.Path p; Boolean isExpandable, isImpure; - - case UNKNOWN(p) then (SCode.R_CLASS(),p); - case OPTIMIZATION(p) then (SCode.R_OPTIMIZATION(),p); - case MODEL(p) then (SCode.R_MODEL(),p); - // mahge: TODO ClassInf.RECORD should contain isOperator. - case RECORD(p) then (SCode.R_RECORD(false),p); - case BLOCK(p) then (SCode.R_BLOCK(),p) ; - case CONNECTOR(p,isExpandable) then (SCode.R_CONNECTOR(isExpandable),p); - case TYPE(p) then (SCode.R_TYPE(),p); - case PACKAGE(p) then (SCode.R_PACKAGE(),p) ; - case FUNCTION(p,isImpure) then (SCode.R_FUNCTION(SCode.FR_NORMAL_FUNCTION(isImpure)),p); - case ENUMERATION(p) then (SCode.R_ENUMERATION(),p); - case TYPE_INTEGER(p) then (SCode.R_PREDEFINED_INTEGER(),p); - case TYPE_REAL(p) then (SCode.R_PREDEFINED_REAL(),p); - case TYPE_STRING(p) then (SCode.R_PREDEFINED_STRING(),p); - case TYPE_BOOL(p) then (SCode.R_PREDEFINED_BOOLEAN(),p); - // BTH - case TYPE_CLOCK(p) then (SCode.R_PREDEFINED_CLOCK(),p); - case TYPE_ENUM(p) then (SCode.R_PREDEFINED_ENUMERATION(),p); - /* Meta Modelica extensions */ - case META_UNIONTYPE(p) then (SCode.R_UNIONTYPE(),p); - case META_RECORD(p) then (SCode.R_METARECORD(p, 0, false, false),p); + outIsRecord := match inState + case META_RECORD() then true; + else false; end match; -end stateToSCodeRestriction; +end isMetaRecord; annotation(__OpenModelica_Interface="frontend"); end ClassInf; diff --git a/Compiler/FrontEnd/DAE.mo b/Compiler/FrontEnd/DAE.mo index a1c03c4f99c..02794396397 100644 --- a/Compiler/FrontEnd/DAE.mo +++ b/Compiler/FrontEnd/DAE.mo @@ -830,7 +830,7 @@ constant Type T_METATYPE_DEFAULT = T_METATYPE(T_UNKNOWN_DEFAULT, emptyTypeSou constant Type T_COMPLEX_DEFAULT = T_COMPLEX(ClassInf.UNKNOWN(Absyn.IDENT("")), {}, NONE(), emptyTypeSource) "default complex with unknown CiState"; constant Type T_COMPLEX_DEFAULT_RECORD = T_COMPLEX(ClassInf.RECORD(Absyn.IDENT("")), {}, NONE(), emptyTypeSource) "default complex with record CiState"; -constant Type T_SOURCEINFO_DEFAULT_METARECORD = T_METARECORD(Absyn.QUALIFIED("SourceInfo",Absyn.IDENT("SOURCEINFO")), 1, { +constant Type T_SOURCEINFO_DEFAULT_METARECORD = T_METARECORD(Absyn.QUALIFIED("SourceInfo",Absyn.IDENT("SOURCEINFO")), {}, 1, { TYPES_VAR("fileName", dummyAttrVar, T_STRING_DEFAULT, UNBOUND(), NONE()), TYPES_VAR("isReadOnly", dummyAttrVar, T_BOOL_DEFAULT, UNBOUND(), NONE()), TYPES_VAR("lineNumberStart", dummyAttrVar, T_INTEGER_DEFAULT, UNBOUND(), NONE()), @@ -839,7 +839,7 @@ constant Type T_SOURCEINFO_DEFAULT_METARECORD = T_METARECORD(Absyn.QUALIFIED("So TYPES_VAR("columnNumberEnd", dummyAttrVar, T_INTEGER_DEFAULT, UNBOUND(), NONE()), TYPES_VAR("lastModification", dummyAttrVar, T_REAL_DEFAULT, UNBOUND(), NONE()) }, true, emptyTypeSource); -constant Type T_SOURCEINFO_DEFAULT = T_METAUNIONTYPE({Absyn.QUALIFIED("SourceInfo",Absyn.IDENT("SOURCEINFO"))},true,EVAL_SINGLETON_KNOWN_TYPE(T_SOURCEINFO_DEFAULT_METARECORD),Absyn.IDENT("SourceInfo")::{}); +constant Type T_SOURCEINFO_DEFAULT = T_METAUNIONTYPE({Absyn.QUALIFIED("SourceInfo",Absyn.IDENT("SOURCEINFO"))},{},true,EVAL_SINGLETON_KNOWN_TYPE(T_SOURCEINFO_DEFAULT_METARECORD),Absyn.IDENT("SourceInfo")::{}); // Arrays of unknown dimension, eg. Real[:] public constant Type T_ARRAY_REAL_NODIM = T_ARRAY(T_REAL_DEFAULT,{DIM_UNKNOWN()}, emptyTypeSource); @@ -970,6 +970,7 @@ public uniontype Type "models the different front-end and back-end types" record T_METAUNIONTYPE "MetaModelica Uniontype, added by simbj" // TODO: You can't trust these fields as it seems MetaUtil.fixUniontype is sent empty elements when running dependency analysis list paths; + list typeVars; Boolean knownSingleton "The runtime system (dynload), does not know if the value is a singleton. But optimizations are safe if this is true."; EvaluateSingletonType singletonType; TypeSource source; @@ -979,6 +980,7 @@ public uniontype Type "models the different front-end and back-end types" Absyn.Path utPath "the path to its uniontype; this is what we match the type against"; // If the metarecord constructor was added to the FunctionTree, this would // not be needed. They are used to create the datatype in the runtime... + list typeVars; Integer index; //The index in the uniontype list fields; Boolean knownSingleton "The runtime system (dynload), does not know if the value is a singleton. But optimizations are safe if this is true."; @@ -1469,6 +1471,7 @@ uniontype Exp "Expressions list args; list fieldNames; Integer index; //Index in the uniontype + list typeVars; end METARECORDCALL; record MATCHEXPRESSION @@ -1619,6 +1622,7 @@ public uniontype Pattern "Patterns deconstruct expressions" Integer index; list patterns; list fields; // Needed to be able to bind a variable to the fields + list typeVars; Boolean knownSingleton "The runtime system (dynload), does not know if the value is a singleton. But optimizations are safe if this is true."; end PAT_CALL; record PAT_CALL_NAMED "RECORD(pat1,...,patn); all patterns are named" diff --git a/Compiler/FrontEnd/Expression.mo b/Compiler/FrontEnd/Expression.mo index 58d9ba01c24..febe9c873ca 100644 --- a/Compiler/FrontEnd/Expression.mo +++ b/Compiler/FrontEnd/Expression.mo @@ -2252,7 +2252,7 @@ algorithm Absyn.Path p; String msg; DAE.Type ty, iterTp, operTp; - list tys; + list tys, typeVars; Integer i,i1,i2; DAE.Dimension dim; DAE.Dimensions iterdims; @@ -2321,11 +2321,11 @@ algorithm then DAE.T_TUPLE(tys, NONE(), DAE.emptyTypeSource); case (DAE.META_OPTION(_))then DAE.T_METATYPE(DAE.T_NONE_DEFAULT, DAE.emptyTypeSource); - case (DAE.METARECORDCALL(path=p, index = i)) + case (DAE.METARECORDCALL(path=p, index = i, typeVars=typeVars)) equation then - DAE.T_METATYPE(DAE.T_METARECORD(p, i, {}, false, DAE.emptyTypeSource), DAE.emptyTypeSource); + DAE.T_METATYPE(DAE.T_METARECORD(p, typeVars, i, {}, false, DAE.emptyTypeSource), DAE.emptyTypeSource); case (DAE.BOX(e)) equation ty = typeof(e); @@ -5044,6 +5044,7 @@ algorithm DAE.ComponentRef cr, cr_1; list> aliases; DAE.ClockKind clk, clk1; + list typeVars; case DAE.EMPTY() equation (e, ext_arg) = inFunc(inExp, inExtArg); @@ -5269,9 +5270,9 @@ algorithm (e, ext_arg) = inFunc(e, ext_arg); then (e, ext_arg); - case DAE.METARECORDCALL(fn, expl, fieldNames, i) equation + case DAE.METARECORDCALL(fn, expl, fieldNames, i, typeVars) equation (expl_1, ext_arg) = traverseExpList(expl, inFunc, inExtArg); - e = if referenceEq(expl, expl_1) then inExp else DAE.METARECORDCALL(fn, expl_1, fieldNames, i); + e = if referenceEq(expl, expl_1) then inExp else DAE.METARECORDCALL(fn, expl_1, fieldNames, i, typeVars); (e, ext_arg) = inFunc(e, ext_arg); then (e, ext_arg); // --------------------- @@ -5641,6 +5642,7 @@ algorithm ComponentRef cr,cr_1; list> aliases; DAE.ClockKind clk, clk1; + list typeVars; case (false,_,_,_) then (inExp,inArg); case (_,DAE.ICONST(_),_,ext_arg) then (inExp,ext_arg); @@ -5818,10 +5820,10 @@ algorithm (cases, ext_arg) = Patternm.traverseCasesTopDown(cases, rel, ext_arg); then (DAE.MATCHEXPRESSION(matchType,expl,aliases,localDecls,cases,et),ext_arg); - case (_,DAE.METARECORDCALL(fn,expl,fieldNames,i),rel,ext_arg) + case (_,DAE.METARECORDCALL(fn,expl,fieldNames,i,typeVars),rel,ext_arg) equation (expl_1,ext_arg_1) = traverseExpListTopDown(expl, rel, ext_arg); - then (DAE.METARECORDCALL(fn,expl_1,fieldNames,i),ext_arg_1); + then (DAE.METARECORDCALL(fn,expl_1,fieldNames,i,typeVars),ext_arg_1); case (_,DAE.UNBOX(e1,tp),rel,ext_arg) equation @@ -6823,6 +6825,7 @@ algorithm DAE.CallAttributes attr; list> aliases; ArgT arg; + list typeVars; case DAE.ICONST() then (inExp, inArg); case DAE.RCONST() then (inExp, inArg); @@ -6985,11 +6988,11 @@ algorithm then (DAE.META_OPTION(oe1), arg); - case DAE.METARECORDCALL(path = path, args = expl, fieldNames = strl, index = index) + case DAE.METARECORDCALL(path = path, args = expl, fieldNames = strl, index = index, typeVars = typeVars) equation (expl, arg) = traverseExpListBidir(expl, inEnterFunc, inExitFunc, inArg); then - (DAE.METARECORDCALL(path, expl, strl, index), arg); + (DAE.METARECORDCALL(path, expl, strl, index, typeVars), arg); case DAE.MATCHEXPRESSION(matchType = match_ty, inputs = expl, aliases=aliases, localDecls = match_decls, cases = match_cases, et = ty) @@ -11758,6 +11761,7 @@ algorithm DAE.ReductionIterators riters,riters_1; DAE.ComponentRef cr,cr_1; list> aliases; + list typeVars; case ((e as DAE.EMPTY()),rel,ext_arg) equation @@ -12002,10 +12006,10 @@ algorithm (e,ext_arg) = rel(e,ext_arg); then (e,ext_arg); - case (DAE.METARECORDCALL(fn,expl,fieldNames,i),rel,ext_arg) + case (DAE.METARECORDCALL(fn,expl,fieldNames,i,typeVars),rel,ext_arg) equation (expl_1,ext_arg) = traverseExpDerPreStartList(expl, rel, ext_arg); - e = if referenceEq(expl,expl_1) then inExp else DAE.METARECORDCALL(fn,expl_1,fieldNames,i); + e = if referenceEq(expl,expl_1) then inExp else DAE.METARECORDCALL(fn,expl_1,fieldNames,i,typeVars); (e,ext_arg) = rel(e,ext_arg); then (e,ext_arg); // --------------------- diff --git a/Compiler/FrontEnd/Inst.mo b/Compiler/FrontEnd/Inst.mo index d15b7ac6b4c..ac0717753ba 100644 --- a/Compiler/FrontEnd/Inst.mo +++ b/Compiler/FrontEnd/Inst.mo @@ -2012,7 +2012,7 @@ algorithm SCode.ClassDef classDef; Option eq; DAE.Dimensions dims; - Absyn.Path cn; + Absyn.Path cn, fq_class; Option> ad; SCode.Mod mod; FCore.Cache cache; @@ -2040,6 +2040,7 @@ algorithm InstStateMachineUtil.SMNodeToFlatSMGroupTable smCompToFlatSM; //List> fieldDomLst; InstUtil.DomainFieldsLst domainFieldsLst; + list typeVars; // list> domainNLst; /*// uncomment for debugging @@ -2312,6 +2313,13 @@ algorithm eqConstraint = InstUtil.equalityConstraint(env5, els, info); ci_state6 = if isSome(ed) then ClassInf.assertTrans(ci_state6,ClassInf.FOUND_EXT_DECL(),info) else ci_state6; (cache,oty) = MetaUtil.fixUniontype(cache, env5, ci_state6, inClassDef6); + _ = match oty + case SOME(ty as DAE.T_METAUNIONTYPE(typeVars=_::_)) + algorithm + Error.addSourceMessage(Error.UNIONTYPE_MISSING_TYPEVARS, {Types.unparseType(ty)}, info); + then fail(); + else (); + end match; then (cache,env5,ih,store,dae,csets5,ci_state6,vars,oty,NONE(),eqConstraint,graph); @@ -2399,15 +2407,8 @@ algorithm SCode.DERIVED(typeSpec = Absyn.TPATH(path = cn,arrayDim = ad), modifications = mod, attributes=DA), re,vis,partialPrefix,encapsulatedPrefix,inst_dims,impl,callscope,graph,_,_,_,_,_) equation - // don't enter here - // false = true; false = Util.getStatefulBoolean(stopInst); - - // no meta-modelica - // false = Config.acceptMetaModelicaGrammar(); - // no types, enums or connectors please! false = valueEq(re, SCode.R_TYPE()); - // false = SCode.isFunctionRestriction(re); false = valueEq(re, SCode.R_ENUMERATION()); false = valueEq(re, SCode.R_PREDEFINED_ENUMERATION()); false = SCode.isConnector(re); @@ -2416,7 +2417,6 @@ algorithm (cache,SCode.CLASS(name=cn2,restriction=r),_) = Lookup.lookupClass(cache, env, cn, SOME(info)); false = InstUtil.checkDerivedRestriction(re, r, cn2); - // chain the redeclares mod = InstUtil.chainRedeclares(mods, mod); @@ -2428,16 +2428,11 @@ algorithm // print("mods: " + Absyn.pathString(cn) + " " + Mod.printModStr(mods_1) + "\n"); mods_1 = Mod.merge(mods, mod_1, className); - //print("DEF:--->" + FGraph.printGraphPathStr(env) + " = " + Absyn.pathString(cn) + " mods: " + Mod.printModStr(mods_1) + "\n"); - //System.startTimer(); - // use instExtends for derived with no array dimensions and no modification (given via the mods_1) (cache, env, ih, store, dae, csets, ci_state, vars, bc, oDA, eqConstraint, graph) = instClassdef2(cache, env, ih, store, mods_1, pre, ci_state, className, SCode.PARTS({SCode.EXTENDS(cn, vis, SCode.NOMOD(), NONE(), info)},{},{},{},{},{},{},NONE()), re, vis, partialPrefix, encapsulatedPrefix, inst_dims, impl, callscope, graph, inSets, instSingleCref,comment,info,stopInst); - //System.stopTimer(); - //print("DEF:<---" + FGraph.printGraphPathStr(env) + " took: " + realString(System.getTimerIntervalTime()) + "\n"); oDA = SCode.mergeAttributes(DA,oDA); then (cache,env,ih,store,dae,csets,ci_state,vars,bc,oDA,eqConstraint,graph); @@ -2453,48 +2448,20 @@ algorithm // not a basic type, change class name! false = InstUtil.checkDerivedRestriction(re, r, cn2); - // change the class name to className!! - // package A2=A - // package A3=A(mods) - // will get you different function implementations for the different packages! - /* - fullEnvPath = Absyn.selectPathsOpt(FGraph.getScopePath(env), Absyn.IDENT("")); - fullClassName = "DE_" + Absyn.pathStringReplaceDot(fullEnvPath, "_") + "_D_" + - Absyn.pathStringReplaceDot(Absyn.selectPathsOpt(FGraph.getScopePath(cenv), Absyn.IDENT("")), "_" ) + "." + cn2 + "_ED"; - fullClassName = System.stringReplace(fullClassName, ".", "_"); - - // open a scope with a unique name in the base class environment so there is no collision - cenv_2 = FGraph.openScope(cenv, enc2, SOME(fullClassName), FGraph.classInfToScopeType(ci_state)); - new_ci_state = ClassInf.start(r, FGraph.getGraphName(cenv_2)); - */ - // open a scope with the correct name - - // className = className + "|" + PrefixUtil.printPrefixStr(pre) + "|" + cn2; - cenv_2 = FGraph.openScope(cenv, enc2, SOME(className), FGraph.classInfToScopeType(ci_state)); new_ci_state = ClassInf.start(r, FGraph.getGraphName(cenv_2)); c = SCode.setClassName(className, c); - - //print("Derived Env: " + FGraph.printGraphPathStr(cenv_2) + "\n"); - // chain the redeclares mod = InstUtil.chainRedeclares(mods, mod); - // elab the modifiers in the parent environment! (parentEnv, _) = FGraph.stripLastScopeRef(env); (cache,mod_1) = Mod.elabMod(cache, parentEnv, ih, pre, mod, impl, Mod.DERIVED(cn), info); mods_1 = Mod.merge(mods, mod_1, className); - eq = Mod.modEquation(mods_1) "instantiate array dimensions" ; (cache,dims) = InstUtil.elabArraydimOpt(cache, parentEnv, Absyn.CREF_IDENT("",{}), cn, ad, eq, impl, NONE(), true, pre, info, inst_dims) "owncref not valid here" ; - // inst_dims2 = InstUtil.instDimExpLst(dims, impl); inst_dims_1 = List.appendLastList(inst_dims, dims); - - _ = Absyn.getArrayDimOptAsList(ad); - (cache,env_2,ih,store,dae,csets_1,ci_state_1,vars,bc,oDA,eqConstraint,graph) = instClassIn(cache, cenv_2, ih, store, mods_1, pre, new_ci_state, c, vis, - inst_dims_1, impl, callscope, graph, inSets, instSingleCref) "instantiate class in opened scope. " ; - + (cache,env_2,ih,store,dae,csets_1,ci_state_1,vars,bc,oDA,eqConstraint,graph) = instClassIn(cache, cenv_2, ih, store, mods_1, pre, new_ci_state, c, vis, inst_dims_1, impl, callscope, graph, inSets, instSingleCref) "instantiate class in opened scope. " ; ClassInf.assertValid(ci_state_1, re, info) "Check for restriction violations" ; oDA = SCode.mergeAttributes(DA,oDA); then @@ -2586,15 +2553,6 @@ algorithm Error.addSourceMessage(Error.META_POLYMORPHIC, {className}, info); then fail(); - case (_,_,_,_,_,_,_,_, - SCode.DERIVED(typeSpec=tSpec as Absyn.TCOMPLEX(arrayDim=SOME(_))), - _,_,_,_,_,_,_,_,_,_,_,_,_) - equation - true = Config.acceptMetaModelicaGrammar(); - cns = Dump.unparseTypeSpec(tSpec); - Error.addSourceMessage(Error.META_INVALID_COMPLEX_TYPE, {cns}, info); - then fail(); - case (cache,env,ih,store,mods,pre,ci_state,_, SCode.DERIVED(Absyn.TCOMPLEX(Absyn.IDENT(str),tSpecs,NONE()),modifications = mod, attributes=DA), re,vis,partialPrefix,encapsulatedPrefix,inst_dims,impl,_,graph,_,_,_,_,_) @@ -2604,6 +2562,38 @@ algorithm = instClassdef2(cache,env,ih,store,mods,pre,ci_state,className,SCode.DERIVED(Absyn.TCOMPLEX(Absyn.IDENT(str),tSpecs,NONE()),mod,DA),re,vis,partialPrefix,encapsulatedPrefix,inst_dims,impl,inCallingScope,graph,inSets,instSingleCref,comment,info,stopInst); then (outCache,outEnv,outIH,outStore,outDae,outSets,outState,outTypesVarLst,oty,optDerAttr,outEqualityConstraint,outGraph); + case (cache,env,ih,store,mods,pre,_,_, + SCode.DERIVED(Absyn.TCOMPLEX(cn,tSpecs,NONE()),modifications = mod, attributes=DA), + _,_,_,_,inst_dims,impl,_,graph,_,_,_,_,_) + equation + true = Config.acceptMetaModelicaGrammar(); + false = Util.getStatefulBoolean(stopInst); + true = Mod.emptyModOrEquality(mods) and SCode.emptyModOrEquality(mod); + false = listMember(Absyn.pathString(cn), {"tuple","Tuple","array","Array","Option","list","List"}); + (cache,(c as SCode.CLASS(name=cn2,encapsulatedPrefix=enc2,restriction=r as SCode.R_UNIONTYPE(typeVars=typeVars),classDef=classDef)),cenv) = Lookup.lookupClass(cache, env, cn, SOME(info)); + (cache,fq_class) = makeFullyQualified(cache,cenv,Absyn.IDENT(cn2)); + new_ci_state = ClassInf.META_UNIONTYPE(fq_class, typeVars); + (cache,SOME(ty as DAE.T_METAUNIONTYPE())) = MetaUtil.fixUniontype(cache, env, new_ci_state, classDef); + (cache,_,ih,tys,csets,oDA) = instClassDefHelper(cache,env,ih,tSpecs,pre,inst_dims,impl,{}, inSets,info); + tys = list(Types.boxIfUnboxedType(t) for t in tys); + if not (listLength(tys)==listLength(typeVars)) then + Error.addSourceMessage(Error.UNIONTYPE_WRONG_NUM_TYPEVARS,{Absyn.pathString(fq_class),String(listLength(typeVars)),String(listLength(tys))},info); + fail(); + end if; + ty = Types.setTypeVariables(ty, tys); + oDA = SCode.mergeAttributes(DA,oDA); + bc = SOME(ty); + then (cache,env,ih,store,DAE.emptyDae,csets,new_ci_state,{},bc,oDA,NONE(),graph); + + case (_,_,_,_,_,_,_,_, + SCode.DERIVED(typeSpec=tSpec as Absyn.TCOMPLEX(arrayDim=SOME(_))), + _,_,_,_,_,_,_,_,_,_,_,_,_) + equation + true = Config.acceptMetaModelicaGrammar(); + cns = Dump.unparseTypeSpec(tSpec); + Error.addSourceMessage(Error.META_INVALID_COMPLEX_TYPE, {cns}, info); + then fail(); + case (_,_,_,_,_,_,_,_, SCode.DERIVED(typeSpec=tSpec as Absyn.TCOMPLEX(path=cn,typeSpecs=tSpecs)), _,_,_,_,_,_,_,_,_,_,_,_,_) diff --git a/Compiler/FrontEnd/Lookup.mo b/Compiler/FrontEnd/Lookup.mo index 043dc5bf09f..8a30fbf896e 100644 --- a/Compiler/FrontEnd/Lookup.mo +++ b/Compiler/FrontEnd/Lookup.mo @@ -3169,8 +3169,10 @@ protected Boolean singleton; DAE.TypeSource ts; FCore.Cache cache; + list typeVarsType; + list typeVars; algorithm - SCode.CLASS(name=id,restriction=SCode.R_METARECORD(utPath,index,singleton),classDef=SCode.PARTS(elementLst = els)) := cdef; + SCode.CLASS(name=id,restriction=SCode.R_METARECORD(name=utPath,index=index,singleton=singleton,typeVars=typeVars),classDef=SCode.PARTS(elementLst = els)) := cdef; env := FGraph.openScope(inEnv, SCode.NOT_ENCAPSULATED(), SOME(id), SOME(FCore.CLASS_SCOPE())); // print("buildMetaRecordType " + id + " in scope " + FGraph.printGraphPathStr(env) + "\n"); (cache,utPath) := Inst.makeFullyQualified(inCache,env,utPath); @@ -3181,8 +3183,10 @@ algorithm ClassInf.META_RECORD(Absyn.IDENT("")), List.map1(els,Util.makeTuple,DAE.NOMOD()), {}, false, InstTypes.INNER_CALL(), ConnectionGraph.EMPTY, Connect.emptySet, true); varlst := Types.boxVarLst(varlst); + // for v in varlst loop print(Types.unparseType(v.ty)+"\n"); end for; ts := Types.mkTypeSource(SOME(path)); - ftype := DAE.T_METARECORD(utPath,index,varlst,singleton,ts); + typeVarsType := list(DAE.T_METAPOLYMORPHIC(tv,{}) for tv in typeVars); + ftype := DAE.T_METARECORD(utPath,typeVarsType,index,varlst,singleton,ts); // print("buildMetaRecordType " + id + " in scope " + FGraph.printGraphPathStr(env) + " OK " + Types.unparseType(ftype) +"\n"); end buildMetaRecordType; diff --git a/Compiler/FrontEnd/MetaUtil.mo b/Compiler/FrontEnd/MetaUtil.mo index d06550c40a0..c9056636510 100644 --- a/Compiler/FrontEnd/MetaUtil.mo +++ b/Compiler/FrontEnd/MetaUtil.mo @@ -48,6 +48,7 @@ import Error; import FGraph; import Flags; import List; +import MetaModelica.Dangerous; import Lookup; import Types; @@ -73,7 +74,8 @@ algorithm classes := c :: listAppend(meta_classes, classes); end for; - outProgram.classes := listReverse(classes); + outProgram.classes := Dangerous.listReverseInPlace(classes); + // print(Dump.unparseStr(outProgram)); then (); @@ -93,10 +95,12 @@ protected list parts; algorithm _ := match outClass + local + list typeVars; case Absyn.CLASS(restriction = Absyn.R_UNIONTYPE(), - body = body as Absyn.PARTS(classParts = parts)) + body = body as Absyn.PARTS(classParts = parts, typeVars=typeVars)) algorithm - (parts, outMetaClasses) := fixClassParts(parts, outClass.name); + (parts, outMetaClasses) := fixClassParts(parts, outClass.name, body.typeVars); body.classParts := parts; outClass.body := body; then @@ -105,7 +109,7 @@ algorithm case Absyn.CLASS(restriction = Absyn.R_UNIONTYPE(), body = body as Absyn.CLASS_EXTENDS(parts = parts)) algorithm - (parts, outMetaClasses) := fixClassParts(parts, outClass.name); + (parts, outMetaClasses) := fixClassParts(parts, outClass.name, {}); body.parts := parts; outClass.body := body; then @@ -213,6 +217,7 @@ end convertElementToClass; protected function fixClassParts input list inClassParts; input Absyn.Ident inClassName; + input list typeVars; output list outClassParts = {}; output list outMetaClasses = {}; protected @@ -222,7 +227,7 @@ algorithm outClassParts := list(match p case Absyn.PUBLIC() algorithm - (els, meta_classes) := fixElementItems(p.contents, inClassName); + (els, meta_classes) := fixElementItems(p.contents, inClassName, typeVars); p.contents := els; outMetaClasses := listAppend(meta_classes, outMetaClasses); then @@ -230,7 +235,7 @@ algorithm case Absyn.PROTECTED() algorithm - (els, meta_classes) := fixElementItems(p.contents, inClassName); + (els, meta_classes) := fixElementItems(p.contents, inClassName, typeVars); p.contents := els; outMetaClasses := listAppend(meta_classes, outMetaClasses); then @@ -243,6 +248,7 @@ end fixClassParts; protected function fixElementItems input list inElementItems; input String inName; + input list typeVars; output list outElementItems; output list outMetaClasses = {}; protected @@ -256,12 +262,19 @@ algorithm case Absyn.ELEMENTITEM(element = Absyn.ELEMENT(specification = Absyn.CLASSDEF(class_ = c as Absyn.CLASS(restriction = Absyn.R_RECORD())))) algorithm + _ := match body as c.body + case Absyn.PARTS(typeVars=_::_) + algorithm + Error.addSourceMessage(Error.METARECORD_WITH_TYPEVARS, {stringDelimitList(body.typeVars, ",")}, c.info); + then fail(); + else (); + end match; // Change the record into a metarecord and add it to the list of metaclasses. - r := Absyn.R_METARECORD(Absyn.IDENT(inName), index, singleton, true); + r := Absyn.R_METARECORD(Absyn.IDENT(inName), index, singleton, true, typeVars); c.restriction := r; outMetaClasses := c :: outMetaClasses; // Change the record into a metarecord and update the original class. - r := Absyn.R_METARECORD(Absyn.IDENT(inName), index, singleton, false); + r := Absyn.R_METARECORD(Absyn.IDENT(inName), index, singleton, false, typeVars); c.restriction := r; index := index + 1; then @@ -284,17 +297,18 @@ algorithm Boolean b; Absyn.Path p,p2; list paths; - list names; + list typeVarsTypes; + list names, typeVars; DAE.TypeSource ts; DAE.EvaluateSingletonType singletonType; SCode.Element c; FCore.Graph env_1; - case (ClassInf.META_UNIONTYPE(), SCode.PARTS()) + case (ClassInf.META_UNIONTYPE(typeVars=typeVars), SCode.PARTS()) algorithm p := Absyn.makeFullyQualified(inState.path); - names := SCode.elementNames(inClassDef.elementLst); - paths := list(Absyn.pathReplaceIdent(p, n) for n in names); + names := SCode.elementNames(list(e for e guard match e case SCode.CLASS(restriction=SCode.R_METARECORD()) then true; else false; end match in inClassDef.elementLst)); + paths := list(Absyn.suffixPath(p, n) for n in names); b := listLength(paths)==1; if b then p2 := listGet(paths, 1); @@ -302,9 +316,10 @@ algorithm else singletonType := DAE.NOT_SINGLETON(); end if; + typeVarsTypes := list(DAE.T_METAPOLYMORPHIC(tv,{}) for tv in typeVars); ts := Types.mkTypeSource(SOME(p)); then - SOME(DAE.T_METAUNIONTYPE(paths,b,singletonType,ts)); + SOME(DAE.T_METAUNIONTYPE(paths,typeVarsTypes,b,singletonType,ts)); else NONE(); end match; diff --git a/Compiler/FrontEnd/Patternm.mo b/Compiler/FrontEnd/Patternm.mo index ba4b06dc811..d12bf589773 100644 --- a/Compiler/FrontEnd/Patternm.mo +++ b/Compiler/FrontEnd/Patternm.mo @@ -464,7 +464,7 @@ algorithm list namedArgList,invalidArgs; list funcArgsNamedFixed,funcArgs; list fieldNameList,fieldNamesNamed; - list fieldTypeList; + list fieldTypeList, typeVars; list fieldVarList; list patterns; list> namedPatterns; @@ -474,7 +474,7 @@ algorithm case (cache,_,_,Absyn.FUNCTIONARGS(funcArgs,namedArgList),utPath2,_,_) algorithm - (cache,DAE.T_METARECORD(utPath=utPath1,index=index,fields=fieldVarList,knownSingleton = knownSingleton,source = {fqPath}),_) := + (cache,DAE.T_METARECORD(utPath=utPath1,index=index,fields=fieldVarList,typeVars=typeVars,knownSingleton = knownSingleton,source = {fqPath}),_) := Lookup.lookupType(cache, env, callPath, NONE()); validUniontype(utPath1,utPath2,info,lhs); @@ -517,7 +517,7 @@ algorithm funcArgs := listAppend(funcArgs,funcArgsNamedFixed); Util.SUCCESS() := checkInvalidPatternNamedArgs(invalidArgs,fieldNameList,Util.SUCCESS(),info); (cache,patterns) := elabPatternTuple(cache,env,funcArgs,fieldTypeList,info,lhs); - then (cache,DAE.PAT_CALL(fqPath,index,patterns,fieldVarList,knownSingleton)); + then (cache,DAE.PAT_CALL(fqPath,index,patterns,fieldVarList,typeVars,knownSingleton)); case (cache,_,_,Absyn.FUNCTIONARGS(funcArgs,namedArgList),utPath2,_,_) equation @@ -1535,7 +1535,7 @@ algorithm DAE.Pattern pat,pat1,pat2; list pats; list fields; - list types; + list types, typeVars; String id,str; Option ty; Absyn.Path name; @@ -1556,10 +1556,10 @@ algorithm pat = DAE.PAT_AS_FUNC_PTR(id,pat2); (pat,extra) = func(pat,extra); then (pat,extra); - case DAE.PAT_CALL(name,index,pats,fieldVars,knownSingleton) + case DAE.PAT_CALL(name,index,pats,fieldVars,typeVars,knownSingleton) equation (pats,extra) = traversePatternList(pats, func, extra); - pat = DAE.PAT_CALL(name,index,pats,fieldVars,knownSingleton); + pat = DAE.PAT_CALL(name,index,pats,fieldVars,typeVars,knownSingleton); (pat,extra) = func(pat,extra); then (pat,extra); case DAE.PAT_CALL_NAMED(name,namedpats) @@ -2776,10 +2776,11 @@ algorithm Integer index; Boolean knownSingleton; DAE.Attributes attr; - case (DAE.PAT_AS(id=id,attr=attr),DAE.PAT_CALL(index=index,fields=fields,knownSingleton=knownSingleton,name=name)) + list typeVars; + case (DAE.PAT_AS(id=id,attr=attr),DAE.PAT_CALL(index=index,typeVars=typeVars,fields=fields,knownSingleton=knownSingleton,name=name)) equation path = Absyn.stripLast(name); - ty = DAE.T_METARECORD(path,index,fields,knownSingleton,{name}); + ty = DAE.T_METARECORD(path,typeVars,index,fields,knownSingleton,{name}); env = FGraph.mkComponentNode(env, DAE.TYPES_VAR(id,attr,ty,DAE.UNBOUND(),NONE()), SCode.COMPONENT(id,SCode.defaultPrefixes,SCode.defaultVarAttr,Absyn.TPATH(name,NONE()),SCode.NOMOD(),SCode.noComment,NONE(),Absyn.dummyInfo), DAE.NOMOD(), FCore.VAR_DAE(), FGraph.empty()); then env; else env; diff --git a/Compiler/FrontEnd/SCode.mo b/Compiler/FrontEnd/SCode.mo index f13a107e3fc..30d7b5f770a 100644 --- a/Compiler/FrontEnd/SCode.mo +++ b/Compiler/FrontEnd/SCode.mo @@ -88,9 +88,11 @@ uniontype Restriction Integer index; //Index in the uniontype Boolean singleton; Boolean moved; // true if moved outside uniontype, otherwise false. + list typeVars; end R_METARECORD; /* added by x07simbj */ record R_UNIONTYPE "Metamodelica extension" + list typeVars; end R_UNIONTYPE; /* added by simbj */ end Restriction; diff --git a/Compiler/FrontEnd/SCodeDump.mo b/Compiler/FrontEnd/SCodeDump.mo index cae706715d3..5c18724d04c 100644 --- a/Compiler/FrontEnd/SCodeDump.mo +++ b/Compiler/FrontEnd/SCodeDump.mo @@ -165,7 +165,7 @@ algorithm case SCode.R_TYPE() then "type"; case SCode.R_PACKAGE() then "package"; case SCode.R_ENUMERATION() then "enumeration"; - case SCode.R_METARECORD() then "metarecord"; + case SCode.R_METARECORD() then "metarecord " + Absyn.pathString(inRestriction.name); case SCode.R_UNIONTYPE() then "uniontype"; // predefined types case SCode.R_PREDEFINED_INTEGER() then "Integer"; diff --git a/Compiler/FrontEnd/SCodeUtil.mo b/Compiler/FrontEnd/SCodeUtil.mo index 6bc74464c35..6ec48a0972e 100644 --- a/Compiler/FrontEnd/SCodeUtil.mo +++ b/Compiler/FrontEnd/SCodeUtil.mo @@ -150,7 +150,7 @@ algorithm equation // fprint(Flags.TRANSLATE, "Translating class:" + n + "\n"); r_1 = translateRestriction(c, r); // uniontype will not get translated! - (d_1,cmt) = translateClassdef(d,file_info); + (d_1,cmt) = translateClassdef(d,file_info,r_1); sFin = SCode.boolFinal(f); sEnc = SCode.boolEncapsulated(e); sPar = SCode.boolPartial(p); @@ -296,6 +296,7 @@ algorithm Integer index; Boolean singleton, isImpure, moved; Absyn.FunctionPurity purity; + list typeVars; // ?? Only normal functions can have 'external' case (d,Absyn.R_FUNCTION(Absyn.FR_NORMAL_FUNCTION(purity))) @@ -333,9 +334,10 @@ algorithm case (_,Absyn.R_PREDEFINED_CLOCK()) then SCode.R_PREDEFINED_CLOCK(); case (_,Absyn.R_PREDEFINED_ENUMERATION()) then SCode.R_PREDEFINED_ENUMERATION(); - case (_,Absyn.R_METARECORD(name,index,singleton,moved)) //MetaModelica extension, added by x07simbj - then SCode.R_METARECORD(name,index,singleton,moved); - case (_,Absyn.R_UNIONTYPE()) then SCode.R_UNIONTYPE(); /*MetaModelica extension added by x07simbj */ + case (_,Absyn.R_METARECORD(name,index,singleton,moved,typeVars)) //MetaModelica extension, added by x07simbj + then SCode.R_METARECORD(name,index,singleton,moved,typeVars); + case (Absyn.CLASS(body=Absyn.PARTS(typeVars=typeVars)),Absyn.R_UNIONTYPE()) then SCode.R_UNIONTYPE(typeVars); /*MetaModelica extension added by x07simbj */ + case (_,Absyn.R_UNIONTYPE()) then SCode.R_UNIONTYPE({}); /*MetaModelica extension added by x07simbj */ end match; end translateRestriction; @@ -428,6 +430,7 @@ protected function translateClassdef LS: Divided the translateClassdef into separate functions for collecting the different parts" input Absyn.ClassDef inClassDef; input SourceInfo info; + input SCode.Restriction re; output SCode.ClassDef outClassDef; output SCode.Comment outComment; algorithm @@ -471,6 +474,11 @@ algorithm case (Absyn.PARTS(typeVars = typeVars, classAttrs = classAttrs, classParts = parts,ann=ann,comment = cmtString),_) equation // fprintln(Flags.TRANSLATE, "translating class parts"); + typeVars = match re + case SCode.R_METARECORD() then List.union(typeVars, re.typeVars); + case SCode.R_UNIONTYPE() then List.union(typeVars, re.typeVars); + else typeVars; + end match; tvels = List.map1(typeVars, makeTypeVarElement, info); els = translateClassdefElements(parts); els = listAppend(tvels,els); @@ -1172,7 +1180,7 @@ algorithm equation // fprintln(Flags.TRANSLATE, "translating local class: " + n); re_1 = translateRestriction(cl, re); // uniontype will not get translated! - (de_1,cmt) = translateClassdef(de,i); + (de_1,cmt) = translateClassdef(de,i,re_1); (_, redecl) = translateRedeclarekeywords(repl); sRed = SCode.boolRedeclare(redecl); sFin = SCode.boolFinal(finalPrefix); diff --git a/Compiler/FrontEnd/Static.mo b/Compiler/FrontEnd/Static.mo index 82288339ac6..4bb73fd4a19 100644 --- a/Compiler/FrontEnd/Static.mo +++ b/Compiler/FrontEnd/Static.mo @@ -3695,7 +3695,7 @@ algorithm DAE.ICONST(info.columnNumberEnd), DAE.RCONST(info.lastModification) }; - outExp := DAE.METARECORDCALL(Absyn.QUALIFIED("SourceInfo",Absyn.IDENT("SOURCEINFO")),args,{"fileName","isReadOnly","lineNumberStart","columnNumberStart","lineNumberEnd","columnNumberEnd","lastEditTime"},0); + outExp := DAE.METARECORDCALL(Absyn.QUALIFIED("SourceInfo",Absyn.IDENT("SOURCEINFO")),args,{"fileName","isReadOnly","lineNumberStart","columnNumberStart","lineNumberEnd","columnNumberEnd","lastEditTime"},0,{}); then (inCache,outExp,DAE.PROP(DAE.T_SOURCEINFO_DEFAULT,DAE.C_CONST())); end match; end elabBuiltinSourceInfo; @@ -8025,12 +8025,12 @@ protected function elabCallArgsMetarecord output FCore.Cache outCache; output Option> expProps; algorithm - (outCache, expProps) := matchcontinue inType + (outCache, expProps) := matchcontinue ty as inType local Absyn.Path fq_path, ut_path; String str, fn_str; list field_names; - list tys; + list tys, typeVars; list fargs; list slots; list const_lst; @@ -8038,6 +8038,7 @@ algorithm DAE.TupleConst ty_const; DAE.Properties prop; list args; + InstTypes.PolymorphicBindings bindings; case DAE.T_METARECORD(source = {fq_path}) algorithm @@ -8062,16 +8063,24 @@ algorithm tys := list(Types.getVarType(var) for var in inType.fields); fargs := list(Types.makeDefaultFuncArg(n, t) threaded for n in field_names, t in tys); slots := makeEmptySlots(fargs); - (outCache, _, slots, const_lst) := elabInputArgs(inCache, inEnv, inPosArgs, + (outCache, _, slots, const_lst, bindings) := elabInputArgs(inCache, inEnv, inPosArgs, inNamedArgs, slots, true, true, inImplicit, NOT_EXTERNAL_OBJECT_MODEL_SCOPE(), inST, inPrefix, inInfo, inType, inType.utPath); const := List.fold(const_lst, Types.constAnd, DAE.C_CONST()); ty_const := elabConsts(inType, const); - prop := getProperties(inType, ty_const); true := List.fold(slots, slotAnd, true); args := slotListArgs(slots); + if not listEmpty(bindings) then + bindings := Types.solvePolymorphicBindings(bindings, inInfo, inType.source); + typeVars := list(Types.fixPolymorphicRestype(tv, bindings, inInfo) for tv in inType.typeVars); + ty.typeVars := typeVars; + prop := getProperties(ty, ty_const); + else + typeVars := inType.typeVars; + prop := getProperties(ty, ty_const); + end if; then - (outCache, SOME((DAE.METARECORDCALL(fq_path, args, field_names, inType.index), prop))); + (outCache, SOME((DAE.METARECORDCALL(fq_path, args, field_names, inType.index, inType.typeVars), prop))); // MetaRecord failure. case DAE.T_METARECORD(source = {fq_path}) diff --git a/Compiler/FrontEnd/Types.mo b/Compiler/FrontEnd/Types.mo index 4a34e18004d..09c60bf6c00 100644 --- a/Compiler/FrontEnd/Types.mo +++ b/Compiler/FrontEnd/Types.mo @@ -1144,7 +1144,7 @@ algorithm vars = valuesToVars(vl, ids); utPath = Absyn.stripLast(cname); then - DAE.T_METARECORD(utPath, index, vars, false /*We simply do not know...*/,{cname}); + DAE.T_METARECORD(utPath, {} /* typeVar? */, index, vars, false /*We simply do not know...*/,{cname}); // MetaModelica list type case Values.LIST(vl) @@ -1562,19 +1562,19 @@ algorithm then Absyn.pathEqual(p1,p2); case (DAE.T_METAUNIONTYPE(source = {p1}),DAE.T_METARECORD(utPath=p2)) - then Absyn.pathEqual(p1,p2); + then if Absyn.pathEqual(p1,p2) then subtypeTypelist(inType1.typeVars,inType2.typeVars,requireRecordNamesEqual) else false; // If the record is the only one in the uniontype, of course their types match case (DAE.T_METARECORD(knownSingleton=true,utPath = p1),DAE.T_METAUNIONTYPE(source={p2})) - then Absyn.pathEqual(p1,p2); + then if Absyn.pathEqual(p1,p2) then subtypeTypelist(inType1.typeVars,inType2.typeVars,requireRecordNamesEqual) else false; // = case (DAE.T_METAUNIONTYPE(source = {p1}), DAE.T_METAUNIONTYPE(source = {p2})) - then Absyn.pathEqual(p1,p2); + then if Absyn.pathEqual(p1,p2) then subtypeTypelist(inType1.typeVars,inType2.typeVars,requireRecordNamesEqual) else false; case (DAE.T_METAUNIONTYPE(source = {p1}), DAE.T_COMPLEX(complexClassType=ClassInf.META_UNIONTYPE(_), source = {p2})) - then Absyn.pathEqual(p1,p2); + then Absyn.pathEqual(p1,p2); // TODO: Remove? case(DAE.T_COMPLEX(complexClassType=ClassInf.META_UNIONTYPE(_), source = {p2}), DAE.T_METAUNIONTYPE(source = {p1})) - then Absyn.pathEqual(p1,p2); + then Absyn.pathEqual(p1,p2); // TODO: Remove? case (DAE.T_CODE(ty = c1),DAE.T_CODE(ty = c2)) then valueEq(c1,c2); @@ -2243,8 +2243,7 @@ algorithm case (DAE.T_METAUNIONTYPE(source = {p})) equation res = Absyn.pathStringNoQual(p); - then - res; + then if listEmpty(inType.typeVars) then res else (res+"<"+stringDelimitList(list(unparseType(tv) for tv in inType.typeVars), ",")+">"); // MetaModelica uniontype (but we know which record in the UT it is) /* @@ -4236,10 +4235,10 @@ algorithm (e_2,res) = matchTypeTuple(rest,ts1,ts2,printFailtrace); then (e_1::e_2,(tp :: res)); - case (_,(_ :: _),(_ :: _),true) + case (_,(t1 :: _),(t2 :: _),true) equation true = Flags.isSet(Flags.FAILTRACE); - Debug.trace("- Types.matchTypeTuple failed\n"); + Debug.trace("- Types.matchTypeTuple failed:"+Types.unparseType(t1)+" "+Types.unparseType(t2)+"\n"); then fail(); end matchcontinue; @@ -4813,7 +4812,7 @@ algorithm tys1 = List.map(v, getVarType); tys2 = List.map(tys1, boxIfUnboxedType); (elist,_) = matchTypeTuple(elist, tys1, tys2, printFailtrace); - e_1 = DAE.METARECORDCALL(path1, elist, l, -1); + e_1 = DAE.METARECORDCALL(path1, elist, l, -1, {}); then (e_1,t2); case (DAE.RECORD(path = path1, exps = elist), @@ -4828,18 +4827,9 @@ algorithm tys1 = List.map(v, getVarType); tys2 = List.map(tys1, boxIfUnboxedType); (elist,_) = matchTypeTuple(elist, tys1, tys2, printFailtrace); - e_1 = DAE.METARECORDCALL(path1, elist, l, -1); + e_1 = DAE.METARECORDCALL(path1, elist, l, -1, {}); then (e_1,t2); - case (DAE.CALL(), - DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_)), - DAE.T_METABOXED(),_) - equation - true = Flags.isSet(Flags.FAILTRACE); - Debug.trace("- Not yet implemented: Converting record calls (not constructor) into boxed records\n"); - then - fail(); - case (DAE.CREF(cref,_), t1 as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_), varLst = v, source = {path}), DAE.T_METABOXED(ty = t2),_) @@ -4855,9 +4845,18 @@ algorithm crefList = List.map1r(crefList, ComponentReference.joinCrefs, cref); elist = List.threadMap(crefList, expTypes, Expression.makeCrefExp); (elist,_) = matchTypeTuple(elist, tys1, tys2, printFailtrace); - e_1 = DAE.METARECORDCALL(path, elist, l, -1); + e_1 = DAE.METARECORDCALL(path, elist, l, -1, {}); then (e_1,t2); + case (e, + DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_)), + DAE.T_METABOXED(),_) + equation + true = Flags.isSet(Flags.FAILTRACE); + Debug.trace("- Not yet implemented: Converting record into boxed records: "+ExpressionDump.printExpStr(e)+"\n"); + then + fail(); + case (DAE.BOX(e),DAE.T_METABOXED(ty = t1),t2,_) equation true = subtype(t1,t2); @@ -5793,7 +5792,7 @@ algorithm case (DAE.T_METARECORD(knownSingleton=false,utPath = path1), DAE.T_METARECORD(knownSingleton=false,utPath=path2)) equation true = Absyn.pathEqual(path1,path2); - then DAE.T_METAUNIONTYPE({},false,DAE.NOT_SINGLETON(),{path1}); + then DAE.T_METAUNIONTYPE({},inType1.typeVars,false,DAE.NOT_SINGLETON(),{path1}); case (DAE.T_INTEGER(),DAE.T_REAL()) then DAE.T_REAL_DEFAULT; @@ -6075,6 +6074,9 @@ algorithm list cs; list ps; list> oe; + list paths; + Boolean knownSingleton; + DAE.EvaluateSingletonType singletonType; case (DAE.T_METAPOLYMORPHIC(name = id),_,_,_) equation @@ -6100,6 +6102,15 @@ algorithm t2 = boxIfUnboxedType(t2); then DAE.T_METAOPTION(t2,DAE.emptyTypeSource); + case (DAE.T_METAUNIONTYPE(typeVars={}),_,_,_) + then ty; + + case (DAE.T_METAUNIONTYPE(typeVars=tys),_,_,_) + equation + tys = List.map3(tys, fixPolymorphicRestype2, prefix, bindings, info); + tys = List.map(tys, boxIfUnboxedType); + then DAE.T_METAUNIONTYPE(ty.paths,tys,ty.knownSingleton,ty.singletonType,ty.source); + case (DAE.T_METATUPLE(types = tys),_,_,_) equation tys = List.map3(tys, fixPolymorphicRestype2, prefix, bindings, info); @@ -6206,8 +6217,9 @@ algorithm case DAE.T_METAOPTION(ty = ty) then {ty}; case DAE.T_TUPLE(types = tys) then tys; case DAE.T_METATUPLE(types = tys) then tys; - case DAE.T_METARECORD(fields = fields) - then List.map(fields, getVarType); + case DAE.T_METAUNIONTYPE(typeVars = tys) then tys; + case DAE.T_METARECORD(typeVars = tys, fields = fields) + then listAppend(tys, List.map(fields, getVarType)); case DAE.T_COMPLEX(varLst = fields) then List.map(fields, getVarType); case DAE.T_SUBTYPE_BASIC(varLst = fields) @@ -6453,9 +6465,10 @@ possible)." protected InstTypes.PolymorphicBindings unsolvedBindings; algorithm - // print("solvePoly " + Absyn.optPathString(path) + " " + polymorphicBindingsStr(bindings) + "\n"); + // print("solvePoly " + polymorphicBindingsStr(bindings) + "\n"); (solvedBindings,unsolvedBindings) := solvePolymorphicBindingsLoop(bindings, {}, {}); checkValidBindings(bindings, solvedBindings, unsolvedBindings, info, pathLst); + // print("solved poly " + polymorphicBindingsStr(solvedBindings) + "\n"); end solvePolymorphicBindings; protected function checkValidBindings @@ -6822,7 +6835,7 @@ algorithm case (DAE.T_METAUNIONTYPE(source = {path1}),DAE.T_METAUNIONTYPE(source = {path2})) equation true = Absyn.pathEqual(path1,path2); - then inBindings; + then subtypePolymorphicList(actual.typeVars, expected.typeVars, envPath, inBindings); case (DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ(path1)),DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ(path2))) equation @@ -7769,7 +7782,7 @@ algorithm Type funcRType; DAE.FunctionAttributes funcAttr; Boolean b; - list tys; + list tys, typeVars; DAE.CodeType ct; String str; @@ -7801,7 +7814,7 @@ algorithm algorithm t.source := ts; then t; - case (DAE.T_METARECORD(p, i, v, b, _), ts) then DAE.T_METARECORD(p, i, v, b, ts); + case (DAE.T_METARECORD(p, typeVars, i, v, b, _), ts) then DAE.T_METARECORD(p, typeVars, i, v, b, ts); case (DAE.T_METAARRAY(t, _), ts) then DAE.T_METAARRAY(t, ts); case (DAE.T_METABOXED(t, _), ts) then DAE.T_METABOXED(t, ts); case (DAE.T_METAPOLYMORPHIC(str, _), ts) then DAE.T_METAPOLYMORPHIC(str, ts); @@ -8196,7 +8209,7 @@ algorithm local Boolean b; Absyn.Path p; - case DAE.T_METARECORD(utPath=p,knownSingleton=b) then DAE.T_METAUNIONTYPE({},b,if b then DAE.EVAL_SINGLETON_KNOWN_TYPE(inTy) else DAE.NOT_SINGLETON(),{p}); + case DAE.T_METARECORD(utPath=p,knownSingleton=b) then DAE.T_METAUNIONTYPE({},inTy.typeVars,b,if b then DAE.EVAL_SINGLETON_KNOWN_TYPE(inTy) else DAE.NOT_SINGLETON(),{p}); else inTy; end match; end getUniontypeIfMetarecord; @@ -8215,7 +8228,7 @@ protected function getUniontypeIfMetarecordTraverse output Integer odummy = dummy; algorithm oty := match ty - case DAE.T_METARECORD() then DAE.T_METAUNIONTYPE({},ty.knownSingleton,if ty.knownSingleton then DAE.EVAL_SINGLETON_KNOWN_TYPE(ty) else DAE.NOT_SINGLETON(),{ty.utPath}); + case DAE.T_METARECORD() then DAE.T_METAUNIONTYPE({},ty.typeVars,ty.knownSingleton,if ty.knownSingleton then DAE.EVAL_SINGLETON_KNOWN_TYPE(ty) else DAE.NOT_SINGLETON(),{ty.utPath}); else ty; end match; end getUniontypeIfMetarecordTraverse; @@ -8910,5 +8923,23 @@ algorithm end match; end getMetaRecordIfSingleton; +public function setTypeVariables + input DAE.Type ty; + input list typeVars; + output DAE.Type oty; +algorithm + oty := match ty + case oty as DAE.T_METAUNIONTYPE() + algorithm + oty.typeVars := typeVars; + then oty; + case oty as DAE.T_METARECORD() + algorithm + oty.typeVars := typeVars; + then oty; + else ty; + end match; +end setTypeVariables; + annotation(__OpenModelica_Interface="frontend"); end Types; diff --git a/Compiler/FrontEnd/ValuesUtil.mo b/Compiler/FrontEnd/ValuesUtil.mo index c9cc31a0ab7..69819352271 100644 --- a/Compiler/FrontEnd/ValuesUtil.mo +++ b/Compiler/FrontEnd/ValuesUtil.mo @@ -927,7 +927,7 @@ algorithm explist = List.map(vallist, valueExp); typelist = List.map(vallist, Types.typeOfValue); (explist,_) = Types.matchTypeTuple(explist, typelist, List.map(typelist, Types.boxIfUnboxedType), true); - then DAE.METARECORDCALL(path,explist,namelst,ix); + then DAE.METARECORDCALL(path,explist,namelst,ix,{}); case (Values.META_FAIL()) then DAE.CALL(Absyn.IDENT("fail"),{},DAE.callAttrBuiltinOther); diff --git a/Compiler/Template/AbsynDumpTV.mo b/Compiler/Template/AbsynDumpTV.mo index 8c9e6b4c1d7..c492289f376 100644 --- a/Compiler/Template/AbsynDumpTV.mo +++ b/Compiler/Template/AbsynDumpTV.mo @@ -809,6 +809,7 @@ package Absyn Path name; Integer index; Boolean singleton; + list typeVars; end R_METARECORD; record R_UNKNOWN end R_UNKNOWN; end Restriction; diff --git a/Compiler/Template/AbsynDumpTpl.tpl b/Compiler/Template/AbsynDumpTpl.tpl index 53355d0f51a..d4080b90be5 100644 --- a/Compiler/Template/AbsynDumpTpl.tpl +++ b/Compiler/Template/AbsynDumpTpl.tpl @@ -159,7 +159,7 @@ match restriction case R_PREDEFINED_BOOLEAN(__) then "Boolean" case R_PREDEFINED_ENUMERATION(__) then "enumeration(:)" case R_UNIONTYPE(__) then "uniontype" - case R_METARECORD(__) then "metarecord" + case R_METARECORD(__) then 'metarecord<% if typeVars then ("<" + (typeVars |> tv => tv; separator=",") + ">") %>' case R_UNKNOWN(__) then "*unknown*" end dumpRestriction; diff --git a/Compiler/Template/CodegenCFunctions.tpl b/Compiler/Template/CodegenCFunctions.tpl index 5927baa5355..1804b3e39eb 100644 --- a/Compiler/Template/CodegenCFunctions.tpl +++ b/Compiler/Template/CodegenCFunctions.tpl @@ -389,7 +389,7 @@ template recordDeclaration(RecordDeclaration recDecl) << <%recordDefinition(dotPath(defPath), underscorePath(defPath), - (variables |> VARIABLE(__) => '"_<%crefStr(name)%>"' ;separator=","), + (variables |> VARIABLE(__) => '"<%crefStr(name)%>"' ;separator=","), listLength(variables))%> >> case RECORD_DECL_DEF(__) then diff --git a/Compiler/Util/Error.mo b/Compiler/Util/Error.mo index 5db96346b8f..e60972c0ddf 100644 --- a/Compiler/Util/Error.mo +++ b/Compiler/Util/Error.mo @@ -914,6 +914,12 @@ public constant Message IS_PRESENT_WRONG_DIRECTION = MESSAGE(5041, TRANSLATION() Util.gettext("isPresent needs to be called on an input or output formal parameter.")); public constant Message IS_PRESENT_INVALID_EXP = MESSAGE(5042, TRANSLATION(), ERROR(), Util.gettext("isPresent needs to be called on an input or output formal parameter, but got a non-identifier expression: %s.")); +public constant Message METARECORD_WITH_TYPEVARS = MESSAGE(5043, TRANSLATION(), ERROR(), + Util.gettext("Records inside uniontypes must not contain type variables (got: %s). Put them on the uniontype instead.")); +public constant Message UNIONTYPE_MISSING_TYPEVARS = MESSAGE(5044, TRANSLATION(), ERROR(), + Util.gettext("Uniontype %s has type variables, but they were not given in the declaration.")); +public constant Message UNIONTYPE_WRONG_NUM_TYPEVARS = MESSAGE(5045, TRANSLATION(), ERROR(), + Util.gettext("Uniontype %s has %s type variables, but got %s.")); public constant Message COMPILER_ERROR = MESSAGE(5999, TRANSLATION(), ERROR(), Util.notrans("%s")); diff --git a/Compiler/Util/GC.mo b/Compiler/Util/GC.mo index b23af0ee913..d540639a46f 100644 --- a/Compiler/Util/GC.mo +++ b/Compiler/Util/GC.mo @@ -47,6 +47,11 @@ function disable external "C" GC_disable() annotation(Library = {"omcgc"}); end disable; +function free + input T data; +external "C" GC_free(data) annotation(Library = {"omcgc"}); +end free; + function expandHeap input Real sz "To avoid the 32-bit signed limit on sizes"; output Boolean success; diff --git a/Compiler/boot/LoadCompilerSources.mos b/Compiler/boot/LoadCompilerSources.mos index f6f72cd0040..9664a4046f3 100644 --- a/Compiler/boot/LoadCompilerSources.mos +++ b/Compiler/boot/LoadCompilerSources.mos @@ -321,6 +321,7 @@ if true then /* Suppress output */ "../Util/BaseAvlTree.mo", "../Util/AvlTreeString2.mo", + // "../Util/Deque.mo", "../Util/DiffAlgorithm.mo", "../Util/FMI.mo", "../Util/FMIExt.mo",