diff --git a/src/FrontendUtil/ClassInf.jl b/src/FrontendUtil/ClassInf.jl deleted file mode 100644 index 4575064..0000000 --- a/src/FrontendUtil/ClassInf.jl +++ /dev/null @@ -1,213 +0,0 @@ -#= /* -* This file is part of OpenModelica. -* -* Copyright (c) 1998-2014, Open Source Modelica Consortium (OSMC), -* c/o Linköpings universitet, Department of Computer and Information Science, -* SE-58183 Linköping, Sweden. -* -* All rights reserved. -* -* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR -* THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2. -* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES -* RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3, -* ACCORDING TO RECIPIENTS CHOICE. -* -* The OpenModelica software and the Open Source Modelica -* Consortium (OSMC) Public License (OSMC-PL) are obtained -* from OSMC, either from the above address, -* from the URLs: http:www.ida.liu.se/projects/OpenModelica or -* http:www.openmodelica.org, and in the OpenModelica distribution. -* GNU version 3 is obtained from: http:www.gnu.org/copyleft/gpl.html. -* -* This program is distributed WITHOUT ANY WARRANTY; without -* even the implied warranty of MERCHANTABILITY or FITNESS -* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH -* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. -* -* See the full OSMC Public License conditions for more details. -* -*/ =# -module ClassInf - using MetaModelica - #= ExportAll is not good practice but it makes it so that we do not have to write export after each function :( =# - using ExportAll - #= Necessary to write declarations for your uniontypes until Julia adds support for mutually recursive types =# - - @UniontypeDecl SMNode - @UniontypeDecl Event - - import SCode - - import Absyn - - #= - Machine states, the string contains the classname. =# - @Uniontype SMNode begin - @Record UNKNOWN begin - - path::Absyn.Path - end - - @Record OPTIMIZATION begin - - path::Absyn.Path - end - - @Record MODEL begin - - path::Absyn.Path - end - - @Record RECORD begin - - path::Absyn.Path - end - - @Record BLOCK begin - - path::Absyn.Path - end - - @Record CONNECTOR begin - - path::Absyn.Path - isExpandable::Bool - end - - @Record TYPE begin - - path::Absyn.Path - end - - @Record PACKAGE begin - - path::Absyn.Path - end - - @Record FUNCTION begin - - path::Absyn.Path - isImpure::Bool - end - - @Record ENUMERATION begin - - path::Absyn.Path - end - - @Record HAS_RESTRICTIONS begin - - path::Absyn.Path - hasEquations::Bool - hasAlgorithms::Bool - hasConstraints::Bool - end - - @Record TYPE_INTEGER begin - - path::Absyn.Path - end - - @Record TYPE_REAL begin - - path::Absyn.Path - end - - @Record TYPE_STRING begin - - path::Absyn.Path - end - - @Record TYPE_BOOL begin - - path::Absyn.Path - end - - #= BTH - =# - - @Record TYPE_CLOCK begin - - path::Absyn.Path - end - - @Record TYPE_ENUM begin - - path::Absyn.Path - end - - @Record EXTERNAL_OBJ begin - - path::Absyn.Path - end - - #= /* MetaModelica extension */ =# - - @Record META_TUPLE begin - - path::Absyn.Path - end - - @Record META_LIST begin - - path::Absyn.Path - end - - @Record META_OPTION begin - - path::Absyn.Path - end - - @Record META_RECORD begin - - path::Absyn.Path - end - - @Record META_UNIONTYPE begin - - path::Absyn.Path - typeVars::List{String} - end - - @Record META_ARRAY begin - - path::Absyn.Path - end - - @Record META_POLYMORPHIC begin - - path::Absyn.Path - end - - #= /*---------------------*/ =# - end - - #= - Events =# - @Uniontype Event begin - @Record FOUND_EQUATION begin - - end - - @Record FOUND_ALGORITHM begin - - end - - @Record FOUND_CONSTRAINT begin - - end - - @Record FOUND_EXT_DECL begin - - end - - @Record NEWDEF begin - - end - - @Record FOUND_COMPONENT begin - - name #= name of the component =#::String - end - end - @exportAll() - end diff --git a/src/FrontendUtil/DAE.jl b/src/FrontendUtil/DAE.jl deleted file mode 100644 index 1bbc49c..0000000 --- a/src/FrontendUtil/DAE.jl +++ /dev/null @@ -1,2317 +0,0 @@ -#= /* -* This file is part of OpenModelica. -* -* Copyright (c) 1998-CurrentYear, Open Source Modelica Consortium (OSMC), -* c/o Linköpings universitet, Department of Computer and Information Science, -* SE-58183 Linköping, Sweden. -* -* All rights reserved. -* -* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR -* THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2. -* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES -* RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3, -* ACCORDING TO RECIPIENTS CHOICE. -* -* The OpenModelica software and the Open Source Modelica -* Consortium (OSMC) Public License (OSMC-PL) are obtained -* from OSMC, either from the above address, -* from the URLs: http:www.ida.liu.se/projects/OpenModelica or -* http:www.openmodelica.org, and in the OpenModelica distribution. -* GNU version 3 is obtained from: http:www.gnu.org/copyleft/gpl.html. -* -* This program is distributed WITHOUT ANY WARRANTY; without -* even the implied warranty of MERCHANTABILITY or FITNESS -* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH -* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. -* -* See the full OSMC Public License conditions for more details. -* -=# - -module DAE - -using MetaModelica -using ExportAll - -include("DAE_Interface.jl") - -import ..AbsynUtil -import ..ClassInf -import ..Values -import Absyn -import SCode - -const UNIQUEIO = "uniqueouter"::String - -const derivativeNamePrefix = "DER"::String - -const partialDerivativeNamePrefix = "pDER"::String - -const preNamePrefix = "PRE"::String - -const previousNamePrefix = "CLKPRE"::String - -const startNamePrefix = "START"::String - -const auxNamePrefix = "AUX"::String - -@Uniontype VarKind begin - @Record VARIABLE begin - - end - - @Record DISCRETE begin - - end - - @Record PARAM begin - - end - - @Record CONST begin - - end -end - -#= The type of a connector element. =# -@Uniontype ConnectorType begin - @Record POTENTIAL begin - - end - - @Record FLOW begin - - end - - @Record STREAM begin - - associatedFlow::Option{ComponentRef} - end - - @Record NON_CONNECTOR begin - - end -end - -@Uniontype VarDirection begin - @Record INPUT begin - - end - - @Record OUTPUT begin - - end - - @Record BIDIR begin - - end -end - -@Uniontype VarParallelism begin - @Record PARGLOBAL begin - - end - - @Record PARLOCAL begin - - end - - @Record NON_PARALLEL begin - - end -end - -@Uniontype VarVisibility begin - @Record PUBLIC begin - - end - - @Record PROTECTED begin - - end -end - -@Uniontype VarInnerOuter begin - @Record INNER begin - end - - @Record OUTER begin - end - - @Record INNER_OUTER begin - end - - @Record NOT_INNER_OUTER begin - end -end - -#= gives information about the origin of the element =# -@Uniontype ElementSource begin - @Record SOURCE begin - info #= the line and column numbers of the equations and algorithms this element came from =#::SourceInfo - partOfLst #= the model(s) this element came from =#::List{Absyn.Within} - instance #= the instance(s) this element is part of =# # TODO ::Prefix.ComponentPrefix - connectEquationOptLst #= this element came from this connect(s) =#::List{Tuple{ComponentRef, ComponentRef}} - typeLst #= the classes where the type(s) of the element is defined =#::List{Absyn.Path} - operations #= the symbolic operations used to end up with the final state of the element =#::List{SymbolicOperation} - comment::List{SCode.Comment} - end -end - -const emptyElementSource = SOURCE(AbsynUtil.dummyInfo, nil, nothing #= Prefix.NOCOMPPRE() =#, nil, nil, nil, nil)::ElementSource - -@Uniontype SymbolicOperation begin - @Record FLATTEN begin - - scode::SCode.EEquation - dae::Option{Element} - end - - @Record SIMPLIFY begin - - before::EquationExp - after::EquationExp - end - - @Record SUBSTITUTION begin - - substitutions::List{Exp} - source::Exp - end - - @Record OP_INLINE begin - - before::EquationExp - after::EquationExp - end - - @Record OP_SCALARIZE begin - - before::EquationExp - index::ModelicaInteger - after::EquationExp - end - - @Record OP_DIFFERENTIATE begin - - cr::ComponentRef - before::Exp - after::Exp - end - - @Record SOLVE begin - - cr::ComponentRef - exp1::Exp - exp2::Exp - res::Exp - assertConds::List{Exp} - end - - @Record SOLVED begin - - cr::ComponentRef - exp::Exp - end - - @Record LINEAR_SOLVED begin - - vars::List{ComponentRef} - jac::List{List{ModelicaReal}} - rhs::List{ModelicaReal} - result::List{ModelicaReal} - end - - @Record NEW_DUMMY_DER begin - - chosen::ComponentRef - candidates::List{ComponentRef} - end - - @Record OP_RESIDUAL begin - - e1::Exp - e2::Exp - e::Exp - end -end - -#= An equation on residual or equality form has 1 or 2 expressions. For use with symbolic operation tracing. =# -@Uniontype EquationExp begin - @Record PARTIAL_EQUATION begin - - exp::Exp - end - - @Record RESIDUAL_EXP begin - - exp::Exp - end - - @Record EQUALITY_EXPS begin - - lhs::Exp - rhs::Exp - end -end - -@Uniontype Function begin - @Record FUNCTION begin - - path::Absyn.Path - functions #= contains the body and an optional function derivative mapping =#::List{FunctionDefinition} - type_::Type - visibility::SCode.Visibility - partialPrefix #= MetaModelica extension =#::Bool - isImpure #= Modelica 3.3 impure/pure, by default isImpure = false all the time only if prefix *impure* function is specified =#::Bool - inlineType::InlineType - source #= the origin of the component/equation/algorithm =#::ElementSource - comment::Option{SCode.Comment} - end - - @Record RECORD_CONSTRUCTOR begin - - path::Absyn.Path - type_::Type - source #= the origin of the component/equation/algorithm =#::ElementSource - end -end - -@Uniontype InlineType begin - @Record NORM_INLINE begin - - end - - @Record BUILTIN_EARLY_INLINE begin - - end - - @Record EARLY_INLINE begin - - end - - @Record DEFAULT_INLINE begin - - end - - @Record NO_INLINE begin - - end - - @Record AFTER_INDEX_RED_INLINE begin - - end -end - -@Uniontype FunctionDefinition begin - @Record FUNCTION_DEF begin - - body::List{Element} - end - - @Record FUNCTION_EXT begin - - body::List{Element} - externalDecl::ExternalDecl - end - - @Record FUNCTION_DER_MAPPER begin - - derivedFunction #= Function that is derived =#::Absyn.Path - derivativeFunction #= Path to derivative function =#::Absyn.Path - derivativeOrder #= in case a function have multiple derivatives, include all =#::ModelicaInteger - conditionRefs::List{Tuple{ModelicaInteger, derivativeCond}} - defaultDerivative #= if conditions fails, use default derivative if exists =#::Option{Absyn.Path} - lowerOrderDerivatives::List{Absyn.Path} - end -end - -#= Different conditions on derivatives =# -@Uniontype derivativeCond begin - @Record ZERO_DERIVATIVE begin - - end - - @Record NO_DERIVATIVE begin - - binding::Exp - end -end - -@Uniontype VariableAttributes begin - @Record VAR_ATTR_REAL begin - - quantity #= quantity =#::Option{Exp} - unit #= unit =#::Option{Exp} - displayUnit #= displayUnit =#::Option{Exp} - min::Option{Exp} - max::Option{Exp} - start #= start value =#::Option{Exp} - fixed #= fixed - true: default for parameter/constant, false - default for other variables =#::Option{Exp} - nominal #= nominal =#::Option{Exp} - stateSelectOption::Option{StateSelect} - uncertainOption::Option{Uncertainty} - distributionOption::Option{Distribution} - equationBound::Option{Exp} - isProtected::Option{Bool} - finalPrefix::Option{Bool} - startOrigin #= where did start=X came from? NONE()|SOME(SCONST binding|type|undefined) =#::Option{Exp} - end - - @Record VAR_ATTR_INT begin - - quantity #= quantity =#::Option{Exp} - min::Option{Exp} - max::Option{Exp} - start #= start value =#::Option{Exp} - fixed #= fixed - true: default for parameter/constant, false - default for other variables =#::Option{Exp} - uncertainOption::Option{Uncertainty} - distributionOption::Option{Distribution} - equationBound::Option{Exp} - isProtected::Option{Bool} - #= ,eb,ip - =# - finalPrefix::Option{Bool} - startOrigin #= where did start=X came from? NONE()|SOME(SCONST binding|type|undefined) =#::Option{Exp} - end - - @Record VAR_ATTR_BOOL begin - - quantity #= quantity =#::Option{Exp} - start #= start value =#::Option{Exp} - fixed #= fixed - true: default for parameter/constant, false - default for other variables =#::Option{Exp} - equationBound::Option{Exp} - isProtected::Option{Bool} - finalPrefix::Option{Bool} - startOrigin #= where did start=X came from? NONE()|SOME(SCONST binding|type|undefined) =#::Option{Exp} - end - - @Record VAR_ATTR_CLOCK begin - - isProtected::Option{Bool} - finalPrefix::Option{Bool} - end - - @Record VAR_ATTR_STRING begin - - quantity #= quantity =#::Option{Exp} - start #= start value =#::Option{Exp} - fixed #= new in Modelica 3.4; fixed - true: default for parameter/constant, false - default for other variables =#::Option{Exp} - equationBound::Option{Exp} - isProtected::Option{Bool} - finalPrefix::Option{Bool} - startOrigin #= where did start=X came from? NONE()|SOME(SCONST binding|type|undefined) =#::Option{Exp} - end - - @Record VAR_ATTR_ENUMERATION begin - - quantity #= quantity =#::Option{Exp} - min::Option{Exp} - max::Option{Exp} - start #= start =#::Option{Exp} - fixed #= fixed - true: default for parameter/constant, false - default for other variables =#::Option{Exp} - equationBound::Option{Exp} - isProtected::Option{Bool} - finalPrefix::Option{Bool} - startOrigin #= where did start=X came from? NONE()|SOME(SCONST binding|type|undefined) =#::Option{Exp} - end -end - -const emptyVarAttrReal = VAR_ATTR_REAL(NONE(), NONE(), NONE(), NONE(), NONE(), NONE(), NONE(), NONE(), NONE(), NONE(), NONE(), NONE(), NONE(), NONE(), NONE())::VariableAttributes - -const emptyVarAttrBool = VAR_ATTR_BOOL(NONE(), NONE(), NONE(), NONE(), NONE(), NONE(), NONE())::VariableAttributes - -@Uniontype StateSelect begin - @Record NEVER begin - - end - - @Record AVOID begin - - end - - @Record DEFAULT begin - - end - - @Record PREFER begin - - end - - @Record ALWAYS begin - - end -end - -@Uniontype Uncertainty begin - @Record GIVEN begin - - end - - @Record SOUGHT begin - - end - - @Record REFINE begin - - end -end - -@Uniontype Distribution begin - @Record DISTRIBUTION begin - - name::Exp - params::Exp - paramNames::Exp - end -end - -@Uniontype ExtArg begin - @Record EXTARG begin - - componentRef::ComponentRef - direction::Absyn.Direction - type_::Type - end - - @Record EXTARGEXP begin - - exp::Exp - type_::Type - end - - @Record EXTARGSIZE begin - - componentRef::ComponentRef - type_::Type - exp::Exp - end - - @Record NOEXTARG begin - - end -end - -@Uniontype ExternalDecl begin - @Record EXTERNALDECL begin - - name::String - args::List{ExtArg} - returnArg::ExtArg - language::String - ann::Option{SCode.Annotation} - end -end - -" A DAE_LIST is a list of Elements. Variables, equations, functions, -algorithms, etc. are all found in this list. -" -struct DAE_LIST - elementLst::List{Element} -end - -#= /* -- Algorithm.mo -- */ =# - -#= The `Algorithm\\' type corresponds to a whole algorithm section. -It is simple a list of algorithm statements. =# -@Uniontype Algorithm begin - @Record ALGORITHM_STMTS begin - - statementLst::List{Statement} - end -end - -#= Optimica extension: The `Constraints\\' type corresponds to a whole Constraint section. -It is simple a list of expressions. =# -@Uniontype Constraint begin - @Record CONSTRAINT_EXPS begin - - constraintLst::List{Exp} - end - - @Record CONSTRAINT_DT begin - - constraint::Exp - localCon #= local or global constraint; local constraints depend on variables that are computed within the algebraic loop itself =#::Bool - end -end - -#= currently for Optimica extension: these are the objectives of optimization class =# -@Uniontype ClassAttributes begin - @Record OPTIMIZATION_ATTRS begin - - objetiveE::Option{Exp} - objectiveIntegrandE::Option{Exp} - startTimeE::Option{Exp} - finalTimeE::Option{Exp} - end -end - -#= /* TODO: create a backend and a simcode uniontype */ =# - -#= There are four kinds of statements: -1. assignments ('a := b;') -2. if statements ('if A then B; elseif C; else D;') -3. for loops ('for i in 1:10 loop ...; end for;') -4. when statements ('when E do S; end when;') =# -@Uniontype Statement begin - @Record STMT_ASSIGN begin - type_::Type - exp1::Exp - exp::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_TUPLE_ASSIGN begin - - type_::Type - expExpLst::List{Exp} - exp::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_ASSIGN_ARR begin - - type_::Type - lhs::Exp - exp::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_IF begin - - exp::Exp - statementLst::List{Statement} - else_::Else - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_FOR begin - - type_ #= this is the type of the iterator =#::Type - iterIsArray #= True if the iterator has an array type, otherwise false. =#::Bool - iter #= the iterator variable =#::String - index #= the index of the iterator variable, to make it unique; used by the new inst =#::ModelicaInteger - range #= range for the loop =#::Exp - statementLst::List{Statement} - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_PARFOR begin - - type_ #= this is the type of the iterator =#::Type - iterIsArray #= True if the iterator has an array type, otherwise false. =#::Bool - iter #= the iterator variable =#::String - index #= the index of the iterator variable, to make it unique; used by the new inst =#::ModelicaInteger - range #= range for the loop =#::Exp - statementLst::List{Statement} - loopPrlVars #= list of parallel variables used/referenced in the parfor loop =#::List{Tuple{ComponentRef, SourceInfo}} - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_WHILE begin - - exp::Exp - statementLst::List{Statement} - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_WHEN begin - - exp::Exp - conditions::List{ComponentRef} - #= list of boolean variables as conditions (this is simcode stuff) - =# - initialCall::Bool - #= true, if top-level branch with initial() (this is simcode stuff) - =# - statementLst::List{Statement} - elseWhen::Option{Statement} - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_ASSERT begin - - cond::Exp - msg::Exp - level::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_TERMINATE begin - - msg::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_REINIT begin - - var #= Variable =#::Exp - value #= Value =#::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_NORETCALL begin - - exp::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_RETURN begin - - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_BREAK begin - - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_CONTINUE begin - - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record STMT_ARRAY_INIT begin - - name::String - ty::Type - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - #= MetaModelica extension. KS - =# - - @Record STMT_FAILURE begin - - body::List{Statement} - source #= the origin of the component/equation/algorithm =#::ElementSource - end -end - -#= An if statements can one or more `elseif\\' branches and an -optional `else\\' branch. =# -@Uniontype Else begin - @Record NOELSE begin - - end - - @Record ELSEIF begin - - exp::Exp - statementLst::List{Statement} - else_::Else - end - - @Record ELSE begin - - statementLst::List{Statement} - end -end - -#= /* -- End Algorithm.mo -- */ =# -#= /* -- Start Types.mo -- */ =# - -#= - Variables =# -@Uniontype Var begin - @Record TYPES_VAR begin - - name #= name =#::String - attributes #= attributes =#::Attributes - ty #= type =#::Type - binding #= equation modification =#::Binding - constOfForIteratorRange #= the constant-ness of the range if this is a for iterator, NONE() if is NOT a for iterator =#::Option{Const} - end -end - -#= - Attributes =# -@Uniontype Attributes begin - @Record ATTR begin - - connectorType #= flow, stream or unspecified =#::ConnectorType - parallelism #= parallelism =#::SCode.Parallelism - variability #= variability =#::SCode.Variability - direction #= direction =#::Absyn.Direction - innerOuter #= inner, outer, inner outer or unspecified =#::Absyn.InnerOuter - visibility #= public, protected =#::SCode.Visibility - end -end - -const dummyAttrVar = ATTR(NON_CONNECTOR(), SCode.NON_PARALLEL(), SCode.VAR(), Absyn.BIDIR(), Absyn.NOT_INNER_OUTER(), SCode.PUBLIC())::Attributes -const dummyAttrParam = ATTR(NON_CONNECTOR(), SCode.NON_PARALLEL(), SCode.PARAM(), Absyn.BIDIR(), Absyn.NOT_INNER_OUTER(), SCode.PUBLIC())::Attributes -const dummyAttrConst = ATTR(NON_CONNECTOR(), SCode.NON_PARALLEL(), SCode.CONST(), Absyn.BIDIR(), Absyn.NOT_INNER_OUTER(), SCode.PUBLIC())::Attributes -const dummyAttrInput = ATTR(NON_CONNECTOR(), SCode.NON_PARALLEL(), SCode.VAR(), Absyn.INPUT(), Absyn.NOT_INNER_OUTER(), SCode.PUBLIC())::Attributes - -#= where this binding came from: either default binding or start value =# -@Uniontype BindingSource begin - @Record BINDING_FROM_DEFAULT_VALUE begin - - end - - @Record BINDING_FROM_START_VALUE begin - - end -end - -#=We do not care..=# -@Uniontype Binding begin - @Record UNBOUND begin - - end - - @Record EQBOUND begin - - exp::Exp - evaluatedExp::Option{Values.Value} - constant_::Const - source::BindingSource - end - - @Record VALBOUND begin - - valBound::Values.Value - source::BindingSource - end -end - -EqualityConstraint = Option #= contains the path to the equalityConstraint function, -the dimension of the output and the inline type of the function =# -#= default constants that can be used -=# - -#= models the different front-end and back-end types =# -@Uniontype Type begin - @Record T_INTEGER begin - - varLst::List{Var} - end - - @Record T_REAL begin - - varLst::List{Var} - end - - @Record T_STRING begin - - varLst::List{Var} - end - - @Record T_BOOL begin - - varLst::List{Var} - end - - @Record T_CLOCK begin - - varLst::List{Var} - #= BTH Since Clock type has no attributes, this is not really needed, but at the moment kept for unified treatment of fundamental types - =# - end - - @Record T_ENUMERATION begin - - index #= the enumeration value index, SOME for element, NONE() for type =#::Option{ModelicaInteger} - path #= enumeration path =#::Absyn.Path - names #= names =#::List{String} - literalVarLst::List{Var} - attributeLst::List{Var} - end - - @Record T_ARRAY begin - - ty #= Type =#::Type - dims #= dims =#::Dimensions - end - - @Record T_NORETCALL begin - - end - - @Record T_UNKNOWN begin - - end - - @Record T_COMPLEX begin - - complexClassType #= The type of a class =#::ClassInf.SMNode - varLst #= The variables of a complex type =#::List{Var} - equalityConstraint::EqualityConstraint - end - - @Record T_SUBTYPE_BASIC begin - - complexClassType #= The type of a class =#::ClassInf.SMNode - varLst #= complexVarLst; The variables of a complex type! Should be empty, kept here to verify! =#::List{Var} - complexType #= complexType; A complex type can be a subtype of another (primitive) type (through extends) =#::Type - equalityConstraint::EqualityConstraint - end - - @Record T_FUNCTION begin - - funcArg #= funcArg =#::List{FuncArg} - funcResultType #= Only single-result =#::Type - functionAttributes::FunctionAttributes - path::Absyn.Path - end - - @Record T_FUNCTION_REFERENCE_VAR begin - - functionType #= the type of the function =#::Type - end - - @Record T_FUNCTION_REFERENCE_FUNC begin - - builtin::Bool - functionType #= type of the non-boxptr function =#::Type - end - - @Record T_TUPLE begin - - types #= For functions returning multiple values. =#::List{Type} - names #= For tuples elements that have names (function outputs) =#::Option{List{String}} - end - - @Record T_CODE begin - - ty::CodeType - end - - @Record T_ANYTYPE begin - - anyClassType #= anyClassType - used for generic types. When class state present the type is assumed to be a complex type which has that restriction. =#::Option{ClassInf.SMNode} - end - - #= MetaModelica extensions - =# - - @Record T_METALIST begin - - ty #= listType =#::Type - end - - @Record T_METATUPLE begin - - types::List{Type} - end - - @Record T_METAOPTION begin - - ty::Type - end - - @Record T_METAUNIONTYPE begin - - #= TODO: You can't trust these fields as it seems MetaUtil.fixUniontype is sent empty elements when running dependency analysis - =# - paths::List{Absyn.Path} - typeVars::List{Type} - knownSingleton #= The runtime system (dynload), does not know if the value is a singleton. But optimizations are safe if this is true. =#::Bool - singletonType::EvaluateSingletonType - path::Absyn.Path - end - - @Record T_METARECORD begin - - path #= the path to the record =#::Absyn.Path - utPath #= the path to its uniontype; this is what we match the type against =#::Absyn.Path - #= If the metarecord constructor was added to the FunctionTree, this would - =# - #= not be needed. They are used to create the datatype in the runtime... - =# - typeVars::List{Type} - index::ModelicaInteger - #= The index in the uniontype - =# - fields::List{Var} - knownSingleton #= The runtime system (dynload), does not know if the value is a singleton. But optimizations are safe if this is true. =#::Bool - end - - @Record T_METAARRAY begin - - ty::Type - end - - @Record T_METABOXED begin - - ty::Type - end - - @Record T_METAPOLYMORPHIC begin - - name::String - end - - @Record T_METATYPE begin - - ty::Type - end -end - -@Uniontype CodeType begin - @Record C_EXPRESSION begin - end - - @Record C_EXPRESSION_OR_MODIFICATION begin - end - - @Record C_MODIFICATION begin - end - - @Record C_TYPENAME begin - end - - @Record C_VARIABLENAME begin - end - - @Record C_VARIABLENAMES begin - end -end - -#= Is here because constants are not allowed to contain function pointers for some reason =# -@Uniontype EvaluateSingletonType begin - @Record EVAL_SINGLETON_TYPE_FUNCTION begin - fun::EvaluateSingletonTypeFunction - end - - @Record EVAL_SINGLETON_KNOWN_TYPE begin - ty::Type - end - - @Record NOT_SINGLETON begin - end -end - -@Uniontype FunctionAttributes begin - @Record FUNCTION_ATTRIBUTES begin - - inline::InlineType - isOpenModelicaPure #= if the function has __OpenModelica_Impure =#::Bool - isImpure #= if the function has prefix *impure* is true, else false =#::Bool - isFunctionPointer #= if the function is a local variable =#::Bool - isBuiltin::FunctionBuiltin - functionParallelism::FunctionParallelism - end -end - -@Uniontype FunctionBuiltin begin - @Record FUNCTION_NOT_BUILTIN begin - - end - - @Record FUNCTION_BUILTIN begin - - name::Option{String} - unboxArgs::Bool - end - - @Record FUNCTION_BUILTIN_PTR begin - - end -end - -#= This was a function restriction in SCode and Absyn -=# -#= Now it is part of function attributes. -=# - -@Uniontype FunctionParallelism begin - @Record FP_NON_PARALLEL begin - - end - - @Record FP_PARALLEL_FUNCTION begin - - end - - @Record FP_KERNEL_FUNCTION begin - - end -end - -const FUNCTION_ATTRIBUTES_BUILTIN = FUNCTION_ATTRIBUTES(NO_INLINE(), true, false, false, FUNCTION_BUILTIN(NONE(), false), FP_NON_PARALLEL())::FunctionAttributes - -const FUNCTION_ATTRIBUTES_DEFAULT = FUNCTION_ATTRIBUTES(DEFAULT_INLINE(), true, false, false, FUNCTION_NOT_BUILTIN(), FP_NON_PARALLEL())::FunctionAttributes - -const FUNCTION_ATTRIBUTES_IMPURE = FUNCTION_ATTRIBUTES(NO_INLINE(), false, true, false, FUNCTION_NOT_BUILTIN(), FP_NON_PARALLEL())::FunctionAttributes - -const FUNCTION_ATTRIBUTES_BUILTIN_IMPURE = FUNCTION_ATTRIBUTES(NO_INLINE(), false, true, false, FUNCTION_BUILTIN(NONE(), false), FP_NON_PARALLEL())::FunctionAttributes - - -@Uniontype Dimension begin - @Record DIM_INTEGER begin - - integer::ModelicaInteger - end - - @Record DIM_BOOLEAN begin - - end - - @Record DIM_ENUM begin - - enumTypeName #= The enumeration type name. =#::Absyn.Path - literals #= A list of the literals in the enumeration. =#::List{String} - size #= The size of the enumeration. =#::ModelicaInteger - end - - @Record DIM_EXP begin - - exp::Exp - end - - @Record DIM_UNKNOWN begin - - #= DimensionBinding dimensionBinding \"unknown dimension can be bound or unbound\"; - =# - end -end - -#= adrpo: this is used to bind unknown dimensions to an expression -=# -#= and when we do subtyping we add constrains to this expression. -=# -#= this should be used for typechecking with unknown dimensions -=# -#= when running checkModel. the binding acts like a type variable. -=# - -@Uniontype DimensionBinding begin - @Record DIM_UNBOUND begin - - end - - @Record DIM_BOUND begin - - binding #= the dimension is bound to this expression =#::Exp - constrains #= the bound has these constrains (collected when doing subtyping) =#::Dimensions - end -end - -@Uniontype FuncArg begin - @Record FUNCARG begin - - name::String - ty::Type - constType::Const - par::VarParallelism - defaultBinding::Option{Exp} - end -end - -#= The degree of constantness of an expression is determined by the Const -datatype. Variables declared as \\'constant\\' will get C_CONST constantness. -Variables declared as \\'parameter\\' will get C_PARAM constantness and -all other variables are not constant and will get C_VAR constantness. - -- Variable properties =# -@Uniontype Const begin - @Record C_CONST begin - - end - - @Record C_PARAM begin - - end - - @Record C_VAR begin - - end - - @Record C_UNKNOWN begin - - end -end - -#= A tuple is added to the Types. This is used by functions whom returns multiple arguments. -Used by split_props -- Tuple constants =# -@Uniontype TupleConst begin - @Record SINGLE_CONST begin - - constType::Const - end - - @Record TUPLE_CONST begin - - tupleConstLst::List{TupleConst} - end -end - -#= P.R 1.1 for multiple return arguments from functions, -one constant flag for each return argument. - -The datatype `Properties\\' contain information about an -expression. The properties are created by analyzing the -expressions. -- Expression properties =# -@Uniontype Properties begin - @Record PROP begin - - type_ #= type =#::Type - constFlag #= constFlag; if the type is a tuple, each element - have a const flag. =#::Const - end - - @Record PROP_TUPLE begin - - type_::Type - tupleConst #= tupleConst; The elements might be - tuple themselfs. =#::TupleConst - end -end - -const ReductionIterators = List #= NOTE: OMC only handles one iterator for now =# -#= To generate the correct set of equations, the translator has to -differentiate between the primitive types `Real\\', `Integer\\', -`String\\', `Boolean\\' and types directly derived from then from -other, complex types. For arrays and matrices the type -`T_ARRAY\\' is used, with the first argument being the number of -dimensions, and the second being the type of the objects in the -array. The `Type\\' type is used to store -information about whether a class is derived from a primitive -type, and whether a variable is of one of these types. -- Modification datatype, was originally in Mod =# -@Uniontype EqMod begin - @Record TYPED begin - - modifierAsExp #= modifier as expression =#::Exp - modifierAsValue #= modifier as Value option =#::Option{Values.Value} - properties #= properties =#::Properties - modifierAsAbsynExp #= keep the untyped modifier as an absyn expression for modification comparison =#::Absyn.Exp - info::SourceInfo - end - - @Record UNTYPED begin - - exp::Absyn.Exp - end -end - -#= -Sub Modification =# -@Uniontype SubMod begin - @Record NAMEMOD begin - - ident #= component name =#::String - mod #= modification =#::Mod - end -end - -#= Modification =# -@Uniontype Mod begin - @Record MOD begin - - finalPrefix #= final prefix =#::SCode.Final - eachPrefix #= each prefix =#::SCode.Each - subModLst::List{SubMod} - binding::Option{EqMod} - info::SourceInfo - end - - @Record REDECL begin - - finalPrefix #= final prefix =#::SCode.Final - eachPrefix #= each prefix =#::SCode.Each - element::SCode.Element - mod::Mod - end - - @Record NOMOD begin - - end -end - -@Uniontype ClockKind begin - @Record INFERRED_CLOCK begin - - end - - @Record INTEGER_CLOCK begin - - intervalCounter::Exp - resolution #= integer type >= 1 =#::Exp - end - - @Record REAL_CLOCK begin - - interval::Exp - end - - @Record BOOLEAN_CLOCK begin - - condition::Exp - startInterval #= real type >= 0.0 =#::Exp - end - - @Record SOLVER_CLOCK begin - - c::Exp - solverMethod #= string type =#::Exp - end -end - -#= /* -- End Types.mo -- */ =# - -#= Expressions -The 'Exp' datatype closely corresponds to the 'Absyn.Exp' datatype, but -is used for statically analyzed expressions. It includes explicit type -promotions and typed (non-overloaded) operators. It also contains expression -indexing with the 'ASUB' constructor. Indexing arbitrary array expressions -is currently not supported in Modelica, but it is needed here. - -When making additions, update at least the following functions: -* Expression.traverseExp -* Expression.traverseExpTopDown -* Expression.traverseExpBiDir -* ExpressionDump.printExpStr =# -@Uniontype Exp begin - @Record ICONST begin - - integer #= Integer constants =#::ModelicaInteger - end - - @Record RCONST begin - - real #= Real constants =#::ModelicaReal - end - - @Record SCONST begin - - string #= String constants =#::String - end - - @Record BCONST begin - - bool #= Bool constants =#::Bool - end - - @Record CLKCONST begin - - clk #= Clock kinds =#::ClockKind - end - - @Record ENUM_LITERAL begin - - name::Absyn.Path - index::ModelicaInteger - end - - @Record CREF begin - - componentRef::ComponentRef - ty::Type - end - - @Record BINARY begin - - exp1::Exp - operator::Operator - exp2::Exp - end - - @Record UNARY begin - - operator::Operator - exp::Exp - end - - @Record LBINARY begin - - exp1::Exp - operator::Operator - exp2::Exp - end - - @Record LUNARY begin - - operator::Operator - exp::Exp - end - - @Record RELATION begin - - exp1::Exp - operator::Operator - exp2::Exp - index #= Use -1 as a default; other indexes are used in the backend for some silly reasons =#::ModelicaInteger - optionExpisASUB::Option{Tuple{Exp, ModelicaInteger, ModelicaInteger}} - end - - @Record IFEXP begin - expCond::Exp - expThen::Exp - expElse::Exp - end - - @Record CALL begin - path::Absyn.Path - expLst::List{Exp} - attr::CallAttributes - end - - @Record RECORD begin - path::Absyn.Path - exps #= component values =#::List{Exp} - comp #= component name =#::List{String} - ty::Type - end - - @Record PARTEVALFUNCTION begin - - path::Absyn.Path - expList::List{Exp} - ty::Type - origType::Type - end - - @Record ARRAY begin - - ty::Type - scalar #= scalar for codegen =#::Bool - array #= Array constructor, e.g. {1,3,4} =#::List{Exp} - end - - @Record MATRIX begin - - ty::Type - integer #= Size of the first dimension =#::ModelicaInteger - matrix::List{List{Exp}} - end - - @Record RANGE begin - - ty #= the (array) type of the expression =#::Type - start #= start value =#::Exp - step #= step value =#::Option{Exp} - stop #= stop value =#::Exp - end - - @Record TUPLE begin - - PR #= PR. Tuples, used in func calls returning several - arguments =#::List{Exp} - end - - @Record CAST begin - - ty #= This is the full type of this expression, i.e. ET_ARRAY(...) for arrays and matrices =#::Type - exp::Exp - end - - @Record ASUB begin - - exp::Exp - sub::List{Exp} - end - - @Record TSUB begin - - exp::Exp - ix::ModelicaInteger - ty::Type - end - - @Record RSUB begin - - exp::Exp - ix::ModelicaInteger - #= Used when generating code for MetaModelica records - =# - fieldName::String - ty::Type - end - - @Record SIZE begin - - exp::Exp - sz::Option{Exp} - end - - @Record CODE begin - - code::Absyn.CodeNode - ty::Type - end - - @Record EMPTY begin - - scope #= the scope where we could not find the binding =#::String - name #= the name of the variable =#::ComponentRef - ty #= the type of the variable =#::Type - tyStr::String - end - - @Record REDUCTION begin - - reductionInfo::ReductionInfo - expr #= expr, e.g i*i+1 =#::Exp - iterators::ReductionIterators - end - - #= /* Part of MetaModelica extension. KS */ =# - - @Record LIST begin - - valList::List{Exp} - end - - @Record CONS begin - - car::Exp - cdr::Exp - end - - @Record META_TUPLE begin - - listExp::List{Exp} - end - - @Record META_OPTION begin - - exp::Option{Exp} - end - - #= /* - Holds a metarecord call - () - */ =# - - @Record METARECORDCALL begin - - #= Metamodelica extension, simbj - =# - path::Absyn.Path - args::List{Exp} - fieldNames::List{String} - index::ModelicaInteger - #= Index in the uniontype - =# - typeVars::List{Type} - end - - @Record MATCHEXPRESSION begin - - matchType::MatchType - inputs::List{Exp} - aliases #= input aliases (input as-bindings) =#::List{List{String}} - localDecls::List{Element} - cases::List{MatchCase} - et::Type - end - - @Record BOX begin - - exp::Exp - end - - @Record UNBOX begin - - exp::Exp - ty::Type - end - - @Record SHARED_LITERAL begin - - index #= A unique indexing that can be used to point to a single shared literal in generated code =#::ModelicaInteger - exp #= For printing strings, code generators that do not support this kind of literal, or for getting the type in case the code generator needs that =#::Exp - end - - @Record PATTERN begin - - pattern::Pattern - end - - #= /* --- */ =# -end - -@Uniontype TailCall begin - @Record NO_TAIL begin - - end - - @Record TAIL begin - - vars::List{String} - outVars::List{String} - end -end - -@Uniontype CallAttributes begin - @Record CALL_ATTR begin - - ty #= The type of the return value, if several return values this is undefined =#::Type - tuple_ #= tuple =#::Bool - builtin #= builtin Function call =#::Bool - isImpure #= if the function has prefix *impure* is true, else false =#::Bool - isFunctionPointerCall::Bool - inlineType::InlineType - tailCall #= Input variables of the function if the call is tail-recursive =#::TailCall - end -end - -@Uniontype ReductionInfo begin - @Record REDUCTIONINFO begin - - path #= array, sum,.. =#::Absyn.Path - iterType::Absyn.ReductionIterType - exprType::Type - defaultValue #= if there is no default value, the reduction is not defined for 0-length arrays/lists =#::Option{Values.Value} - foldName::String - resultName #= Unique identifier for the resulting expression =#::String - foldExp #= For example, max(ident,$res) or ident+$res; array() does not use this feature; DO NOT TRAVERSE THIS EXPRESSION! =#::Option{Exp} - end -end - -@Uniontype ReductionIterator begin - @Record REDUCTIONITER begin - - id::String - exp::Exp - guardExp::Option{Exp} - ty::Type - end -end - - -@Uniontype MatchCase begin - @Record CASE begin - - patterns #= ELSE is handled by not doing pattern-matching =#::List{Pattern} - patternGuard #= Guard-expression =#::Option{Exp} - localDecls::List{Element} - body::List{Statement} - result::Option{Exp} - resultInfo #= We need to keep the line info here so we can set a breakpoint at the last statement of a match-expression =#::SourceInfo - jump #= the number of iterations we should skip if we succeed with pattern-matching, but don't succeed =#::ModelicaInteger - info::SourceInfo - end -end - -@Uniontype MatchType begin - @Record MATCHCONTINUE begin - - end - - @Record TRY_STACKOVERFLOW begin - - end - - @Record MATCH begin - - switch #= The index of the pattern to switch over, its type and the value to divide string hashes with =#::Option{Tuple{ModelicaInteger, Type, ModelicaInteger}} - end -end - -#= Patterns deconstruct expressions =# -@Uniontype Pattern begin - @Record PAT_WILD begin - - end - - @Record PAT_CONSTANT begin - - ty #= so we can unbox if needed =#::Option{Type} - exp::Exp - end - - @Record PAT_AS begin - - id::String - ty #= so we can unbox if needed =#::Option{Type} - attr #= so we know if the ident is parameter or assignable =#::Attributes - pat::Pattern - end - - @Record PAT_AS_FUNC_PTR begin - - id::String - pat::Pattern - end - - @Record PAT_META_TUPLE begin - - patterns::List{Pattern} - end - - @Record PAT_CALL_TUPLE begin - - patterns::List{Pattern} - end - - @Record PAT_CONS begin - - head::Pattern - tail::Pattern - end - - @Record PAT_CALL begin - - name::Absyn.Path - index::ModelicaInteger - patterns::List{Pattern} - fields::List{Var} - #= Needed to be able to bind a variable to the fields - =# - typeVars::List{Type} - knownSingleton #= The runtime system (dynload), does not know if the value is a singleton. But optimizations are safe if this is true. =#::Bool - end - - @Record PAT_CALL_NAMED begin - - name::Absyn.Path - patterns::List{Tuple{Pattern, String, Type}} - end - - @Record PAT_SOME begin - - pat::Pattern - end -end - -#= Operators which are overloaded in the abstract syntax are here -made type-specific. The integer addition operator (`ADD(INT)\\') -and the real addition operator (`ADD(REAL)\\') are two distinct -operators. =# -@Uniontype Operator begin - @Record ADD begin - - ty::Type - end - - @Record SUB begin - - ty::Type - end - - @Record MUL begin - - ty::Type - end - - @Record DIV begin - - ty::Type - end - - @Record POW begin - - ty::Type - end - - @Record UMINUS begin - - ty::Type - end - - @Record UMINUS_ARR begin - - ty::Type - end - - @Record ADD_ARR begin - - ty::Type - end - - @Record SUB_ARR begin - - ty::Type - end - - @Record MUL_ARR begin - - ty::Type - end - - @Record DIV_ARR begin - - ty::Type - end - - @Record MUL_ARRAY_SCALAR begin - - ty #= type of the array =#::Type - end - - @Record ADD_ARRAY_SCALAR begin - - ty #= type of the array =#::Type - end - - @Record SUB_SCALAR_ARRAY begin - - ty #= type of the array =#::Type - end - - @Record MUL_SCALAR_PRODUCT begin - - ty #= type of the array =#::Type - end - - @Record MUL_MATRIX_PRODUCT begin - - ty #= {{..},..} {{..},{..}} =#::Type - end - - @Record DIV_ARRAY_SCALAR begin - - ty #= type of the array =#::Type - end - - @Record DIV_SCALAR_ARRAY begin - - ty #= type of the array =#::Type - end - - @Record POW_ARRAY_SCALAR begin - - ty #= type of the array =#::Type - end - - @Record POW_SCALAR_ARRAY begin - - ty #= type of the array =#::Type - end - - @Record POW_ARR begin - - ty #= type of the array =#::Type - end - - @Record POW_ARR2 begin - - ty #= type of the array =#::Type - end - - @Record AND begin - - ty::Type - end - - @Record OR begin - - ty::Type - end - - @Record NOT begin - - ty::Type - end - - @Record LESS begin - - ty::Type - end - - @Record LESSEQ begin - - ty::Type - end - - @Record GREATER begin - - ty::Type - end - - @Record GREATEREQ begin - - ty::Type - end - - @Record EQUAL begin - - ty::Type - end - - @Record NEQUAL begin - - ty::Type - end - - @Record USERDEFINED begin - - fqName #= The FQ name of the overloaded operator function =#::Absyn.Path - end -end - -#= - Component references -CREF_QUAL(...) is used for qualified component names, e.g. a.b.c -CREF_IDENT(..) is used for non-qualifed component names, e.g. x =# -@Uniontype ComponentRef begin - @Record CREF_QUAL begin - ident::String - identType #= type of the identifier, without considering the subscripts =#::Type - subscriptLst::List{Subscript} - componentRef::ComponentRef - end - - @Record CREF_IDENT begin - - ident::String - identType #= type of the identifier, without considering the subscripts =#::Type - subscriptLst::List{Subscript} - end - - @Record CREF_ITER begin - - ident::String - index::ModelicaInteger - identType #= type of the identifier, without considering the subscripts =#::Type - subscriptLst::List{Subscript} - end - - @Record OPTIMICA_ATTR_INST_CREF begin - componentRef::ComponentRef - instant::String - end - - @Record WILD begin - end -end - - -const NEW_SET = -1 #= The index used for new sets which have not -yet been assigned a set index. =#::ModelicaInteger - -#= This type indicates whether a connector is an inside or an outside connector. -Note: this is not the same as inner and outer references. -A connector is inside if it connects from the outside into a component and it -is outside if it connects out from the component. This is important when -generating equations for flow variables, where outside connectors are -multiplied with -1 (since flow is always into a component). =# -@Uniontype Face begin - @Record INSIDE begin - - end - - @Record OUTSIDE begin - - end - - @Record NO_FACE begin - - end -end - -#= The type of a connector element. =# -@Uniontype CConnectorType begin - @Record CEQU begin - - end - - @Record CFLOW begin - - end - - @Record CSTREAM begin - - associatedFlow::Option{ComponentRef} - end - - @Record CNO_TYPE begin - - end -end - -@Uniontype ConnectorElement begin - @Record CONNECTOR_ELEMENT begin - - name::ComponentRef - face::Face - ty::CConnectorType - source::ElementSource - set #= Which set this element belongs to. =#::ModelicaInteger - end -end - -@Uniontype SetTrieNode begin - @Record SET_TRIE_NODE begin - - name::String - cref::ComponentRef - nodes::List{SetTrieNode} - connectCount::ModelicaInteger - end - - @Record SET_TRIE_LEAF begin - - name::String - insideElement #= The inside element. =#::Option{ConnectorElement} - outsideElement #= The outside element. =#::Option{ConnectorElement} - flowAssociation #= The name of the associated flow - variable, if the leaf represents a stream variable. =#::Option{ComponentRef} - connectCount #= How many times this connector has been connected. =#::ModelicaInteger - end -end - -const SetTrie = SetTrieNode #= A trie, a.k.a. prefix tree, that maps crefs to sets. =# - -const SetConnection = Tuple #= A connection between two sets. =# - -@Uniontype OuterConnect begin - @Record OUTERCONNECT begin - scope #= the scope where this connect was created =# #TODO:::Prefix.PrefixType - cr1 #= the lhs component reference =#::ComponentRef - io1 #= inner/outer attribute for cr1 component =#::Absyn.InnerOuter - f1 #= the face of the lhs component =#::Face - cr2 #= the rhs component reference =#::ComponentRef - io2 #= inner/outer attribute for cr2 component =#::Absyn.InnerOuter - f2 #= the face of the rhs component =#::Face - source #= the element origin =#::ElementSource - end -end - -@Uniontype Sets begin - @Record SETS begin - - sets::SetTrie - setCount #= How many sets the trie contains. =#::ModelicaInteger - connections::List{SetConnection} - outerConnects #= Connect statements to propagate upwards. =#::List{OuterConnect} - end -end - -#= A set of connection elements. =# -@Uniontype CSet begin - @Record SET begin - - ty::CConnectorType - elements::List{ConnectorElement} - end - - @Record SET_POINTER begin - - index::ModelicaInteger - end -end - -const emptySet = SETS(SET_TRIE_NODE("", WILD(), nil, 0), 0, nil, nil)::Sets - -@Uniontype Element begin - @Record VAR begin - componentRef #= The variable name =#::ComponentRef - kind #= varible kind: variable, constant, parameter, discrete etc. =#::VarKind - direction #= input, output or bidir =#::VarDirection - parallelism #= parglobal, parlocal, or non_parallel =#::VarParallelism - protection #= if protected or public =#::VarVisibility - ty #= Full type information required =#::Type - binding #= Binding expression e.g. for parameters value of start attribute =#::Option{Exp} - dims #= dimensions =#::List - connectorType #= The connector type: flow, stream, no prefix, or not a connector element. =#::ConnectorType - source #= the origins of the component/equation/algorithm =#::ElementSource - variableAttributesOption::Option{VariableAttributes} - comment::Option{SCode.Comment} - innerOuter #= inner/outer required to 'change' outer references =#::Absyn.InnerOuter - end - - @Record DEFINE begin - - componentRef::ComponentRef - exp::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record INITIALDEFINE begin - - componentRef::ComponentRef - exp::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record EQUATION begin - exp::Exp - scalar::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record EQUEQUATION begin - - cr1::ComponentRef - cr2::ComponentRef - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record ARRAY_EQUATION begin - - dimension #= dimension sizes =#::Dimensions - exp::Exp - array::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record INITIAL_ARRAY_EQUATION begin - - dimension #= dimension sizes =#::Dimensions - exp::Exp - array::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record CONNECT_EQUATION begin - - lhsElement::Element - lhsFace::Face - rhsElement::Element - rhsFace::Face - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record COMPLEX_EQUATION begin - - lhs::Exp - rhs::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record INITIAL_COMPLEX_EQUATION begin - - lhs::Exp - rhs::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record WHEN_EQUATION begin - - condition #= Condition =#::Exp - equations #= Equations =#::List{Element} - elsewhen_ #= Elsewhen should be of type WHEN_EQUATION =#::Option{Element} - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record FOR_EQUATION begin - - type_ #= this is the type of the iterator =#::Type - iterIsArray #= True if the iterator has an array type, otherwise false. =#::Bool - iter #= the iterator variable =#::String - index #= the index of the iterator variable, to make it unique; used by the new inst =#::ModelicaInteger - range #= range for the loop =#::Exp - equations #= Equations =#::List{Element} - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record IF_EQUATION begin - condition1 #= Condition =#::List{Exp} - equations2 #= Equations of true branch =#::List{List{Element}} - equations3 #= Equations of false branch =#::List{Element} - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record INITIAL_IF_EQUATION begin - condition1 #= Condition =#::List{Exp} - equations2 #= Equations of true branch =#::List{List{Element}} - equations3 #= Equations of false branch =#::List{Element} - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record INITIALEQUATION begin - - exp1::Exp - exp2::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record ALGORITHM begin - - algorithm_::Algorithm - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record INITIALALGORITHM begin - - algorithm_::Algorithm - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record COMP begin - ident::String - dAElist #= a component with subelements, normally only used at top level. =#::List{Element} - source #= the origin of the component/equation/algorithm =#::ElementSource - #= we might not this here. - =# - comment::Option{SCode.Comment} - end - - @Record EXTOBJECTCLASS begin - - path #= className of external object =#::Absyn.Path - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record ASSERT begin - - condition::Exp - message::Exp - level::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - - @Record INITIAL_ASSERT begin - - condition::Exp - message::Exp - level::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource - end - -@Record TERMINATE begin - - message::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource -end - -@Record INITIAL_TERMINATE begin - - message::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource -end - -@Record REINIT begin - - componentRef::ComponentRef - exp::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource -end - -@Record NORETCALL begin - - exp::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource -end - -@Record INITIAL_NORETCALL begin - - exp::Exp - source #= the origin of the component/equation/algorithm =#::ElementSource -end - -@Record CONSTRAINT begin - - constraints::Constraint - source #= the origin of the component/equation/algorithm =#::ElementSource -end - -@Record CLASS_ATTRIBUTES begin - - classAttrs::ClassAttributes -end - -@Record FLAT_SM begin - - ident::String - dAElist #= The states/modes transitions and variable - merging equations within the the flat state machine =#::List{Element} -end - -@Record SM_COMP begin - - componentRef::ComponentRef - dAElist #= a component with subelements =#::List{Element} -end - -@Record COMMENT begin - - cmt #= Functions store the inherited class annotations in the DAE =#::SCode.Comment -end -end - -#= The `Subscript\\' and `ComponentRef\\' datatypes are simple -translations of the corresponding types in the `Absyn\\' module. =# -@Uniontype Subscript begin - @Record WHOLEDIM begin - end - - @Record SLICE begin - exp #= a{1:3,1}, a{1:2:10,2} =#::Exp - end - - @Record INDEX begin - exp #= a[i+1] =#::Exp - end - - @Record WHOLE_NONEXP begin - exp::Exp - end -end - -#= /* -- End Expression.mo -- */ =# - -#= array cref expansion strategy =# -@Uniontype Expand begin - @Record EXPAND begin - - end - - @Record NOT_EXPAND begin - - end -end - -const emptyDae = DAE_LIST(nil)::DAE_LIST -const T_ASSERTIONLEVEL = T_ENUMERATION(NONE(), Absyn.FULLYQUALIFIED(Absyn.IDENT("AssertionLevel")), list("error", "warning"), nil, nil)::Type - -const ASSERTIONLEVEL_ERROR = ENUM_LITERAL(Absyn.QUALIFIED("AssertionLevel", Absyn.IDENT("error")), 1)::Exp - -const ASSERTIONLEVEL_WARNING = ENUM_LITERAL(Absyn.QUALIFIED("AssertionLevel", Absyn.IDENT("warning")), 2)::Exp - -const T_UNKNOWN_DEFAULT = T_UNKNOWN() -const T_REAL_DEFAULT = T_REAL(nil)::Type -const T_INTEGER_DEFAULT = T_INTEGER(nil)::Type -const T_STRING_DEFAULT = T_STRING(nil)::Type -const T_BOOL_DEFAULT = T_BOOL(nil)::Type -const T_CLOCK_DEFAULT = T_CLOCK(nil)::Type -const T_ENUMERATION_DEFAULT = T_ENUMERATION(NONE(), Absyn.IDENT(""), nil, nil, nil)::Type -const T_REAL_BOXED = T_METABOXED(T_REAL_DEFAULT)::Type -const T_INTEGER_BOXED = T_METABOXED(T_INTEGER_DEFAULT)::Type -const T_STRING_BOXED = T_METABOXED(T_STRING_DEFAULT)::Type -const T_BOOL_BOXED = T_METABOXED(T_BOOL_DEFAULT)::Type -const T_METABOXED_DEFAULT = T_METABOXED(T_UNKNOWN_DEFAULT)::Type -const T_METALIST_DEFAULT = T_METALIST(T_UNKNOWN_DEFAULT)::Type -const T_NONE_DEFAULT = T_METAOPTION(T_UNKNOWN_DEFAULT)::Type -const T_ANYTYPE_DEFAULT = T_ANYTYPE(NONE())::Type -const T_UNKNOWN_DEFAULT = T_UNKNOWN()::Type -const T_NORETCALL_DEFAULT = T_NORETCALL()::Type -const T_METATYPE_DEFAULT = T_METATYPE(T_UNKNOWN_DEFAULT)::Type -const T_COMPLEX_DEFAULT = T_COMPLEX(ClassInf.UNKNOWN(Absyn.IDENT("")), nil, NONE()) #= default complex with unknown CiState =#::Type -const T_COMPLEX_DEFAULT_RECORD = T_COMPLEX(ClassInf.RECORD(Absyn.IDENT("")), nil, NONE()) #= default complex with record CiState =#::Type -const T_SOURCEINFO_DEFAULT_METARECORD = T_METARECORD(Absyn.QUALIFIED("SourceInfo", Absyn.IDENT("SOURCEINFO")), Absyn.IDENT("SourceInfo"), nil, 1, list(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()), TYPES_VAR("columnNumberStart", dummyAttrVar, T_INTEGER_DEFAULT, UNBOUND(), NONE()), TYPES_VAR("lineNumberEnd", dummyAttrVar, T_INTEGER_DEFAULT, UNBOUND(), NONE()), TYPES_VAR("columnNumberEnd", dummyAttrVar, T_INTEGER_DEFAULT, UNBOUND(), NONE()), TYPES_VAR("lastModification", dummyAttrVar, T_REAL_DEFAULT, UNBOUND(), NONE())), true)::Type -const T_SOURCEINFO_DEFAULT = T_METAUNIONTYPE(list(Absyn.QUALIFIED("SourceInfo", Absyn.IDENT("SOURCEINFO"))), nil, true, EVAL_SINGLETON_KNOWN_TYPE(T_SOURCEINFO_DEFAULT_METARECORD), Absyn.IDENT("SourceInfo"))::Type -#= Arrays of unknown dimension, eg. Real[:] =# - -const T_ARRAY_REAL_NODIM = T_ARRAY(T_REAL_DEFAULT, list(DIM_UNKNOWN()))::Type - -const T_ARRAY_INT_NODIM = T_ARRAY(T_INTEGER_DEFAULT, list(DIM_UNKNOWN()))::Type - -const T_ARRAY_BOOL_NODIM = T_ARRAY(T_BOOL_DEFAULT, list(DIM_UNKNOWN()))::Type - -const T_ARRAY_STRING_NODIM = T_ARRAY(T_STRING_DEFAULT, list(DIM_UNKNOWN()))::Type - - -const callAttrBuiltinBool = CALL_ATTR(T_BOOL_DEFAULT, false, true, false, false, NO_INLINE(), NO_TAIL())::CallAttributes - -const callAttrBuiltinInteger = CALL_ATTR(T_INTEGER_DEFAULT, false, true, false, false, NO_INLINE(), NO_TAIL())::CallAttributes - -const callAttrBuiltinReal = CALL_ATTR(T_REAL_DEFAULT, false, true, false, false, NO_INLINE(), NO_TAIL())::CallAttributes - -const callAttrBuiltinString = CALL_ATTR(T_STRING_DEFAULT, false, true, false, false, NO_INLINE(), NO_TAIL())::CallAttributes - -const callAttrBuiltinOther = CALL_ATTR(T_UNKNOWN_DEFAULT, false, true, false, false, NO_INLINE(), NO_TAIL())::CallAttributes - -const callAttrBuiltinImpureBool = CALL_ATTR(T_BOOL_DEFAULT, false, true, true, false, NO_INLINE(), NO_TAIL())::CallAttributes - -const callAttrBuiltinImpureInteger = CALL_ATTR(T_INTEGER_DEFAULT, false, true, true, false, NO_INLINE(), NO_TAIL())::CallAttributes - -const callAttrBuiltinImpureReal = CALL_ATTR(T_REAL_DEFAULT, false, true, true, false, NO_INLINE(), NO_TAIL())::CallAttributes - -const callAttrOther = CALL_ATTR(T_UNKNOWN_DEFAULT, false, false, false, false, NO_INLINE(), NO_TAIL())::CallAttributes - - -const crefTime = CREF_IDENT("time", T_REAL_DEFAULT, nil)::ComponentRef -const crefTimeState = CREF_IDENT("time", T_REAL_DEFAULT, nil)::ComponentRef -const emptyCref = CREF_IDENT("", T_UNKNOWN_DEFAULT, nil)::ComponentRef - -FunctionTree = Dict{Absyn.Path, Function} - - -@exportAll() - -end diff --git a/src/FrontendUtil/DAE_Interface.jl b/src/FrontendUtil/DAE_Interface.jl deleted file mode 100644 index c3b0e1c..0000000 --- a/src/FrontendUtil/DAE_Interface.jl +++ /dev/null @@ -1,70 +0,0 @@ -#= - This file is needed to provide a necessary interface for Prefix.jl -=# -const Dimensions = List #= a list of dimensions =# -@UniontypeDecl VarKind -@UniontypeDecl ConnectorType -@UniontypeDecl VarDirection -@UniontypeDecl VarParallelism -@UniontypeDecl VarVisibility -@UniontypeDecl VarInnerOuter -@UniontypeDecl ElementSource -@UniontypeDecl SymbolicOperation -@UniontypeDecl EquationExp -@UniontypeDecl Element -@UniontypeDecl Function -@UniontypeDecl InlineType -@UniontypeDecl FunctionDefinition -@UniontypeDecl derivativeCond -@UniontypeDecl VariableAttributes -@UniontypeDecl StateSelect -@UniontypeDecl Uncertainty -@UniontypeDecl Distribution -@UniontypeDecl ExtArg -@UniontypeDecl ExternalDecl -@UniontypeDecl DAElist -@UniontypeDecl Algorithm -@UniontypeDecl Constraint -@UniontypeDecl ClassAttributes -@UniontypeDecl Statement -@UniontypeDecl Else -@UniontypeDecl Var -@UniontypeDecl Attributes -@UniontypeDecl BindingSource -@UniontypeDecl Binding -@UniontypeDecl Type -@UniontypeDecl CodeType -@UniontypeDecl EvaluateSingletonType -EvaluateSingletonTypeFunction = Function -@UniontypeDecl FunctionAttributes -@UniontypeDecl FunctionBuiltin -@UniontypeDecl FunctionParallelism -@UniontypeDecl Dimension -@UniontypeDecl DimensionBinding -@UniontypeDecl FuncArg -@UniontypeDecl Const -@UniontypeDecl TupleConst -@UniontypeDecl Properties -@UniontypeDecl EqMod -@UniontypeDecl SubMod -@UniontypeDecl Mod -@UniontypeDecl ClockKind -@UniontypeDecl Exp -@UniontypeDecl TailCall -@UniontypeDecl CallAttributes -@UniontypeDecl ReductionInfo -@UniontypeDecl ReductionIterator -@UniontypeDecl MatchCase -@UniontypeDecl MatchType -@UniontypeDecl Pattern -@UniontypeDecl Operator -@UniontypeDecl ComponentRef -@UniontypeDecl Subscript -@UniontypeDecl Expand -@UniontypeDecl Face -@UniontypeDecl CConnectorType -@UniontypeDecl ConnectorElement -@UniontypeDecl SetTrieNode -@UniontypeDecl OuterConnect -@UniontypeDecl Sets -@UniontypeDecl CSet diff --git a/src/FrontendUtil/Prefix.jl b/src/FrontendUtil/Prefix.jl index 916a2d7..211c988 100644 --- a/src/FrontendUtil/Prefix.jl +++ b/src/FrontendUtil/Prefix.jl @@ -9,7 +9,7 @@ using ExportAll @UniontypeDecl ClassPrefix import SCode -import ..ClassInf +import DAE.ClassInf #= A Prefix has a component prefix and a class prefix. The component prefix consist of a name an a list of constant valued subscripts. diff --git a/src/FrontendUtil/Util.jl b/src/FrontendUtil/Util.jl index 427e49d..0973f21 100644 --- a/src/FrontendUtil/Util.jl +++ b/src/FrontendUtil/Util.jl @@ -1,6 +1,6 @@ module Util -import ..DAE +import DAE import DoubleEnded using MetaModelica diff --git a/src/FrontendUtil/Values.jl b/src/FrontendUtil/Values.jl deleted file mode 100644 index 908a4bf..0000000 --- a/src/FrontendUtil/Values.jl +++ /dev/null @@ -1,165 +0,0 @@ - -#= /* -* This file is part of OpenModelica. -* -* Copyright (c) 1998-2014, Open Source Modelica Consortium (OSMC), -* c/o Linköpings universitet, Department of Computer and Information Science, -* SE-58183 Linköping, Sweden. -* -* All rights reserved. -* -* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR -* THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2. -* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES -* RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3, -* ACCORDING TO RECIPIENTS CHOICE. -* -* The OpenModelica software and the Open Source Modelica -* Consortium (OSMC) Public License (OSMC-PL) are obtained -* from OSMC, either from the above address, -* from the URLs: http:www.ida.liu.se/projects/OpenModelica or -* http:www.openmodelica.org, and in the OpenModelica distribution. -* GNU version 3 is obtained from: http:www.gnu.org/copyleft/gpl.html. -* -* This program is distributed WITHOUT ANY WARRANTY; without -* even the implied warranty of MERCHANTABILITY or FITNESS -* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH -* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. -* -* See the full OSMC Public License conditions for more details. -* -*/ =# - -module Values - -using MetaModelica -using ExportAll - -@UniontypeDecl Value -@UniontypeDecl IntRealOp - -import Absyn -import ..AbsynUtil - -@Uniontype Value begin - @Record INTEGER begin - - integer::ModelicaInteger - end - - @Record REAL begin - - real::ModelicaReal - end - - @Record STRING begin - - string::String - end - - @Record BOOL begin - - boolean::Bool - end - - @Record ENUM_LITERAL begin - - name::Absyn.Path - index::ModelicaInteger - end - - @Record ARRAY begin - - valueLst::List{Value} - dimLst::List{ModelicaInteger} - end - - @Record LIST begin - - valueLst::List{Value} - end - - @Record META_ARRAY begin - - valueLst::List{Value} - end - - @Record TUPLE begin - - valueLst::List{Value} - end - - @Record META_TUPLE begin - - valueLst::List{Value} - end - - @Record RECORD begin - - record_ #= record name =#::Absyn.Path - orderd #= orderd set of values =#::List{Value} - comp #= comp names for each value =#::List{String} - index #= -1 for regular records, 0..n-1 for uniontypes containing n records =#::ModelicaInteger - end - - @Record OPTION begin - - some::Option{Value} - end - - @Record CODE begin - - A #= A record consist of value Ident pairs =#::Absyn.CodeNode - end - - @Record NORETCALL begin - - end - - @Record META_BOX begin - - value::Value - end - - @Record META_FAIL begin - - end - - @Record EMPTY begin - - scope #= the scope where we could not find the binding =#::String - name #= the name of the variable =#::String - ty #= the DAE.Type translated to Value using defaults =#::Value - tyStr #= the type of the variable =#::String - end -end - -@Uniontype IntRealOp begin - @Record MULOP begin - - end - - @Record DIVOP begin - - end - - @Record ADDOP begin - - end - - @Record SUBOP begin - - end - - @Record POWOP begin - - end - - @Record LESSEQOP begin - - end -end - -#= So that we can use wildcard imports and named imports when they do occur. Not good Julia practice =# -@exportAll() -end diff --git a/src/HybridDAEParser.jl b/src/HybridDAEParser.jl index 356dea6..7e468de 100644 --- a/src/HybridDAEParser.jl +++ b/src/HybridDAEParser.jl @@ -7,6 +7,7 @@ module HybridDAEParser import Absyn import SCode import OpenModelicaParser + " Main module " @@ -19,6 +20,7 @@ using ExportAll import Absyn import SCode +import DAE import ListUtil include("./Util/Pointer.jl") import .P_Pointer @@ -37,12 +39,7 @@ include("./AbsynUtil.jl") include("./SCodeUtil.jl") include("./AbsynToSCode.jl") #=Utility for frontend=# -include("./FrontendUtil/Values.jl") -include("./FrontendUtil/ClassInf.jl") include("./FrontendUtil/Prefix.jl") -include("./FrontendUtil/DAE.jl") - - " TODO " @@ -50,7 +47,7 @@ function createElementSource(source) return DAE.emptyElementSource end - +@nospecialize #=New Frontend=# include("./FrontendInterfaces/NFInterfaces.jl") include("./NewFrontend/NFType.jl") @@ -65,6 +62,7 @@ include("./NewFrontend/NFCeval.jl") include("./NewFrontend/NFTyping.jl") include("./NewFrontend/NFInst.jl") include("./NewFrontend/NFEquation.jl") +include("./NewFrontend/NFAlgorithm.jl") include("./NewFrontend/NFStatement.jl") include("./NewFrontend/NFBinding.jl") include("./NewFrontend/NFVariable.jl") @@ -94,6 +92,7 @@ include("./NewFrontend/NFBuiltin.jl") import ..NFBuiltin include("./NewFrontend/BindingExpression.jl") include("./NewFrontend/NFDimension.jl") +include("./NewFrontend/NFBuiltinCall.jl") include("./NewFrontend/NFCall.jl") include("./NewFrontend/NFOperator.jl") include("./NewFrontend/NFTypeCheck.jl") @@ -130,15 +129,18 @@ end " Instantiates and translates to DAE. " -function instantiateSCodeToDAE(elementToInstantiate::String, inProgram::SCode.Program) +function instantiateSCodeToDAE(@nospecialize(elementToInstantiate::String), @nospecialize (inProgram::SCode.Program)) # initialize globals Main.Global.initialize() # make sure we have all the flags loaded! # Main.Flags.new(Flags.emptyFlags) - + @info "Parsing buildin stuff" + GC.enable(false) #=This C stuff can be a bit flaky..=# p = parseFile("../lib/NFModelicaBuiltin.mo", 2 #== MetaModelica ==#) + @info "SCode translation" s = HybridDAEParser.translateToSCode(p) p = Main.listAppend(s, inProgram) + GC.enable(true) Main.instClassInProgram(Absyn.IDENT(elementToInstantiate), p) end diff --git a/src/NewFrontend/#NFEvalFunction.jl# b/src/NewFrontend/#NFEvalFunction.jl# deleted file mode 100644 index 3f5ff0b..0000000 --- a/src/NewFrontend/#NFEvalFunction.jl# +++ /dev/null @@ -1,1607 +0,0 @@ -module NFEvalFunction - -using MetaModelica -using ExportAll - -#= /* -* This file is part of OpenModelica. -* -* Copyright (c) 1998-2014, Open Source Modelica Consortium (OSMC), -* c/o Linköpings universitet, Department of Computer and Information Science, -* SE-58183 Linköping, Sweden. -* -* All rights reserved. -* -* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR -* THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2. -* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES -* RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3, -* ACCORDING TO RECIPIENTS CHOICE. -* -* The OpenModelica software and the Open Source Modelica -* Consortium (OSMC) Public License (OSMC-PL) are obtained -* from OSMC, either from the above address, -* from the URLs: http:www.ida.liu.se/projects/OpenModelica or -* http:www.openmodelica.org, and in the OpenModelica distribution. -* GNU version 3 is obtained from: http:www.gnu.org/copyleft/gpl.html. -* -* This program is distributed WITHOUT ANY WARRANTY; without -* even the implied warranty of MERCHANTABILITY or FITNESS -* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH -* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. -* -* See the full OSMC Public License conditions for more details. -* -*/ =# -import ..P_NFExpression -P_Expression = P_NFExpression -Expression = P_NFExpression.NFExpression -import ..NFClass.P_Class -import ..NFFunction.P_Function -import ..NFInstNode.P_InstNode -import ..P_NFSections -P_Sections = P_NFSections -Sections = P_NFSections.NFSections -import ..P_NFStatement -P_Statement = P_NFStatement -Statement = P_NFStatement.NFStatement -import ..P_NFComponentRef -P_ComponentRef = P_NFComponentRef -ComponentRef = P_NFComponentRef.NFComponentRef -import ..NFBinding.P_Binding -import ..NFComponent.P_Component -import ..P_NFType -P_M_Type = P_NFType -M_Type = NFType -import ..P_NFDimension -P_Dimension = P_NFDimension -Dimension = P_NFDimension.NFDimension -import ..NFClassTree.ree -import ..P_NFSubscript -P_Subscript = P_NFSubscript -Subscript = P_NFSubscript.NFSubscript -import ..NFRecord -Record = NFRecord - -import ..NFCeval -Ceval = NFCeval -using MetaModelica.Dangerous -import ..P_NFRangeIterator -P_RangeIterator = P_NFRangeIterator -RangeIterator = P_NFRangeIterator.NFRangeIterator -import ..ElementSource -import ..Flags -import ..ModelicaExternalC -import ..System -import ..NFTyping.ExpOrigin -import ..SCode -import ..SCodeUtil -import ..NFPrefixes.Variability -import ..NFEvalFunctionExt -EvalFunctionExt = NFEvalFunctionExt -import ..P_EvalTarget - -module ReplTree - -using MetaModelica -using ExportAll - -import ..BaseAvlTree -import ..P_NFExpression -P_Expression = P_NFExpression -Expression = P_NFExpression.NFExpression -import ..NFInstNode.P_InstNode -using BaseAvlTree #= Modelica extend clause =# -Key = InstNode -Value = Expression - -@exportAll() -end - -FlowControl = (() -> begin #= Enumeration =# - NEXT = 1 - CONTINUE = 2 - BREAK = 3 - RETURN = 4 - ASSERTION = 5 - () -> (NEXT; CONTINUE; BREAK; RETURN; ASSERTION) -end)() - -function evaluate(fn::M_Function, args::List{<:Expression})::Expression - local result::Expression - - if P_Function.isExternal(fn) - @assign result = evaluateExternal(fn, args) - else - @assign result = evaluateNormal(fn, args) - end - return result -end - -function evaluateNormal(fn::M_Function, args::List{<:Expression})::Expression - local result::Expression - - local fn_body::List{Statement} - local bindings::List{Binding} - local repl::ReplTree.Tree - local call_count::Integer - local limit::Integer - local call_counter::Pointer{Integer} = fn.callCounter - local ctrl::FlowControl - - #= Functions contain a mutable call counter that's increased by one at the - =# - #= start of each evaluation, and decreased by one when the evalution is - =# - #= finished. This is used to limit the number of recursive functions calls. - =# - @assign call_count = P_Pointer.access(call_counter) + 1 - @assign limit = Flags.getConfigInt(Flags.EVAL_RECURSION_LIMIT) - if call_count > limit - Pointer.update(call_counter, 0) - Error.addSourceMessage( - Error.EVAL_RECURSION_LIMIT_REACHED, - list(String(limit), AbsynUtil.pathString(P_Function.name(fn))), - info(fn.node), - ) - fail() - end - Pointer.update(call_counter, call_count) - try - @assign fn_body = P_Function.getBody(fn) - @assign repl = createReplacements(fn, args) - @assign fn_body = applyReplacements(repl, fn_body) - @assign fn_body = optimizeBody(fn_body) - @assign ctrl = evaluateStatements(fn_body) - if ctrl != FlowControl.ASSERTION - @assign result = createResult(repl, fn.outputs) - else - fail() - end - catch - Pointer.update(call_counter, call_count - 1) - fail() - end - #= TODO: Also apply replacements to the replacements themselves, i.e. the - =# - #= bindings of the function parameters. But they probably need to be - =# - #= sorted by dependencies first. - =# - #= Make sure we always decrease the call counter even if the evaluation fails. - =# - Pointer.update(call_counter, call_count - 1) - return result -end - -function evaluateExternal(fn::M_Function, args::List{<:Expression})::Expression - local result::Expression - - local name::String - local lang::String - local output_ref::ComponentRef - local ann::Option{SCode.Annotation} - local ext_args::List{Expression} - - @match SECTIONS_EXTERNAL( - name = name, - args = ext_args, - outputRef = output_ref, - language = lang, - ann = ann, - ) = getSections(getClass(fn.node)) - if lang == "builtin" - @assign result = Ceval.evalBuiltinCall(fn, args, P_EvalTarget.IGNORE_ERRORS()) - elseif isKnownExternalFunc(name, ann) - @assign result = evaluateKnownExternal(name, args) - else - try - @assign result = evaluateExternal2(name, fn, args, ext_args) - catch - Error.assertion( - false, - getInstanceName() + - " failed on " + - AbsynUtil.pathString(fn.path) + - ", evaluation of userdefined external functions not yet implemented", - sourceInfo(), - ) - fail() - end - end - #= Functions defined as 'external \"builtin\"', delegate to Ceval. - =# - #= External functions that we know how to evaluate without generating code. - =# - #= TODO: Move this to EvalFunctionExt and unify evaluateKnownExternal and - =# - #= evaluateExternal2. This requires handling of outputRef though. - =# - #= External functions that we would need to generate code for and execute. - =# - return result -end - -""" #= Evaluates a default record constructor call by replacing any field references - with the given arguments, optionally constant evaluating the resulting expression. - - Example: - record R - Real x; - constant Real y = x / 2.0; - Real z; - end R; - - CALL(R, {1.0, 2.0}) => RECORD(R, {1.0, 0.5, 2.0}); - =#""" -function evaluateRecordConstructor( - fn::M_Function, - ty::M_Type, - args::List{<:Expression}, - evaluate::Bool = true, -)::Expression - local result::Expression - - local repl::ReplTree.Tree - local arg::Expression - local repl_exp::Expression - local fields::List{Record.P_Field} - local rest_args::List{Expression} = args - local expl::List{Expression} = nil - local inputs::List{InstNode} = fn.inputs - local locals::List{InstNode} = fn.locals - local node::InstNode - - @assign repl = ReplTree.new() - @assign fields = Type.recordFields(ty) - #= Add the inputs and local variables to the replacement tree with their - =# - #= respective bindings. - =# - for i in inputs - @match _cons(arg, rest_args) = rest_args - @assign repl = ReplTree.add(repl, i, arg) - end - for l in locals - @assign repl = ReplTree.add(repl, l, getBindingExp(l, repl)) - end - #= Apply the replacements to all the variables. - =# - @assign repl = ReplTree.map(repl, (repl) -> applyBindingReplacement(repl = repl)) - #= Fetch the new binding expressions for all the variables, both inputs and - =# - #= locals. - =# - for f in fields - if Record.P_Field.isInput(f) - @match _cons(node, inputs) = inputs - else - @match _cons(node, locals) = locals - end - @assign expl = _cons(ReplTree.get(repl, node), expl) - end - #= Create a new record expression from the list of arguments. - =# - @assign result = - P_Expression.Expression.makeRecord(P_Function.name(fn), ty, listReverseInPlace(expl)) - #= Constant evaluate the expression if requested. - =# - if evaluate - @assign result = Ceval.evalExp(result) - end - return result -end - -function createReplacements(fn::M_Function, args::List{<:Expression})::ReplTree.Tree - local repl::ReplTree.Tree - - local arg::Expression - local rest_args::List{Expression} = args - - @assign repl = ReplTree.new() - #= Add inputs to the replacement tree. Since they can't be assigned to the - =# - #= replacements don't need to be mutable. - =# - for i in fn.inputs - @match _cons(arg, rest_args) = rest_args - @assign repl = addInputReplacement(i, arg, repl) - end - #= Add outputs and local variables to the replacement tree. These do need to - =# - #= be mutable to allow assigning to them. - =# - @assign repl = ListUtil.fold(fn.outputs, addMutableReplacement, repl) - @assign repl = ListUtil.fold(fn.locals, addMutableReplacement, repl) - #= Apply the replacements to the replacements themselves. This is done after - =# - #= building the tree to make sure all the replacements are available. - =# - @assign repl = ReplTree.map(repl, (repl) -> applyBindingReplacement(repl = repl)) - return repl -end - -function addMutableReplacement(node::InstNode, repl::ReplTree.Tree)::ReplTree.Tree - - local binding::Binding - local repl_exp::Expression - - @assign repl_exp = getBindingExp(node, repl) - @assign repl_exp = P_Expression.Expression.makeMutable(repl_exp) - @assign repl = ReplTree.add(repl, node, repl_exp) - return repl -end - -function getBindingExp(node::InstNode, repl::ReplTree.Tree)::Expression - local bindingExp::Expression - - local binding::Binding - - @assign binding = P_Component.getBinding(component(node)) - if isBound(binding) - @assign bindingExp = P_Expression.Expression.getBindingExp(getExp(binding)) - else - @assign bindingExp = buildBinding(node, repl) - end - return bindingExp -end - -function buildBinding(node::InstNode, repl::ReplTree.Tree)::Expression - local result::Expression - - local ty::M_Type - - @assign ty = getType(node) - @assign ty = Type.mapDims(ty, (repl) -> applyReplacementsDim(repl = repl)) - @assign result = begin - @match ty begin - Type.ARRAY(__) where {(Type.hasKnownSize(ty))} => begin - P_Expression.Expression.fillType( - ty, - P_Expression.Expression.EMPTY(Type.arrayElementType(ty)), - ) - end - - TYPE_COMPLEX(__) => begin - buildRecordBinding(node, repl) - end - - _ => begin - P_Expression.Expression.EMPTY(ty) - end - end - end - return result -end - -function applyReplacementsDim(repl::ReplTree.Tree, dim::Dimension)::Dimension - - @assign dim = begin - local exp::Expression - @match dim begin - P_Dimension.Dimension.EXP(__) => begin - @assign exp = P_Expression.Expression.map( - dim.exp, - (repl) -> applyReplacements2(repl = repl), - ) - @assign exp = Ceval.evalExp(exp) - P_Dimension.Dimension.fromExp(exp, Variability.CONSTANT) - end - - _ => begin - dim - end - end - end - return dim -end - -""" #= Builds a binding for a record instance that doesn't have an explicit binding. - Binding expressions will be taken from the record fields when available, and - filled with empty expressions when not. =#""" -function buildRecordBinding(recordNode::InstNode, repl::ReplTree.Tree)::Expression - local result::Expression - - local cls_node::InstNode = classScope(recordNode) - local cls::Class = getClass(cls_node) - local comps::Array{InstNode} - local bindings::List{Expression} - local exp::Expression - local local_repl::ReplTree.Tree - - @assign result = begin - @match cls begin - INSTANCED_CLASS(elements = FLAT_TREE(components = comps)) => - begin - @assign bindings = nil - #= Create a replacement tree for just the record instance. This is - =# - #= needed for records that contain local references such as: - =# - #= record R - =# - #= Real x; - =# - #= Real y = x; - =# - #= end R; - =# - #= In that case we need to replace the 'x' in the binding of 'y' with - =# - #= the binding expression of 'x'. - =# - @assign local_repl = ReplTree.new() - for i = arrayLength(comps):(-1):1 - @assign exp = P_Expression.Expression.makeMutable(getBindingExp(comps[i], repl)) - @assign local_repl = ReplTree.add(local_repl, comps[i], exp) - @assign bindings = _cons(exp, bindings) - end - #= Add the expression to both the replacement tree and the list of bindings. - =# - #= Replace references to record fields with those fields' bindings in the tree. - =# - #= This will also update the list of bindings since they share mutable expresions. - =# - ReplTree.map( - local_repl, - (local_repl) -> applyBindingReplacement(repl = local_repl), - ) - P_Expression.Expression.makeRecord( - scopePath(cls_node), - cls.ty, - bindings, - ) - end - - TYPED_DERIVED(__) => begin - buildRecordBinding(cls.baseClass, repl) - end - end - end - return result -end - -function addInputReplacement( - node::InstNode, - argument::Expression, - repl::ReplTree.Tree, -)::ReplTree.Tree - - @assign repl = ReplTree.add(repl, node, argument) - return repl -end - -function applyBindingReplacement( - node::InstNode, - exp::Expression, - repl::ReplTree.Tree, -)::Expression - local outExp::Expression - - @assign outExp = - P_Expression.Expression.map(exp, (repl) -> applyReplacements2(repl = repl)) - return outExp -end - -function applyReplacements(repl::ReplTree.Tree, fnBody::List{<:Statement})::List{Statement} - - @assign fnBody = P_Statement.Statement.mapExpList( - fnBody, - () -> P_Expression.Expression.map(func = (repl) -> applyReplacements2(repl = repl)), - )#= AbsyntoJulia.dumpPattern: UNHANDLED Abyn.Exp =# - return fnBody -end - -function applyReplacements2(repl::ReplTree.Tree, exp::Expression)::Expression - - @assign exp = begin - @match exp begin - CREF_EXPRESSION(__) => begin - applyReplacementCref(repl, exp.cref, exp) - end - - _ => begin - exp - end - end - end - return exp -end - -function applyReplacementCref( - repl::ReplTree.Tree, - cref::ComponentRef, - exp::Expression, -)::Expression - local outExp::Expression - - local cref_parts::List{ComponentRef} - local repl_exp::Option{Expression} - local parent::InstNode - local node::InstNode - - #= Explode the cref into a list of parts in reverse order. - =# - @assign cref_parts = toListReverse(cref) - #= If the list is empty it's probably an iterator or _, which shouldn't be replaced. - =# - if listEmpty(cref_parts) - @assign outExp = exp - else - @assign parent = node(listHead(cref_parts)) - @assign repl_exp = ReplTree.getOpt(repl, parent) - if isSome(repl_exp) - @match SOME(outExp) = repl_exp - else - @assign outExp = exp - return outExp - end - @assign outExp = P_Expression.Expression.applySubscripts( - getSubscripts(listHead(cref_parts)), - outExp, - ) - @assign cref_parts = listRest(cref_parts) - if !listEmpty(cref_parts) - try - for cr in cref_parts - @assign node = node(cr) - @assign outExp = P_Expression.Expression.makeImmutable(outExp) - @assign outExp = - P_Expression.Expression.recordElement(name(node), outExp) - @assign outExp = P_Expression.Expression.applySubscripts( - getSubscripts(cr), - outExp, - ) - end - catch - Error.assertion( - false, - getInstanceName() + - " could not find replacement for " + - toString(cref), - sourceInfo(), - ) - end - end - @assign outExp = - P_Expression.Expression.map(outExp, (repl) -> applyReplacements2(repl = repl)) - end - #= Look up the replacement for the first part in the replacement tree. - =# - #= If the cref consists of more than one identifier we need to look up - =# - #= the corresponding record field in the expression. - =# - return outExp -end - -function optimizeBody(body::List{<:Statement})::List{Statement} - - @assign body = List(P_Statement.Statement.map(s, optimizeStatement) for s in body) - return body -end - -function optimizeStatement(stmt::Statement)::Statement - - @assign () = begin - local iter_exp::Expression - #= Replace iterators in for loops with mutable expressions, so we don't need - =# - #= to do it each time we enter a for loop during evaluation. - =# - @match stmt begin - P_Statement.Statement.FOR(__) => begin - #= Make a mutable expression with a placeholder value. - =# - @assign iter_exp = - P_Expression.Expression.makeMutable(P_Expression.Expression.EMPTY(TYPE_UNKNOWN())) - #= Replace the iterator with the expression in the body of the for loop. - =# - @assign stmt.body = List( - P_Statement.Statement.mapExp( - s, - (stmt.iterator, iter_exp) -> P_Expression.Expression.replaceIterator( - iterator = stmt.iterator, - iteratorValue = iter_exp, - ), - ) for s in stmt.body - ) - #= Replace the iterator node with the mutable expression too. - =# - @assign stmt.iterator = EXP_NODE(iter_exp) - () - end - - _ => begin - () - end - end - end - return stmt -end - -function createResult(repl::ReplTree.Tree, outputs::List{<:InstNode})::Expression - local exp::Expression - - local expl::List{Expression} - local types::List{M_Type} - local e::Expression - - if listLength(outputs) == 1 - @assign exp = Ceval.evalExp(ReplTree.get(repl, listHead(outputs))) - assertAssignedOutput(listHead(outputs), exp) - else - @assign expl = nil - @assign types = nil - for o in outputs - @assign e = Ceval.evalExp(ReplTree.get(repl, o)) - assertAssignedOutput(o, e) - @assign expl = _cons(e, expl) - end - @assign expl = listReverseInPlace(expl) - @assign types = List(P_Expression.Expression.typeOf(e) for e in expl) - @assign exp = TUPLE_EXPRESSION(TYPE_TUPLE(types, NONE()), expl) - end - return exp -end - -function assertAssignedOutput(outputNode::InstNode, value::Expression) - return @assign () = begin - @match value begin - P_Expression.Expression.EMPTY(__) => begin - Error.addSourceMessage( - Error.UNASSIGNED_FUNCTION_OUTPUT, - list(name(outputNode)), - info(outputNode), - ) - fail() - end - - _ => begin - () - end - end - end -end - -function evaluateStatements(stmts::List{<:Statement})::FlowControl - local ctrl::FlowControl = FlowControl.NEXT - - for s in stmts - @assign ctrl = evaluateStatement(s) - if ctrl != FlowControl.NEXT - if ctrl == FlowControl.CONTINUE - @assign ctrl = FlowControl.NEXT - end - break - end - end - return ctrl -end - -function evaluateStatement(stmt::Statement)::FlowControl - local ctrl::FlowControl - - #= adrpo: we really need some error handling here to detect which statement cannot be evaluated - =# - #= try - =# - @assign ctrl = begin - @match stmt begin - P_Statement.Statement.ASSIGNMENT(__) => begin - evaluateAssignment(stmt.lhs, stmt.rhs, stmt.source) - end - - P_Statement.Statement.FOR(__) => begin - evaluateFor(stmt.iterator, stmt.range, stmt.body, stmt.source) - end - - P_Statement.Statement.IF(__) => begin - evaluateIf(stmt.branches, stmt.source) - end - - P_Statement.Statement.ASSERT(__) => begin - evaluateAssert(stmt.condition, stmt) - end - - P_Statement.Statement.NORETCALL(__) => begin - evaluateNoRetCall(stmt.exp, stmt.source) - end - - P_Statement.Statement.WHILE(__) => begin - evaluateWhile(stmt.condition, stmt.body, stmt.source) - end - - P_Statement.Statement.RETURN(__) => begin - FlowControl.RETURN - end - - P_Statement.Statement.BREAK(__) => begin - FlowControl.BREAK - end - - _ => begin - Error.assertion( - false, - getInstanceName() + " failed on " + anyString(stmt) + "\\n", - sourceInfo(), - ) - fail() - end - end - end - #= else - =# - #= Error.assertion(false, getInstanceName() + \" failed to evaluate statement \" + Statement.toString(stmt) + \"\\n\", sourceInfo()); - =# - #= fail(); - =# - #= end try; - =# - return ctrl -end - -function evaluateAssignment( - lhsExp::Expression, - rhsExp::Expression, - source::DAE.ElementSource, -)::FlowControl - local ctrl::FlowControl = FlowControl.NEXT - - assignVariable(lhsExp, Ceval.evalExp(rhsExp, P_EvalTarget.STATEMENT(source))) - return ctrl -end - -function assignVariable(variable::Expression, value::Expression) - return @assign () = begin - local var::Expression - local val::Expression - local vals::List{Expression} - local var_ptr::Pointer{Expression} - #= variable := value - =# - @match (variable, value) begin - (MUTABLE_EXPRESSION(exp = var_ptr), _) => begin - P_Pointer.update(var_ptr, assignExp(P_Pointer.access(var_ptr), value)) - () - end - - (TUPLE_EXPRESSION(__), TUPLE_EXPRESSION(elements = vals)) => begin - #= (var1, var2, ...) := (value1, value2, ...) - =# - for var in variable.elements - @match _cons(val, vals) = vals - assignVariable(var, val) - end - () - end - - ( - SUBSCRIPTED_EXP_EXPRESSION( - exp = MUTABLE_EXPRESSION(exp = var_ptr), - ), - _, - ) => begin - #= variable[subscript1, subscript2, ...] := value - =# - assignSubscriptedVariable(var_ptr, variable.subscripts, value) - () - end - - (CREF_EXPRESSION(cref = WILD(__)), _) => - begin - () - end - - _ => begin - #= _ := value - =# - Error.assertion( - false, - getInstanceName() + - " failed on " + - P_Expression.Expression.toString(variable) + - " := " + - P_Expression.Expression.toString(value), - sourceInfo(), - ) - fail() - end - end - end -end - -function assignSubscriptedVariable( - variable::Pointer{<:Expression}, - subscripts::List{<:Subscript}, - value::Expression, -) - local subs::List{Subscript} - - @assign subs = List(eval(s) for s in subscripts) - return P_Pointer.update(variable, assignArrayElement(P_Pointer.access(variable), subs, value)) -end - -function assignArrayElement( - arrayExp::Expression, - subscripts::List{<:Subscript}, - value::Expression, -)::Expression - local result::Expression - - local sub::Expression - local val::Expression - local rest_subs::List{Subscript} - local idx::Integer - local subs::List{Expression} - local vals::List{Expression} - - @assign result = begin - @match (arrayExp, subscripts) begin - ( - P_Expression.Expression.ARRAY(__), - SUBSCRIPT_INDEX(sub) <| rest_subs, - ) where {(P_Expression.Expression.isScalarLiteral(sub))} => begin - @assign idx = P_Expression.Expression.toInteger(sub) - if listEmpty(rest_subs) - @assign arrayExp.elements = ListUtil.set(arrayExp.elements, idx, value) - else - @assign arrayExp.elements = ListUtil.set( - arrayExp.elements, - idx, - assignArrayElement(listGet(arrayExp.elements, idx), rest_subs, value), - ) - end - arrayExp - end - - (P_Expression.Expression.ARRAY(__), SUBSCRIPT_SLICE(sub) <| rest_subs) => begin - @assign subs = P_Expression.Expression.arrayElements(sub) - @assign vals = P_Expression.Expression.arrayElements(value) - if listEmpty(rest_subs) - for s in subs - @match _cons(val, vals) = vals - @assign idx = P_Expression.Expression.toInteger(s) - @assign arrayExp.elements = ListUtil.set(arrayExp.elements, idx, val) - end - else - for s in subs - @match _cons(val, vals) = vals - @assign idx = P_Expression.Expression.toInteger(s) - @assign arrayExp.elements = ListUtil.set( - arrayExp.elements, - idx, - assignArrayElement(listGet(arrayExp.elements, idx), rest_subs, val), - ) - end - end - arrayExp - end - - (P_Expression.Expression.ARRAY(__), SUBSCRIPT_WHOLE(__) <| rest_subs) => - begin - if listEmpty(rest_subs) - @assign arrayExp.elements = P_Expression.Expression.arrayElements(value) - else - @assign arrayExp.elements = - List(@do_threaded_for assignArrayElement(e, rest_subs, v) (e, v) ( - arrayExp.elements, - P_Expression.Expression.arrayElements(value), - )) - end - arrayExp - end - - _ => begin - Error.assertion( - false, - getInstanceName() + - ": unimplemented case for " + - P_Expression.Expression.toString(arrayExp) + - toStringList(subscripts) + - " = " + - P_Expression.Expression.toString(value), - sourceInfo(), - ) - fail() - end - end - end - return result -end - -function assignExp(lhs::Expression, rhs::Expression)::Expression - local result::Expression - - @assign result = begin - @match lhs begin - P_Expression.Expression.RECORD(__) => begin - assignRecord(lhs, rhs) - end - - _ => begin - rhs - end - end - end - #= TODO: Handle arrays. - =# - return result -end - -function assignRecord(lhs::Expression, rhs::Expression)::Expression - local result::Expression - - @assign result = begin - local elems::List{Expression} - local e::Expression - local val::Expression - local cls_tree::ClassTree - local comps::Array{InstNode} - local binding_exp::Option{Expression} - local ty::M_Type - @match rhs begin - P_Expression.Expression.RECORD(__) => begin - @match P_Expression.Expression.RECORD(elements = elems) = lhs - for v in rhs.elements - @match _cons(e, elems) = elems - assignVariable(e, v) - end - lhs - end - - CREF_EXPRESSION(__) => begin - @match P_Expression.Expression.RECORD(elements = elems) = lhs - @assign cls_tree = - classTree(getClass(node(rhs.cref))) - @assign comps = getComponents(cls_tree) - for c in comps - @match _cons(e, elems) = elems - @assign ty = getType(c) - @assign val = CREF_EXPRESSION( - Type.liftArrayLeftList(ty, Type.arrayDims(rhs.ty)), - prefixCref(c, ty, nil, rhs.cref), - ) - assignVariable(e, val) - end - lhs - end - - _ => begin - rhs - end - end - end - return result -end - -function evaluateFor( - iterator::InstNode, - range::Option{<:Expression}, - forBody::List{<:Statement}, - source::DAE.ElementSource, -)::FlowControl - local ctrl::FlowControl - - local range_iter::RangeIterator - local iter_exp::Pointer{Expression} - local range_exp::Expression - local value::Expression - local body::List{Statement} = forBody - local i::Integer = 0 - local limit::Integer = Flags.getConfigInt(Flags.EVAL_LOOP_LIMIT) - - @assign range_exp = Ceval.evalExp(Util.getOption(range), P_EvalTarget.STATEMENT(source)) - @assign range_iter = P_RangeIterator.RangeIterator.fromExp(range_exp) - if P_RangeIterator.RangeIterator.hasNext(range_iter) - @match EXP_NODE(exp = MUTABLE_EXPRESSION(exp = iter_exp)) = - iterator - while P_RangeIterator.RangeIterator.hasNext(range_iter) - @assign (range_iter, value) = P_RangeIterator.RangeIterator.next(range_iter) - P_Pointer.update(iter_exp, value) - @assign ctrl = evaluateStatements(body) - if ctrl != FlowControl.NEXT - if ctrl == FlowControl.BREAK - @assign ctrl = FlowControl.NEXT - end - break - end - @assign i = i + 1 - if i > limit - Error.addSourceMessage( - Error.EVAL_LOOP_LIMIT_REACHED, - list(String(limit)), - ElementSource.getInfo(source), - ) - fail() - end - end - end - #= Loop through each value in the iteration range. - =# - #= Update the mutable expression with the iteration value and evaluate the statement. - =# - return ctrl -end - -function evaluateIf( - branches::List{<:Tuple{<:Expression, List{<:Statement}}}, - source::DAE.ElementSource, -)::FlowControl - local ctrl::FlowControl - - local cond::Expression - local body::List{Statement} - - for branch in branches - @assign (cond, body) = branch - if P_Expression.Expression.isTrue(Ceval.evalExp(cond, P_EvalTarget.STATEMENT(source))) - @assign ctrl = evaluateStatements(body) - return ctrl - end - end - @assign ctrl = FlowControl.NEXT - return ctrl -end - -function evaluateAssert(condition::Expression, assertStmt::Statement)::FlowControl - local ctrl::FlowControl = FlowControl.NEXT - - local cond::Expression - local msg::Expression - local lvl::Expression - local source::DAE.ElementSource - local target::EvalTarget = - P_EvalTarget.STATEMENT(P_Statement.Statement.source(assertStmt)) - - if P_Expression.Expression.isFalse(Ceval.evalExp(condition, target)) - @match P_Statement.Statement.ASSERT(message = msg, level = lvl, source = source) = - assertStmt - @assign msg = Ceval.evalExp(msg, target) - @assign lvl = Ceval.evalExp(lvl, target) - @assign () = begin - @match (msg, lvl) begin - ( - STRING_EXPRESSION(__), - P_Expression.Expression.ENUM_LITERAL(name = "warning"), - ) => begin - Error.addSourceMessage( - Error.ASSERT_TRIGGERED_WARNING, - list(msg.value), - ElementSource.getInfo(source), - ) - () - end - - ( - STRING_EXPRESSION(__), - P_Expression.Expression.ENUM_LITERAL(name = "error"), - ) => begin - Error.addSourceMessage( - Error.ASSERT_TRIGGERED_ERROR, - list(msg.value), - ElementSource.getInfo(source), - ) - @assign ctrl = FlowControl.ASSERTION - () - end - - _ => begin - Error.assertion( - false, - getInstanceName() + - " failed to evaluate assert(false, " + - P_Expression.Expression.toString(msg) + - ", " + - P_Expression.Expression.toString(lvl) + - ")", - sourceInfo(), - ) - fail() - end - end - end - end - return ctrl -end - -function evaluateNoRetCall(callExp::Expression, source::DAE.ElementSource)::FlowControl - local ctrl::FlowControl = FlowControl.NEXT - - Ceval.evalExp(callExp, P_EvalTarget.STATEMENT(source)) - return ctrl -end - -function evaluateWhile( - condition::Expression, - body::List{<:Statement}, - source::DAE.ElementSource, -)::FlowControl - local ctrl::FlowControl = FlowControl.NEXT - - local i::Integer = 0 - local limit::Integer = Flags.getConfigInt(Flags.EVAL_LOOP_LIMIT) - local target::EvalTarget = P_EvalTarget.STATEMENT(source) - - while P_Expression.Expression.isTrue(Ceval.evalExp(condition, target)) - @assign ctrl = evaluateStatements(body) - if ctrl != FlowControl.NEXT - if ctrl == FlowControl.BREAK - @assign ctrl = FlowControl.NEXT - end - break - end - @assign i = i + 1 - if i > limit - Error.addSourceMessage( - Error.EVAL_LOOP_LIMIT_REACHED, - list(String(limit)), - ElementSource.getInfo(source), - ) - fail() - end - end - return ctrl -end - -function isKnownExternalFunc(name::String, ann::Option{<:SCode.Annotation})::Bool - local isKnown::Bool - - if isKnownLibrary(ann) - @assign isKnown = true - else - @assign isKnown = begin - @match name begin - "OpenModelica_regex" => begin - true - end - - _ => begin - false - end - end - end - end - return isKnown -end - -function isKnownLibrary(extAnnotation::Option{<:SCode.Annotation})::Bool - local isKnown::Bool = false - - local ann::SCode.Annotation - local oexp::Option{Absyn.Exp} - - if isSome(extAnnotation) - @match SOME(ann) = extAnnotation - @assign oexp = - SCodeUtil.getModifierBinding(SCodeUtil.lookupNamedAnnotation(ann, "Library")) - if isSome(oexp) - @assign isKnown = isKnownLibraryExp(Util.getOption(oexp)) - end - end - return isKnown -end - -function isKnownLibraryExp(exp::Absyn.Exp)::Bool - local isKnown::Bool - - @assign isKnown = begin - @match exp begin - Absyn.STRING("ModelicaExternalC") => begin - true - end - - Absyn.STRING("ModelicaIO") => begin - true - end - - Absyn.ARRAY(__) => begin - ListUtil.exist(exp.arrayExp, isKnownLibraryExp) - end - - _ => begin - false - end - end - end - return isKnown -end - -const FILE_TYPE_NAMES = list("NoFile", "RegularFile", "Directory", "SpecialFile")::List -const FILE_TYPE_PATH = - Absyn.QUALIFIED( - "Modelica", - Absyn.QUALIFIED( - "Utilities", - Absyn.QUALIFIED("Types", Absyn.IDENT("FileType")), - ), - )::Absyn.Path -const FILE_TYPE_TYPE = TYPE_ENUMERATION(FILE_TYPE_PATH, FILE_TYPE_NAMES)::M_Type -const FILE_TYPE_LITERALS = - list( - P_Expression.Expression.ENUM_LITERAL(FILE_TYPE_TYPE, "NoFile", 1), - P_Expression.Expression.ENUM_LITERAL(FILE_TYPE_TYPE, "RegularFile", 2), - P_Expression.Expression.ENUM_LITERAL(FILE_TYPE_TYPE, "Directory", 3), - P_Expression.Expression.ENUM_LITERAL(FILE_TYPE_TYPE, "SpecialFile", 4), - )::List -const COMPARE_NAMES = list("Less", "Equal", "Greater")::List -const COMPARE_PATH = - Absyn.QUALIFIED( - "Modelica", - Absyn.QUALIFIED( - "Utilities", - Absyn.QUALIFIED("Types", Absyn.IDENT("Compare")), - ), - )::Absyn.Path -const COMPARE_TYPE = TYPE_ENUMERATION(COMPARE_PATH, COMPARE_NAMES)::M_Type -const COMPARE_LITERALS = - list( - P_Expression.Expression.ENUM_LITERAL(COMPARE_TYPE, "Less", 1), - P_Expression.Expression.ENUM_LITERAL(COMPARE_TYPE, "Equal", 2), - P_Expression.Expression.ENUM_LITERAL(COMPARE_TYPE, "Greater", 3), - )::List - -function evaluateKnownExternal(name::String, args::List{<:Expression})::Expression - local result::Expression - - @assign result = begin - local s1::String - local s2::String - local i::Integer - local i2::Integer - local b::Bool - local r::AbstractFloat - local dims::Integer[2] - @match (name, args) begin - ("ModelicaInternal_countLines", STRING_EXPRESSION(s1) <| nil()) => - begin - INTEGER_EXPRESSION(ModelicaExternalC.Streams_countLines(s1)) - end - - ("ModelicaInternal_fullPathName", STRING_EXPRESSION(s1) <| nil()) => - begin - STRING_EXPRESSION(ModelicaExternalC.File_fullPathName(s1)) - end - - ( - "ModelicaInternal_print", - STRING_EXPRESSION(s1) <| STRING_EXPRESSION(s2) <| nil(), - ) => begin - ModelicaExternalC.Streams_print(s1, s2) - INTEGER_EXPRESSION(0) - end - - ( - "ModelicaInternal_readLine", - STRING_EXPRESSION(s1) <| INTEGER_EXPRESSION(i) <| nil(), - ) => begin - @assign (s1, b) = ModelicaExternalC.Streams_readLine(s1, i) - TUPLE_EXPRESSION( - TYPE_TUPLE(list(TYPE_STRING(), TYPE_BOOLEAN()), NONE()), - list(STRING_EXPRESSION(s1), P_Expression.Expression.BOOLEAN(b)), - ) - end - - ("ModelicaInternal_stat", STRING_EXPRESSION(s1) <| nil()) => begin - @assign i = ModelicaExternalC.File_stat(s1) - listGet(FILE_TYPE_LITERALS, i) - end - - ("ModelicaStreams_closeFile", STRING_EXPRESSION(s1) <| nil()) => begin - ModelicaExternalC.Streams_close(s1) - INTEGER_EXPRESSION(0) - end - - ( - "ModelicaStrings_compare", - STRING_EXPRESSION(s1) <| - STRING_EXPRESSION(s2) <| P_Expression.Expression.BOOLEAN(b) <| nil(), - ) => begin - @assign i = ModelicaExternalC.Strings_compare(s1, s2, b) - listGet(COMPARE_LITERALS, i) - end - - ("ModelicaStrings_length", STRING_EXPRESSION(s1) <| nil()) => begin - INTEGER_EXPRESSION(stringLength(s1)) - end - - ( - "ModelicaStrings_scanReal", - STRING_EXPRESSION(s1) <| - INTEGER_EXPRESSION(i) <| P_Expression.Expression.BOOLEAN(b) <| nil(), - ) => begin - @assign (i, r) = ModelicaExternalC.Strings_scanReal(s1, i, b) - TUPLE_EXPRESSION( - TYPE_TUPLE(list(TYPE_INTEGER(), TYPE_REAL()), NONE()), - list(INTEGER_EXPRESSION(i), P_Expression.REAL_EXPRESSION(r)), - ) - end - - ( - "ModelicaStrings_scanInteger", - STRING_EXPRESSION(s1) <| - INTEGER_EXPRESSION(i) <| P_Expression.Expression.BOOLEAN(b) <| nil(), - ) => begin - @assign (i, i2) = ModelicaExternalC.Strings_scanInteger(s1, i, b) - TUPLE_EXPRESSION( - TYPE_TUPLE(list(TYPE_INTEGER(), TYPE_INTEGER()), NONE()), - list(INTEGER_EXPRESSION(i), INTEGER_EXPRESSION(i2)), - ) - end - - ( - "ModelicaStrings_scanString", - STRING_EXPRESSION(s1) <| INTEGER_EXPRESSION(i) <| nil(), - ) => begin - @assign (i, s2) = ModelicaExternalC.Strings_scanString(s1, i) - TUPLE_EXPRESSION( - TYPE_TUPLE(list(TYPE_INTEGER(), TYPE_STRING()), NONE()), - list(INTEGER_EXPRESSION(i), STRING_EXPRESSION(s2)), - ) - end - - ( - "ModelicaStrings_scanIdentifier", - STRING_EXPRESSION(s1) <| INTEGER_EXPRESSION(i) <| nil(), - ) => begin - @assign (i, s2) = ModelicaExternalC.Strings_scanIdentifier(s1, i) - TUPLE_EXPRESSION( - TYPE_TUPLE(list(TYPE_INTEGER(), TYPE_STRING()), NONE()), - list(INTEGER_EXPRESSION(i), STRING_EXPRESSION(s2)), - ) - end - - ( - "ModelicaStrings_skipWhiteSpace", - STRING_EXPRESSION(s1) <| INTEGER_EXPRESSION(i) <| nil(), - ) => begin - INTEGER_EXPRESSION(ModelicaExternalC.Strings_skipWhiteSpace(s1, i)) - end - - ( - "ModelicaStrings_substring", - STRING_EXPRESSION(s1) <| - INTEGER_EXPRESSION(i) <| INTEGER_EXPRESSION(i2) <| nil(), - ) => begin - STRING_EXPRESSION(System.substring(s1, i, i2)) - end - - ("ModelicaStrings_hashString", STRING_EXPRESSION(s1) <| nil()) => begin - INTEGER_EXPRESSION(ModelicaExternalC.Strings_hashString(s1)) - end - - ("OpenModelica_regex", _) => begin - evaluateOpenModelicaRegex(args) - end - - ( - "ModelicaIO_readMatrixSizes", - STRING_EXPRESSION(s1) <| STRING_EXPRESSION(s2) <| nil(), - ) => begin - @assign dims = ModelicaExternalC.ModelicaIO_readMatrixSizes(s1, s2) - P_Expression.Expression.ARRAY( - Type.ARRAY(TYPE_INTEGER(), list(P_Dimension.Dimension.fromInteger(2))), - list( - INTEGER_EXPRESSION(dims[1]), - INTEGER_EXPRESSION(dims[2]), - ), - true, - ) - end - - ( - "ModelicaIO_readRealMatrix", - STRING_EXPRESSION(s1) <| - STRING_EXPRESSION(s2) <| - INTEGER_EXPRESSION(i) <| - INTEGER_EXPRESSION(i2) <| P_Expression.Expression.BOOLEAN(b) <| nil(), - ) => begin - evaluateModelicaIO_readRealMatrix(s1, s2, i, i2, b) - end - - _ => begin - Error.assertion( - false, - getInstanceName() + ": failed to evaluate " + name, - sourceInfo(), - ) - fail() - end - end - end - return result -end - -function evaluateOpenModelicaRegex(args::List{<:Expression})::Expression - local result::Expression - - local n::Integer - local i::Integer - local str::String - local re::String - local extended::Bool - local insensitive::Bool - local strs::List{String} - local expl::List{Expression} - local strs_ty::M_Type - local strs_exp::Expression - - @assign result = begin - @match args begin - STRING_EXPRESSION(str) <| - STRING_EXPRESSION(re) <| - INTEGER_EXPRESSION(i) <| - P_Expression.Expression.BOOLEAN(extended) <| - P_Expression.Expression.BOOLEAN(insensitive) <| nil() => begin - @assign (n, strs) = System.regex(str, re, i, extended, insensitive) - @assign expl = List(STRING_EXPRESSION(s) for s in strs) - @assign strs_ty = - Type.ARRAY(TYPE_STRING(), list(P_Dimension.Dimension.fromInteger(i))) - @assign strs_exp = P_Expression.Expression.makeArray(strs_ty, expl, true) - TUPLE_EXPRESSION( - TYPE_TUPLE(list(TYPE_INTEGER(), strs_ty), NONE()), - list(INTEGER_EXPRESSION(n), strs_exp), - ) - end - - _ => begin - Error.assertion( - false, - getInstanceName() + - " failed on OpenModelica_regex" + - ListUtil.toString( - args, - P_Expression.Expression.toString, - "", - "(", - ", ", - ")", - true, - ), - sourceInfo(), - ) - fail() - end - end - end - return result -end - -function evaluateModelicaIO_readRealMatrix( - fileName::String, - matrixName::String, - nrow::Integer, - ncol::Integer, - verboseRead::Bool, -)::Expression - local result::Expression - - local matrix::AbstractFloat - local row::List{Expression} - local rows::List{Expression} = nil - local ty::M_Type - - @assign matrix = ModelicaExternalC.ModelicaIO_readRealMatrix( - fileName, - matrixName, - nrow, - ncol, - verboseRead, - ) - @assign ty = Type.ARRAY(TYPE_REAL(), list(P_Dimension.Dimension.fromInteger(ncol))) - for r = 1:nrow - @assign row = nil - for c = 1:ncol - @assign row = _cons(P_Expression.REAL_EXPRESSION(matrix[r, c]), row) - end - @assign rows = _cons(P_Expression.Expression.ARRAY(ty, row, literal = true), rows) - end - @assign ty = Type.liftArrayLeft(ty, P_Dimension.Dimension.fromInteger(nrow)) - @assign result = P_Expression.Expression.ARRAY(ty, rows, literal = true) - return result -end - -function evaluateExternal2( - name::String, - fn::M_Function, - args::List{<:Expression}, - extArgs::List{<:Expression}, -)::Expression - local result::Expression - - local repl::ReplTree.Tree - local ext_args::List{Expression} - - @assign repl = createReplacements(fn, args) - @assign ext_args = List( - P_Expression.Expression.map(e, (repl) -> applyReplacements2(repl = repl)) - for e in extArgs - ) - evaluateExternal3(name, ext_args) - @assign result = createResult(repl, fn.outputs) - return result -end - -function evaluateExternal3(name::String, args::List{<:Expression}) - return @assign () = begin - @match name begin - "dgeev" => begin - EvalFunctionExt.Lapack_dgeev(args) - () - end - - "dgegv" => begin - EvalFunctionExt.Lapack_dgegv(args) - () - end - - "dgels" => begin - EvalFunctionExt.Lapack_dgels(args) - () - end - - "dgelsx" => begin - EvalFunctionExt.Lapack_dgelsx(args) - () - end - - "dgelsy" => begin - EvalFunctionExt.Lapack_dgelsy(args) - () - end - - "dgesv" => begin - EvalFunctionExt.Lapack_dgesv(args) - () - end - - "dgglse" => begin - EvalFunctionExt.Lapack_dgglse(args) - () - end - - "dgtsv" => begin - EvalFunctionExt.Lapack_dgtsv(args) - () - end - - "dgbsv" => begin - EvalFunctionExt.Lapack_dgtsv(args) - () - end - - "dgesvd" => begin - EvalFunctionExt.Lapack_dgesvd(args) - () - end - - "dgetrf" => begin - EvalFunctionExt.Lapack_dgetrf(args) - () - end - - "dgetrs" => begin - EvalFunctionExt.Lapack_dgetrs(args) - () - end - - "dgetri" => begin - EvalFunctionExt.Lapack_dgetri(args) - () - end - - "dgeqpf" => begin - EvalFunctionExt.Lapack_dgeqpf(args) - () - end - - "dorgqr" => begin - EvalFunctionExt.Lapack_dorgqr(args) - () - end - end - end -end - -@exportAll() -end diff --git a/src/NewFrontend/.#NFFlatModel.jl b/src/NewFrontend/.#NFFlatModel.jl new file mode 120000 index 0000000..41aeec8 --- /dev/null +++ b/src/NewFrontend/.#NFFlatModel.jl @@ -0,0 +1 @@ +johti17@win01225.23 \ No newline at end of file diff --git a/src/NewFrontend/BindingExpression.jl b/src/NewFrontend/BindingExpression.jl index 312cdc0..80633bc 100644 --- a/src/NewFrontend/BindingExpression.jl +++ b/src/NewFrontend/BindingExpression.jl @@ -255,8 +255,8 @@ function retype(exp::Expression) ::Expression () end - CALL_EXPRESSION(call = P_Call.TYPED_ARRAY_CONSTRUCTOR(__)) => begin - @assign exp.call = P_Call.retype(exp.call) + CALL_EXPRESSION(call = TYPED_ARRAY_CONSTRUCTOR(__)) => begin + @assign exp.call = retype(exp.call) () end @@ -470,7 +470,7 @@ function enumIndexExp(enumExp::Expression) ::Expression end _ => begin - CALL_EXPRESSION(P_Call.makeTypedCall(NFBuiltinFuncs.INTEGER_ENUM, list(enumExp), variability(enumExp))) + CALL_EXPRESSION(makeTypedCall(NFBuiltinFuncs.INTEGER_ENUM, list(enumExp), variability(enumExp))) end end end @@ -602,7 +602,7 @@ function variability(exp::Expression) ::VariabilityType end CALL_EXPRESSION(__) => begin - P_Call.variability(exp.call) + variability(exp.call) end SIZE_EXPRESSION(__) => begin @@ -713,7 +713,7 @@ function promote2(exp::Expression, isArray::Bool, dims::Integer, types::List{<:M if expanded @assign outExp = promote2(outExp, true, dims, types) else - @assign outExp = CALL_EXPRESSION(P_Call.makeTypedCall(NFBuiltinFuncs.PROMOTE, list(exp, INTEGER(dims)), variability(exp), listHead(types))) + @assign outExp = CALL_EXPRESSION(makeTypedCall(NFBuiltinFuncs.PROMOTE, list(exp, INTEGER(dims)), variability(exp), listHead(types))) end outExp end @@ -825,13 +825,13 @@ function hasArrayCall2(exp::Expression) ::Bool @assign hasArrayCall = begin @match exp begin CALL_EXPRESSION(call = call) => begin - @assign ty = P_Call.typeOf(call) - isArray(ty) && P_Call.isVectorizeable(call) + @assign ty = typeOf(call) + isArray(ty) && isVectorizeable(call) end TUPLE_ELEMENT_EXPRESSION(tupleExp = CALL_EXPRESSION(call = call)) => begin - @assign ty = Type.nthTupleType(P_Call.typeOf(call), exp.index) - isArray(ty) && P_Call.isVectorizeable(call) + @assign ty = Type.nthTupleType(typeOf(call), exp.index) + isArray(ty) && isVectorizeable(call) end _ => begin @@ -1078,7 +1078,7 @@ function makeOperatorRecordZero(recordNode::InstNode) ::Expression @assign op_node = lookupElement("'0'", getClass(recordNode)) P_Function.P_Function.instFunctionNode(op_node) @match list(fn) = P_Function.P_Function.typeNodeCache(op_node) - @assign zeroExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, nil, Variability.CONSTANT)) + @assign zeroExp = CALL_EXPRESSION(makeTypedCall(fn, nil, Variability.CONSTANT)) @assign zeroExp = Ceval.evalExp(zeroExp) zeroExp end @@ -1408,7 +1408,7 @@ end function containsIterator(exp::Expression, origin::ORIGIN_Type) ::Bool local iter::Bool - if ExpOrigin.flagSet(origin, ExpOrigin.FOR) + if flagSet(origin, ExpOrigin.FOR) @assign iter = contains(exp, isIterator) else @assign iter = false @@ -1510,7 +1510,7 @@ function callContainsShallow(call::Call, func::ContainsPred) ::Bool @assign res = begin local e::Expression @match call begin - P_Call.UNTYPED_CALL(__) => begin + UNTYPED_CALL(__) => begin @assign res = listContainsShallow(call.arguments, func) if ! res for arg in call.named_args @@ -1524,7 +1524,7 @@ function callContainsShallow(call::Call, func::ContainsPred) ::Bool res end - P_Call.ARG_TYPED_CALL(__) => begin + ARG_TYPED_CALL(__) => begin for arg in call.arguments @assign (e, _, _) = arg if func(e) @@ -1542,23 +1542,23 @@ function callContainsShallow(call::Call, func::ContainsPred) ::Bool false end - P_Call.TYPED_CALL(__) => begin + TYPED_CALL(__) => begin listContainsShallow(call.arguments, func) end - P_Call.UNTYPED_ARRAY_CONSTRUCTOR(__) => begin + UNTYPED_ARRAY_CONSTRUCTOR(__) => begin func(call.exp) end - P_Call.TYPED_ARRAY_CONSTRUCTOR(__) => begin + TYPED_ARRAY_CONSTRUCTOR(__) => begin func(call.exp) end - P_Call.UNTYPED_REDUCTION(__) => begin + UNTYPED_REDUCTION(__) => begin func(call.exp) end - P_Call.TYPED_REDUCTION(__) => begin + TYPED_REDUCTION(__) => begin func(call.exp) end end @@ -1706,7 +1706,7 @@ function callContains(call::Call, func::ContainsPred) ::Bool @assign res = begin local e::Expression @match call begin - P_Call.UNTYPED_CALL(__) => begin + UNTYPED_CALL(__) => begin @assign res = listContains(call.arguments, func) if ! res for arg in call.named_args @@ -1720,7 +1720,7 @@ function callContains(call::Call, func::ContainsPred) ::Bool res end - P_Call.ARG_TYPED_CALL(__) => begin + ARG_TYPED_CALL(__) => begin for arg in call.arguments @assign (e, _, _) = arg if contains(e, func) @@ -1738,23 +1738,23 @@ function callContains(call::Call, func::ContainsPred) ::Bool false end - P_Call.TYPED_CALL(__) => begin + TYPED_CALL(__) => begin listContains(call.arguments, func) end - P_Call.UNTYPED_ARRAY_CONSTRUCTOR(__) => begin + UNTYPED_ARRAY_CONSTRUCTOR(__) => begin contains(call.exp, func) end - P_Call.TYPED_ARRAY_CONSTRUCTOR(__) => begin + TYPED_ARRAY_CONSTRUCTOR(__) => begin contains(call.exp, func) end - P_Call.UNTYPED_REDUCTION(__) => begin + UNTYPED_REDUCTION(__) => begin contains(call.exp, func) end - P_Call.TYPED_REDUCTION(__) => begin + TYPED_REDUCTION(__) => begin contains(call.exp, func) end end @@ -1960,7 +1960,7 @@ function mapFoldCallShallow(call::Call, func::MapFunc, foldArg::ArgT) where {Ar local fold_exp::Tuple{Option{Expression}, String, String} local oe::Option{Expression} @match call begin - P_Call.UNTYPED_CALL(__) => begin + UNTYPED_CALL(__) => begin @assign (args, foldArg) = ListUtil.mapFold(call.arguments, func, foldArg) @assign nargs = nil for arg in call.named_args @@ -1968,10 +1968,10 @@ function mapFoldCallShallow(call::Call, func::MapFunc, foldArg::ArgT) where {Ar @assign (e, foldArg) = func(e, foldArg) @assign nargs = _cons((s, e), nargs) end - P_Call.UNTYPED_CALL(call.ref, args, listReverse(nargs), call.call_scope) + UNTYPED_CALL(call.ref, args, listReverse(nargs), call.call_scope) end - P_Call.ARG_TYPED_CALL(__) => begin + ARG_TYPED_CALL(__) => begin @assign targs = nil @assign tnargs = nil for arg in call.arguments @@ -1984,33 +1984,33 @@ function mapFoldCallShallow(call::Call, func::MapFunc, foldArg::ArgT) where {Ar @assign (e, foldArg) = func(e, foldArg) @assign tnargs = _cons((s, e, t, v), tnargs) end - P_Call.ARG_TYPED_CALL(call.ref, listReverse(targs), listReverse(tnargs), call.call_scope) + ARG_TYPED_CALL(call.ref, listReverse(targs), listReverse(tnargs), call.call_scope) end - P_Call.TYPED_CALL(__) => begin + TYPED_CALL(__) => begin @assign (args, foldArg) = ListUtil.mapFold(call.arguments, func, foldArg) - P_Call.TYPED_CALL(call.fn, call.ty, call.var, args, call.attributes) + TYPED_CALL(call.fn, call.ty, call.var, args, call.attributes) end - P_Call.UNTYPED_ARRAY_CONSTRUCTOR(__) => begin + UNTYPED_ARRAY_CONSTRUCTOR(__) => begin @assign (e, foldArg) = func(call.exp, foldArg) @assign iters = mapFoldCallIteratorsShallow(call.iters, func, foldArg) - P_Call.UNTYPED_ARRAY_CONSTRUCTOR(e, iters) + UNTYPED_ARRAY_CONSTRUCTOR(e, iters) end - P_Call.TYPED_ARRAY_CONSTRUCTOR(__) => begin + TYPED_ARRAY_CONSTRUCTOR(__) => begin @assign (e, foldArg) = func(call.exp, foldArg) @assign iters = mapFoldCallIteratorsShallow(call.iters, func, foldArg) - P_Call.TYPED_ARRAY_CONSTRUCTOR(call.ty, call.var, e, iters) + TYPED_ARRAY_CONSTRUCTOR(call.ty, call.var, e, iters) end - P_Call.UNTYPED_REDUCTION(__) => begin + UNTYPED_REDUCTION(__) => begin @assign (e, foldArg) = func(call.exp, foldArg) @assign iters = mapFoldCallIteratorsShallow(call.iters, func, foldArg) - P_Call.UNTYPED_REDUCTION(call.ref, e, iters) + UNTYPED_REDUCTION(call.ref, e, iters) end - P_Call.TYPED_REDUCTION(__) => begin + TYPED_REDUCTION(__) => begin @assign (e, foldArg) = func(call.exp, foldArg) @assign iters = mapFoldCallIteratorsShallow(call.iters, func, foldArg) @assign (default_exp, foldArg) = mapFoldOptShallow(call.defaultExp, func, foldArg) @@ -2021,7 +2021,7 @@ function mapFoldCallShallow(call::Call, func::MapFunc, foldArg::ArgT) where {Ar else @assign fold_exp = call.foldExp end - P_Call.TYPED_REDUCTION(call.fn, call.ty, call.var, e, iters, default_exp, fold_exp) + TYPED_REDUCTION(call.fn, call.ty, call.var, e, iters, default_exp, fold_exp) end end end @@ -2377,7 +2377,7 @@ function mapFoldCall(call::Call, func::MapFunc, foldArg::ArgT) where {ArgT} local fold_exp::Tuple{Option{Expression}, String, String} local oe::Option{Expression} @match call begin - P_Call.UNTYPED_CALL(__) => begin + UNTYPED_CALL(__) => begin @assign (args, foldArg) = ListUtil.map1Fold(call.arguments, mapFold, func, foldArg) @assign nargs = nil for arg in call.named_args @@ -2385,10 +2385,10 @@ function mapFoldCall(call::Call, func::MapFunc, foldArg::ArgT) where {ArgT} @assign (e, foldArg) = mapFold(e, func, foldArg) @assign nargs = _cons((s, e), nargs) end - P_Call.UNTYPED_CALL(call.ref, args, listReverse(nargs), call.call_scope) + UNTYPED_CALL(call.ref, args, listReverse(nargs), call.call_scope) end - P_Call.ARG_TYPED_CALL(__) => begin + ARG_TYPED_CALL(__) => begin @assign targs = nil @assign tnargs = nil for arg in call.arguments @@ -2401,30 +2401,30 @@ function mapFoldCall(call::Call, func::MapFunc, foldArg::ArgT) where {ArgT} @assign (e, foldArg) = mapFold(e, func, foldArg) @assign tnargs = _cons((s, e, t, v), tnargs) end - P_Call.ARG_TYPED_CALL(call.ref, listReverse(targs), listReverse(tnargs), call.call_scope) + ARG_TYPED_CALL(call.ref, listReverse(targs), listReverse(tnargs), call.call_scope) end - P_Call.TYPED_CALL(__) => begin + TYPED_CALL(__) => begin @assign (args, foldArg) = ListUtil.map1Fold(call.arguments, mapFold, func, foldArg) - P_Call.TYPED_CALL(call.fn, call.ty, call.var, args, call.attributes) + TYPED_CALL(call.fn, call.ty, call.var, args, call.attributes) end - P_Call.UNTYPED_ARRAY_CONSTRUCTOR(__) => begin + UNTYPED_ARRAY_CONSTRUCTOR(__) => begin @assign (e, foldArg) = mapFold(call.exp, func, foldArg) - P_Call.UNTYPED_ARRAY_CONSTRUCTOR(e, call.iters) + UNTYPED_ARRAY_CONSTRUCTOR(e, call.iters) end - P_Call.TYPED_ARRAY_CONSTRUCTOR(__) => begin + TYPED_ARRAY_CONSTRUCTOR(__) => begin @assign (e, foldArg) = mapFold(call.exp, func, foldArg) - P_Call.TYPED_ARRAY_CONSTRUCTOR(call.ty, call.var, e, call.iters) + TYPED_ARRAY_CONSTRUCTOR(call.ty, call.var, e, call.iters) end - P_Call.UNTYPED_REDUCTION(__) => begin + UNTYPED_REDUCTION(__) => begin @assign (e, foldArg) = mapFold(call.exp, func, foldArg) - P_Call.UNTYPED_REDUCTION(call.ref, e, call.iters) + UNTYPED_REDUCTION(call.ref, e, call.iters) end - P_Call.TYPED_REDUCTION(__) => begin + TYPED_REDUCTION(__) => begin @assign (e, foldArg) = mapFold(call.exp, func, foldArg) @assign (iters, foldArg) = mapFoldCallIterators(call.iters, func, foldArg) @assign (default_exp, foldArg) = mapFoldOpt(call.defaultExp, func, foldArg) @@ -2435,7 +2435,7 @@ function mapFoldCall(call::Call, func::MapFunc, foldArg::ArgT) where {ArgT} else @assign fold_exp = call.foldExp end - P_Call.TYPED_REDUCTION(call.fn, call.ty, call.var, e, iters, default_exp, fold_exp) + TYPED_REDUCTION(call.fn, call.ty, call.var, e, iters, default_exp, fold_exp) end end end @@ -2767,7 +2767,7 @@ function applyCall(call::Call, func::ApplyFunc) @assign () = begin local e::Expression @match call begin - P_Call.UNTYPED_CALL(__) => begin + UNTYPED_CALL(__) => begin applyList(call.arguments, func) for arg in call.named_args @assign (_, e) = arg @@ -2776,7 +2776,7 @@ function applyCall(call::Call, func::ApplyFunc) () end - P_Call.ARG_TYPED_CALL(__) => begin + ARG_TYPED_CALL(__) => begin for arg in call.arguments @assign (e, _, _) = arg apply(e, func) @@ -2788,12 +2788,12 @@ function applyCall(call::Call, func::ApplyFunc) () end - P_Call.TYPED_CALL(__) => begin + TYPED_CALL(__) => begin applyList(call.arguments, func) () end - P_Call.UNTYPED_ARRAY_CONSTRUCTOR(__) => begin + UNTYPED_ARRAY_CONSTRUCTOR(__) => begin apply(call.exp, func) for i in call.iters apply(Util.tuple22(i), func) @@ -2801,7 +2801,7 @@ function applyCall(call::Call, func::ApplyFunc) () end - P_Call.TYPED_ARRAY_CONSTRUCTOR(__) => begin + TYPED_ARRAY_CONSTRUCTOR(__) => begin apply(call.exp, func) for i in call.iters apply(Util.tuple22(i), func) @@ -2809,7 +2809,7 @@ function applyCall(call::Call, func::ApplyFunc) () end - P_Call.UNTYPED_REDUCTION(__) => begin + UNTYPED_REDUCTION(__) => begin apply(call.exp, func) for i in call.iters apply(Util.tuple22(i), func) @@ -2817,7 +2817,7 @@ function applyCall(call::Call, func::ApplyFunc) () end - P_Call.TYPED_REDUCTION(__) => begin + TYPED_REDUCTION(__) => begin apply(call.exp, func) for i in call.iters apply(Util.tuple22(i), func) @@ -3036,7 +3036,7 @@ function foldCall(call::Call, func::FoldFunc, foldArg::ArgT) where {ArgT} @assign () = begin local e::Expression @match call begin - P_Call.UNTYPED_CALL(__) => begin + UNTYPED_CALL(__) => begin @assign foldArg = foldList(call.arguments, func, foldArg) for arg in call.named_args @assign (_, e) = arg @@ -3045,7 +3045,7 @@ function foldCall(call::Call, func::FoldFunc, foldArg::ArgT) where {ArgT} () end - P_Call.ARG_TYPED_CALL(__) => begin + ARG_TYPED_CALL(__) => begin for arg in call.arguments @assign (e, _, _) = arg @assign foldArg = fold(e, func, foldArg) @@ -3057,12 +3057,12 @@ function foldCall(call::Call, func::FoldFunc, foldArg::ArgT) where {ArgT} () end - P_Call.TYPED_CALL(__) => begin + TYPED_CALL(__) => begin @assign foldArg = foldList(call.arguments, func, foldArg) () end - P_Call.UNTYPED_ARRAY_CONSTRUCTOR(__) => begin + UNTYPED_ARRAY_CONSTRUCTOR(__) => begin @assign foldArg = fold(call.exp, func, foldArg) for i in call.iters @assign foldArg = fold(Util.tuple22(i), func, foldArg) @@ -3070,7 +3070,7 @@ function foldCall(call::Call, func::FoldFunc, foldArg::ArgT) where {ArgT} () end - P_Call.TYPED_ARRAY_CONSTRUCTOR(__) => begin + TYPED_ARRAY_CONSTRUCTOR(__) => begin @assign foldArg = fold(call.exp, func, foldArg) for i in call.iters @assign foldArg = fold(Util.tuple22(i), func, foldArg) @@ -3078,7 +3078,7 @@ function foldCall(call::Call, func::FoldFunc, foldArg::ArgT) where {ArgT} () end - P_Call.UNTYPED_REDUCTION(__) => begin + UNTYPED_REDUCTION(__) => begin @assign foldArg = fold(call.exp, func, foldArg) for i in call.iters @assign foldArg = fold(Util.tuple22(i), func, foldArg) @@ -3086,7 +3086,7 @@ function foldCall(call::Call, func::FoldFunc, foldArg::ArgT) where {ArgT} () end - P_Call.TYPED_REDUCTION(__) => begin + TYPED_REDUCTION(__) => begin @assign foldArg = fold(call.exp, func, foldArg) for i in call.iters @assign foldArg = fold(Util.tuple22(i), func, foldArg) @@ -3331,7 +3331,7 @@ function mapCallShallow(call::Call, func::MapFunc) ::Call local default_exp::Option{Expression} local fold_exp::Tuple{Option{Expression}, String, String} @match call begin - P_Call.UNTYPED_CALL(__) => begin + UNTYPED_CALL(__) => begin @assign args = list(func(arg) for arg in call.arguments) @assign nargs = nil for arg in call.named_args @@ -3339,10 +3339,10 @@ function mapCallShallow(call::Call, func::MapFunc) ::Call @assign e = func(e) @assign nargs = _cons((s, e), nargs) end - P_Call.UNTYPED_CALL(call.ref, args, listReverse(nargs), call.call_scope) + UNTYPED_CALL(call.ref, args, listReverse(nargs), call.call_scope) end - P_Call.ARG_TYPED_CALL(__) => begin + ARG_TYPED_CALL(__) => begin @assign targs = nil @assign tnargs = nil for arg in call.arguments @@ -3355,35 +3355,35 @@ function mapCallShallow(call::Call, func::MapFunc) ::Call @assign e = func(e) @assign tnargs = _cons((s, e, t, v), tnargs) end - P_Call.ARG_TYPED_CALL(call.ref, listReverse(targs), listReverse(tnargs), call.call_scope) + ARG_TYPED_CALL(call.ref, listReverse(targs), listReverse(tnargs), call.call_scope) end - P_Call.TYPED_CALL(__) => begin + TYPED_CALL(__) => begin @assign args = list(func(arg) for arg in call.arguments) - P_Call.TYPED_CALL(call.fn, call.ty, call.var, args, call.attributes) + TYPED_CALL(call.fn, call.ty, call.var, args, call.attributes) end - P_Call.UNTYPED_ARRAY_CONSTRUCTOR(__) => begin + UNTYPED_ARRAY_CONSTRUCTOR(__) => begin @assign e = func(call.exp) - P_Call.UNTYPED_ARRAY_CONSTRUCTOR(e, call.iters) + UNTYPED_ARRAY_CONSTRUCTOR(e, call.iters) end - P_Call.TYPED_ARRAY_CONSTRUCTOR(__) => begin + TYPED_ARRAY_CONSTRUCTOR(__) => begin @assign e = func(call.exp) - P_Call.TYPED_ARRAY_CONSTRUCTOR(call.ty, call.var, e, call.iters) + TYPED_ARRAY_CONSTRUCTOR(call.ty, call.var, e, call.iters) end - P_Call.UNTYPED_REDUCTION(__) => begin + UNTYPED_REDUCTION(__) => begin @assign e = func(call.exp) - P_Call.UNTYPED_REDUCTION(call.ref, e, call.iters) + UNTYPED_REDUCTION(call.ref, e, call.iters) end - P_Call.TYPED_REDUCTION(__) => begin + TYPED_REDUCTION(__) => begin @assign e = func(call.exp) @assign iters = mapCallShallowIterators(call.iters, func) @assign default_exp = mapShallowOpt(call.defaultExp, func) @assign fold_exp = Util.applyTuple31(call.foldExp, (func) -> mapShallowOpt(func = func)) - P_Call.TYPED_REDUCTION(call.fn, call.ty, call.var, e, iters, default_exp, fold_exp) + TYPED_REDUCTION(call.fn, call.ty, call.var, e, iters, default_exp, fold_exp) end end end @@ -3730,7 +3730,7 @@ function mapCall(call::Call, func::MapFunc) ::Call local default_exp::Option{Expression} local fold_exp::Tuple{Option{Expression}, String, String} @match call begin - P_Call.UNTYPED_CALL(__) => begin + UNTYPED_CALL(__) => begin @assign args = list(map(arg, func) for arg in call.arguments) @assign nargs = nil for arg in call.named_args @@ -3738,10 +3738,10 @@ function mapCall(call::Call, func::MapFunc) ::Call @assign e = map(e, func) @assign nargs = _cons((s, e), nargs) end - P_Call.UNTYPED_CALL(call.ref, args, listReverse(nargs), call.call_scope) + UNTYPED_CALL(call.ref, args, listReverse(nargs), call.call_scope) end - P_Call.ARG_TYPED_CALL(__) => begin + ARG_TYPED_CALL(__) => begin @assign targs = nil @assign tnargs = nil for arg in call.arguments @@ -3754,38 +3754,38 @@ function mapCall(call::Call, func::MapFunc) ::Call @assign e = map(e, func) @assign tnargs = _cons((s, e, t, v), tnargs) end - P_Call.ARG_TYPED_CALL(call.ref, listReverse(targs), listReverse(tnargs), call.call_scope) + ARG_TYPED_CALL(call.ref, listReverse(targs), listReverse(tnargs), call.call_scope) end - P_Call.TYPED_CALL(__) => begin + TYPED_CALL(__) => begin @assign args = list(map(arg, func) for arg in call.arguments) - P_Call.TYPED_CALL(call.fn, call.ty, call.var, args, call.attributes) + TYPED_CALL(call.fn, call.ty, call.var, args, call.attributes) end - P_Call.UNTYPED_ARRAY_CONSTRUCTOR(__) => begin + UNTYPED_ARRAY_CONSTRUCTOR(__) => begin @assign e = map(call.exp, func) @assign iters = mapCallIterators(call.iters, func) - P_Call.UNTYPED_ARRAY_CONSTRUCTOR(e, iters) + UNTYPED_ARRAY_CONSTRUCTOR(e, iters) end - P_Call.TYPED_ARRAY_CONSTRUCTOR(__) => begin + TYPED_ARRAY_CONSTRUCTOR(__) => begin @assign e = map(call.exp, func) @assign iters = mapCallIterators(call.iters, func) - P_Call.TYPED_ARRAY_CONSTRUCTOR(call.ty, call.var, e, iters) + TYPED_ARRAY_CONSTRUCTOR(call.ty, call.var, e, iters) end - P_Call.UNTYPED_REDUCTION(__) => begin + UNTYPED_REDUCTION(__) => begin @assign e = map(call.exp, func) @assign iters = mapCallIterators(call.iters, func) - P_Call.UNTYPED_REDUCTION(call.ref, e, iters) + UNTYPED_REDUCTION(call.ref, e, iters) end - P_Call.TYPED_REDUCTION(__) => begin + TYPED_REDUCTION(__) => begin @assign e = map(call.exp, func) @assign iters = mapCallIterators(call.iters, func) @assign default_exp = mapOpt(call.defaultExp, func) @assign fold_exp = Util.applyTuple31(call.foldExp, (func) -> mapOpt(func = func)) - P_Call.TYPED_REDUCTION(call.fn, call.ty, call.var, e, iters, default_exp, fold_exp) + TYPED_REDUCTION(call.fn, call.ty, call.var, e, iters, default_exp, fold_exp) end end end @@ -4054,7 +4054,7 @@ end outExp end -function dimensionCount(exp::Expression) ::Integer +function dimensionCount(@nospecialize(exp::Expression))::Integer local dimCount::Integer @assign dimCount = begin @match exp begin @@ -4079,11 +4079,11 @@ function dimensionCount(exp::Expression) ::Integer end SUBSCRIPTED_EXP_EXPRESSION(__) => begin - Type.dimensionCount(exp.ty) + dimensionCount(exp.ty) end TUPLE_ELEMENT_EXPRESSION(__) => begin - Type.dimensionCount(exp.ty) + dimensionCount(exp.ty) end _ => begin @@ -4285,7 +4285,7 @@ function toDAE(exp::Expression)::DAE.Exp end CALL_EXPRESSION(__) => begin - P_Call.toDAE(exp.call) + toDAE(exp.call) end SIZE_EXPRESSION(__) => begin @@ -4360,7 +4360,7 @@ function toDAE(exp::Expression)::DAE.Exp PARTIAL_FUNCTION_APPLICATION_EXPRESSION(__) => begin @match _cons(fn, _) = P_Function.P_Function.typeRefCache(exp.fn) - DAE.PARTEVALFUNCTION(P_Function.P_Function.nameConsiderBuiltin(fn), list(toDAE(arg) for arg in exp.args), toDAE(exp.ty), toDAE(TYPE_FUNCTION(fn, FunctionTYPE_FUNCTIONAL_VARIABLE))) + DAE.PARTEVALFUNCTION(P_Function.nameConsiderBuiltin(fn), list(toDAE(arg) for arg in exp.args), toDAE(exp.ty), toDAE(TYPE_FUNCTION(fn, FunctionTYPE_FUNCTIONAL_VARIABLE))) end BINDING_EXP(__) => begin @@ -4644,7 +4644,7 @@ function toFlatString(exp::Expression) ::String end CALL_EXPRESSION(__) => begin - P_Call.toFlatString(exp.call) + toFlatString(exp.call) end SIZE_EXPRESSION(__) => begin @@ -4796,7 +4796,7 @@ function toString(exp::Expression) ::String end CALL_EXPRESSION(__) => begin - P_Call.toString(exp.call) + toString(exp.call) end SIZE_EXPRESSION(__) => begin @@ -5064,12 +5064,12 @@ function applyIndexSubscriptArrayConstructor(call::Call, index::Subscript) ::Exp local iters::List{Tuple{InstNode, Expression}} local iter::InstNode - @match P_Call.TYPED_ARRAY_CONSTRUCTOR(ty, var, exp, iters) = call + @match TYPED_ARRAY_CONSTRUCTOR(ty, var, exp, iters) = call @assign ((iter, iter_exp), iters) = ListUtil.splitLast(iters) @assign iter_exp = applySubscript(index, iter_exp) @assign subscriptedExp = replaceIterator(exp, iter, iter_exp) if ! listEmpty(iters) - @assign subscriptedExp = CALL_EXPRESSION(P_Call.TYPED_ARRAY_CONSTRUCTOR(Type.unliftArray(ty), var, subscriptedExp, iters)) + @assign subscriptedExp = CALL_EXPRESSION(TYPED_ARRAY_CONSTRUCTOR(Type.unliftArray(ty), var, subscriptedExp, iters)) end subscriptedExp end @@ -5097,13 +5097,13 @@ function applySubscriptCall(subscript::Subscript, exp::Expression, restSubscript local arg::Expression local ty::M_Type @match call begin - P_Call.TYPED_CALL(arguments = arg <| nil()) where (P_Function.P_Function.isSubscriptableBuiltin(call.fn)) => begin + TYPED_CALL(arguments = arg <| nil()) where (P_Function.P_Function.isSubscriptableBuiltin(call.fn)) => begin @assign arg = applySubscript(subscript, arg, restSubscripts) @assign ty = Type.copyDims(typeOf(arg), call.ty) - CALL(P_Call.TYPED_CALL(call.fn, ty, call.var, list(arg), call.attributes)) + CALL(TYPED_CALL(call.fn, ty, call.var, list(arg), call.attributes)) end - P_Call.TYPED_ARRAY_CONSTRUCTOR(__) => begin + TYPED_ARRAY_CONSTRUCTOR(__) => begin applySubscriptArrayConstructor(subscript, call, restSubscripts) end @@ -5139,7 +5139,7 @@ function applyIndexSubscriptRange2(startExp::Expression, stepExp::Option{<:Expre P_Expression.REAL_EXPRESSION(startExp.value + index - 1.0) end - (P_Expression.Expression.BOOLEAN(__), _) => begin + (P_Expression.BOOLEAN_EXPRESSION(__), _) => begin if index == 1 startExp else @@ -5307,9 +5307,9 @@ function applyIndexSubscriptTypename(ty::M_Type, index::Subscript) ::Expression @match ty begin TYPE_BOOLEAN(__) where (idx <= 2) => begin if idx == 1 - P_Expression.Expression.BOOLEAN(false) + P_Expression.BOOLEAN_EXPRESSION(false) else - P_Expression.Expression.BOOLEAN(true) + P_Expression.BOOLEAN_EXPRESSION(true) end end @@ -5390,7 +5390,7 @@ end applySubscriptRange(subscript, exp) end - CALL_EXPRESSION(call = P_Call.TYPED_ARRAY_CONSTRUCTOR(__)) => begin + CALL_EXPRESSION(call = TYPED_ARRAY_CONSTRUCTOR(__)) => begin applySubscriptArrayConstructor(subscript, exp.call, restSubscripts) end @@ -5663,7 +5663,7 @@ function setType(ty::NFType, exp::Expression) ::Expression end CALL_EXPRESSION(__) => begin - @assign exp.call = P_Call.setType(exp.call, ty) + @assign exp.call = setType(exp.call, ty) () end @@ -5784,7 +5784,7 @@ function typeOf(exp::Expression) ::M_Type end CALL_EXPRESSION(__) => begin - P_Call.typeOf(exp.call) + typeOf(exp.call) end SIZE_EXPRESSION(__) => begin @@ -6040,7 +6040,7 @@ end CALL_EXPRESSION(__) => begin @match CALL_EXPRESSION(call = c) = exp2 - P_Call.compare(exp1.call, c) + compare(exp1.call, c) end SIZE_EXPRESSION(__) => begin diff --git a/src/NewFrontend/NFAlgorithm.jl b/src/NewFrontend/NFAlgorithm.jl index 7de6eb1..a29eb6f 100644 --- a/src/NewFrontend/NFAlgorithm.jl +++ b/src/NewFrontend/NFAlgorithm.jl @@ -4,6 +4,14 @@ MapFunc = Function MapFunc = Function ApplyFn = Function @UniontypeDecl NFAlgorithm +Algorithm = NFAlgorithm + +@Uniontype NFAlgorithm begin + @Record ALGORITHM begin + statements::List{Statement} + source::DAE.ElementSource + end +end function toString(alg::Algorithm)::String local str::String @@ -48,10 +56,3 @@ function applyList(algs::List{<:Algorithm}, func::ApplyFn) end end end - -@Uniontype NFAlgorithm begin - @Record ALGORITHM begin - statements::List{Statement} - source::ElementSource - end -end diff --git a/src/NewFrontend/NFBuiltinCall.jl b/src/NewFrontend/NFBuiltinCall.jl index e4f7c90..72ddab5 100644 --- a/src/NewFrontend/NFBuiltinCall.jl +++ b/src/NewFrontend/NFBuiltinCall.jl @@ -1,1933 +1,1849 @@ - module NFBuiltinCall - - using MetaModelica - using ExportAll - - #= /* - * This file is part of OpenModelica. - * - * Copyright (c) 1998-2014, Open Source Modelica Consortium (OSMC), - * c/o Linköpings universitet, Department of Computer and Information Science, - * SE-58183 Linköping, Sweden. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3, - * ACCORDING TO RECIPIENTS CHOICE. - * - * The OpenModelica software and the Open Source Modelica - * Consortium (OSMC) Public License (OSMC-PL) are obtained - * from OSMC, either from the above address, - * from the URLs: http:www.ida.liu.se/projects/OpenModelica or - * http:www.openmodelica.org, and in the OpenModelica distribution. - * GNU version 3 is obtained from: http:www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH - * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. - * - * See the full OSMC Public License conditions for more details. - * - */ =# - import Absyn - import ..AbsynUtil - import ..NFCall.P_Call - import ..NFCall.P_CallAttributes - import ..P_NFExpression - P_Expression=P_NFExpression - Expression=P_NFExpression.NFExpression - import ..NFInstNode.P_InstNode - import ..NFPrefixes.Variability - import ..P_NFType - P_M_Type=P_NFType - M_Type=NFType - import ..P_NFSubscript - P_Subscript=P_NFSubscript - Subscript=P_NFSubscript.NFSubscript - - import ..Config - import .. Ceval=NFCeval - import ..P_NFComponentRef - P_ComponentRef=P_NFComponentRef - ComponentRef=P_NFComponentRef.NFComponentRef - import ..P_NFDimension - P_Dimension=P_NFDimension - import ListUtil - import ..MetaModelica.Dangerous.listReverseInPlace - import ..NFClass.P_Class - import ..NFFunction.P_Function - import ..NFFunction.P_FunctionMatchKind - import ..NFFunction.P_MatchedFunction - import ..NFFunction.NamedArg - import ..NFFunction.TypedArg - import ..NFFunction.TypedNamedArg - import ..NFInstNode.P_CachedData - import ..NFTyping.ExpOrigin - import ..NFPrefixes - P_Prefixes=NFPrefixes - Prefixes=NFPrefixes.Prefixes - import ..NFTypeCheck; TypeCheck=NFTypeCheck - import ..NFTyping; Typing=NFTyping - import ..Util - import ..P_NFExpandExp - P_ExpandExp=P_NFExpandExp - ExpandExp=P_NFExpandExp.NFExpandExp - import ..P_NFOperator - P_Operator=P_NFOperator - Operator=P_NFOperator.NFOperator - import ..NFComponent.P_Component - import ..NFPrefixes.ConnectorType - - function needSpecialHandling(call::Call) ::Bool - local special::Bool - - @assign () = begin - @match call begin - P_Call.UNTYPED_CALL(__) => begin - @match C_FUNCTION(specialBuiltin = special) = getFuncCache(classScope(node(call.ref))) - () - end - - _ => begin - Error.assertion(false, getInstanceName() + " got unknown call: " + P_Call.toString(call), sourceInfo()) - fail() - end - end - end - special - end - - function typeSpecial(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local cref::ComponentRef - local fn_node::InstNode - local first::Expression - local rest::List{Expression} - local name::String - local next_origin::ORIGIN_Type - - @match P_Call.UNTYPED_CALL(ref = cref) = call - @assign next_origin = ExpOrigin.setFlag(origin, ExpOrigin.SUBEXPRESSION) - @assign (callExp, ty, variability) = begin - @match firstName(cref) begin - "String" => begin - typeStringCall(call, next_origin, info) - end - - "actualStream" => begin - typeActualInStreamCall("actualStream", call, next_origin, info) - end - - "branch" => begin - typeBranchCall(call, next_origin, info) - end - - "cardinality" => begin - typeCardinalityCall(call, next_origin, info) - end - - "cat" => begin - typeCatCall(call, next_origin, info) - end - - "change" => begin - typeChangeCall(call, next_origin, info) - end - - "der" => begin - typeDerCall(call, next_origin, info) - end - - "diagonal" => begin - typeDiagonalCall(call, next_origin, info) - end - - "edge" => begin - typeEdgeCall(call, next_origin, info) - end - - "fill" => begin - typeFillCall(call, next_origin, info) - end - - "getInstanceName" => begin - typeGetInstanceName(call) - end - - "initial" => begin - typeDiscreteCall(call, next_origin, info) - end - - "inStream" => begin - typeActualInStreamCall("inStream", call, next_origin, info) - end - - "isRoot" => begin - typeIsRootCall(call, next_origin, info) - end - - "matrix" => begin - typeMatrixCall(call, next_origin, info) - end - - "max" => begin - typeMinMaxCall("max", call, next_origin, info) - end - - "min" => begin - typeMinMaxCall("min", call, next_origin, info) - end - - "ndims" => begin - typeNdimsCall(call, next_origin, info) - end - - "noEvent" => begin - typeNoEventCall(call, next_origin, info) - end - - "ones" => begin - typeZerosOnesCall("ones", call, next_origin, info) - end - - "potentialRoot" => begin - typePotentialRootCall(call, next_origin, info) - end - - "pre" => begin - typePreCall(call, next_origin, info) - end - - "product" => begin - typeProductCall(call, next_origin, info) - end - - "root" => begin - typeRootCall(call, next_origin, info) - end - - "rooted" => begin - typeRootedCall(call, next_origin, info) - end - - "uniqueRoot" => begin - typeUniqueRootCall(call, next_origin, info) - end - - "uniqueRootIndices" => begin - typeUniqueRootIndicesCall(call, next_origin, info) - end - - "scalar" => begin - typeScalarCall(call, next_origin, info) - end - - "smooth" => begin - typeSmoothCall(call, next_origin, info) - end - - "sum" => begin - typeSumCall(call, next_origin, info) - end - - "symmetric" => begin - typeSymmetricCall(call, next_origin, info) - end - - "terminal" => begin - typeDiscreteCall(call, next_origin, info) - end - - "transpose" => begin - typeTransposeCall(call, next_origin, info) - end - - "vector" => begin - typeVectorCall(call, next_origin, info) - end - - "zeros" => begin - typeZerosOnesCall("zeros", call, next_origin, info) - end - - "Clock" where (Config.synchronousFeaturesAllowed()) => begin - typeClockCall(call, next_origin, info) - end - - "sample" => begin - typeSampleCall(call, next_origin, info) - end - - "DynamicSelect" => begin - typeDynamicSelectCall("DynamicSelect", call, next_origin, info) - end - - _ => begin - #= /* - case \"hold\" guard Config.synchronousFeaturesAllowed() then typeHoldCall(call, next_origin, info); - case \"shiftSample\" guard Config.synchronousFeaturesAllowed() then typeShiftSampleCall(call, next_origin, info); - case \"backSample\" guard Config.synchronousFeaturesAllowed() then typeBackSampleCall(call, next_origin, info); - case \"noClock\" guard Config.synchronousFeaturesAllowed() then typeNoClockCall(call, next_origin, info); - case \"transition\" guard Config.synchronousFeaturesAllowed() then typeTransitionCall(call, next_origin, info); - case \"initialState\" guard Config.synchronousFeaturesAllowed() then typeInitialStateCall(call, next_origin, info); - case \"activeState\" guard Config.synchronousFeaturesAllowed() then typeActiveStateCall(call, next_origin, info); - case \"ticksInState\" guard Config.synchronousFeaturesAllowed() then typeTicksInStateCall(call, next_origin, info); - case \"timeInState\" guard Config.synchronousFeaturesAllowed() then typeTimeInStateCall(call, next_origin, info); - */ =# - Error.assertion(false, getInstanceName() + " got unhandled builtin function: " + P_Call.toString(call), sourceInfo()) - fail() - end - end - end - (callExp, ty, variability) - end - - function makeSizeExp(posArgs::List{<:Expression}, namedArgs::List{<:NamedArg}, info::SourceInfo) ::Expression - local callExp::Expression - - local argc::Integer = listLength(posArgs) - local arg1::Expression - local arg2::Expression - - assertNoNamedParams("size", namedArgs, info) - @assign callExp = begin - @match posArgs begin - arg1 <| nil() => begin - SIZE_EXPRESSION(arg1, NONE()) - end - - arg1 <| arg2 <| nil() => begin - SIZE_EXPRESSION(arg1, SOME(arg2)) - end - - _ => begin - Error.addSourceMessage(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list("size" + ListUtil.toString(posArgs, toString, "", "(", ", ", ")", true), "size(Any[:, ...]) => Integer[:]\\n size(Any[:, ...], Integer) => Integer"), info) - fail() - end - end - end - callExp - end - - function makeArrayExp(posArgs::List{<:Expression}, namedArgs::List{<:NamedArg}, info::SourceInfo) ::Expression - local arrayExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local ty::M_Type - assertNoNamedParams("array", namedArgs, info) - #= array can take any number of arguments, but needs at least one. - =# - if listEmpty(posArgs) - Error.addSourceMessage(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list("array" + ListUtil.toString(posArgs, toString, "", "(", ", ", ")", true), "array(Any, Any, ...) => Any[:]"), info) - fail() - end - @assign arrayExp = makeArray(TYPE_UNKNOWN(), posArgs) - arrayExp - end - - function makeCatExp(n::Integer, args::List{<:Expression}, tys::List{<:M_Type}, variability::VariabilityType, info::SourceInfo) ::Tuple{Expression, M_Type} - local ty::M_Type - local callExp::Expression - - local arg2::Expression - local args2::List{Expression} = nil - local res::List{Expression} = nil - local tys2::List{M_Type} = tys - local tys3::List{M_Type} - local dimsLst::List{List{Dimension}} = nil - local dims::List{Dimension} - local resTy::M_Type = TYPE_UNKNOWN() - local ty1::M_Type - local ty2::M_Type - local resTyToMatch::M_Type - local mk::TypeCheck.MatchKind - local maxn::Integer - local pos::Integer - local sumDim::Dimension - - Error.assertion(listLength(args) == listLength(tys) && listLength(args) >= 1, getInstanceName() + " got wrong input sizes", sourceInfo()) - #= First: Get the number of dimensions and the element type - =# - for arg in args - @match _cons(ty, tys2) = tys2 - @assign dimsLst = _cons(arrayDims(ty), dimsLst) - if Type.isEqual(resTy, TYPE_UNKNOWN()) - @assign resTy = arrayElementType(ty) - else - @assign (_, _, ty1, mk) = TypeCheck.matchExpressions(INTEGER_EXPRESSION(0), arrayElementType(ty), INTEGER_EXPRESSION(0), resTy) - if TypeCheck.isCompatibleMatch(mk) - @assign resTy = ty1 - end - end - end - @assign maxn = max(listLength(d) for d in dimsLst) - if maxn != min(listLength(d) for d in dimsLst) - Error.addSourceMessageAndFail(Error.NF_DIFFERENT_NUM_DIM_IN_ARGUMENTS, list(stringDelimitList(List(String(listLength(d)) for d in dimsLst), ", "), "cat"), info) - end - if n < 1 || n > maxn - Error.addSourceMessageAndFail(Error.NF_CAT_WRONG_DIMENSION, list(String(maxn), String(n)), info) - end - @assign tys2 = tys - @assign tys3 = nil - @assign args2 = nil - @assign pos = listLength(args) + 2 - #= Second: Try to match the element type of all the arguments - =# - for arg in args - @match _cons(ty, tys2) = tys2 - @assign pos = pos - 1 - @assign ty2 = setArrayElementType(ty, resTy) - @assign (arg2, ty1, mk) = TypeCheck.matchTypes(ty, ty2, arg, allowUnknown = true) - if TypeCheck.isIncompatibleMatch(mk) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list(String(pos), "cat", "arg", toString(arg), Type.toString(ty), Type.toString(ty2)), info) - end - @assign args2 = _cons(arg2, args2) - @assign tys3 = _cons(ty1, tys3) - end - #= Third: We now have matched the element types of all arguments - =# - #= Try to match the dimensions as well - =# - @assign resTy = TYPE_UNKNOWN() - @assign tys2 = tys3 - for arg in args2 - @match _cons(ty, tys2) = tys2 - if Type.isEqual(resTy, TYPE_UNKNOWN()) - @assign resTy = ty - else - @assign (_, _, ty1, mk) = TypeCheck.matchExpressions(INTEGER_EXPRESSION(0), ty, INTEGER_EXPRESSION(0), resTy) - if TypeCheck.isCompatibleMatch(mk) - @assign resTy = ty1 - end - end - end - #= Got the supertype of the dimensions; trying to match all arguments - =# - #= with the concatenated dimension set to unknown. - =# - @assign dims = arrayDims(resTy) - @assign resTyToMatch = ARRAY_TYPE(arrayElementType(resTy), ListUtil.set(dims, n, P_Dimension.Dimension.UNKNOWN())) - @assign dims = List(listGet(lst, n) for lst in dimsLst) - @assign sumDim = P_Dimension.Dimension.fromInteger(0) - for d in dims - @assign sumDim = P_Dimension.Dimension.add(sumDim, d) - end - #= Create the concatenated dimension - =# - @assign resTy = ARRAY_TYPE(arrayElementType(resTy), ListUtil.set(arrayDims(resTy), n, sumDim)) - @assign tys2 = tys3 - @assign tys3 = nil - @assign res = nil - @assign pos = listLength(args) + 2 - for arg in args2 - @match _cons(ty, tys2) = tys2 - @assign pos = pos - 1 - @assign (arg2, ty1, mk) = TypeCheck.matchTypes(ty, resTyToMatch, arg, allowUnknown = true) - if TypeCheck.isIncompatibleMatch(mk) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list(String(pos), "cat", "arg", toString(arg), Type.toString(ty), Type.toString(resTyToMatch)), info) - end - @assign res = _cons(arg2, res) - @assign tys3 = _cons(ty1, tys3) - end - #= We have all except dimension n having equal sizes; with matching types - =# - @assign ty = resTy - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(NFBuiltinFuncs.CAT, _cons(INTEGER_EXPRESSION(n), res), variability, resTy)) - (callExp, ty) - end - - function assertNoNamedParams(fnName::String, namedArgs::List{<:NamedArg}, info::SourceInfo) - if ! listEmpty(namedArgs) - Error.addSourceMessage(Error.NO_SUCH_PARAMETER, list(fnName, Util.tuple21(listHead(namedArgs))), info) - fail() - end - end - - function typeStringCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType - local outType::M_Type - local callExp::Expression - - local arg_ty::M_Type - local args::List{TypedArg} - local named_args::List{TypedNamedArg} - local ty_call::Call - - @match (@match P_Call.ARG_TYPED_CALL(_, args, named_args) = ty_call) = P_Call.typeNormalCall(call, origin, info) - @match _cons((_, arg_ty, _), _) = args - @assign arg_ty = arrayElementType(arg_ty) - if isComplex(arg_ty) - @assign (callExp, outType, var) = typeOverloadedStringCall(arg_ty, args, named_args, ty_call, origin, info) - else - @assign (callExp, outType, var) = typeBuiltinStringCall(ty_call, origin, info) - end - (callExp, outType, var) - end - - function typeBuiltinStringCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType - local ty::M_Type - local callExp::Expression - - local ty_call::Call - - @assign ty_call = P_Call.matchTypedNormalCall(call, origin, info) - @assign ty = P_Call.typeOf(ty_call) - @assign var = P_Call.variability(ty_call) - @assign callExp = CALL_EXPRESSION(ty_call) - (callExp, ty, var) - end - - function typeOverloadedStringCall(overloadedType::M_Type, args::List{<:TypedArg}, namedArgs::List{<:TypedNamedArg}, call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType = Variability.CONSTANT - local outType::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local candidates::List{M_Function} - local recopnode::InstNode - local matchedFunc::MatchedFunction - local matchedFunctions::List{MatchedFunction} - local exactMatches::List{MatchedFunction} - - @match TYPE_COMPLEX(cls = recopnode) = overloadedType - try - @assign fn_ref = P_Function.lookupFunctionSimple("'String'", recopnode) - catch - typeBuiltinStringCall(call, origin, info) - fail() - end - #= If there's no 'String' overload, let the normal String handler print the error. - =# - @assign fn_ref = P_Function.instFunctionRef(fn_ref, info(recopnode)) - @assign candidates = P_Function.typeRefCache(fn_ref) - #= for fn in candidates loop - =# - #= TypeCheck.checkValidOperatorOverload(\"'String'\", fn, recopnode); - =# - #= end for; - =# - @assign matchedFunctions = P_Function.matchFunctionsSilent(candidates, args, namedArgs, info) - @assign exactMatches = P_MatchedFunction.getExactMatches(matchedFunctions) - if listEmpty(exactMatches) - Error.addSourceMessage(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.typedString(call), P_Function.candidateFuncListString(candidates)), info) - fail() - end - if listLength(exactMatches) == 1 - @match _cons(matchedFunc, _) = exactMatches - @assign outType = P_Function.returnType(matchedFunc.func) - for arg in matchedFunc.args - @assign var = variabilityMax(var, Util.tuple33(arg)) - end - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(matchedFunc.func, List(Util.tuple31(a) for a in matchedFunc.args), var, outType)) - return (callExp, outType, var) - else - Error.addSourceMessage(Error.AMBIGUOUS_MATCHING_FUNCTIONS_NFINST, list(P_Call.typedString(call), P_Function.candidateFuncListString(List(mfn.func for mfn in matchedFunctions))), info) - fail() - end - (callExp, outType, var) - end - - """ #= Types a function call that can be typed normally, but which always has - discrete variability regardless of the variability of the arguments. =#""" - function typeDiscreteCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType = Variability.DISCRETE - local ty::M_Type - local callExp::Expression - - local argtycall::Call - local fn::M_Function - local args::List{TypedArg} - local start::TypedArg - local interval::TypedArg - - @assign argtycall = P_Call.typeMatchNormalCall(call, origin, info) - @assign ty = P_Call.typeOf(argtycall) - @assign callExp = CALL_EXPRESSION(P_Call.unboxArgs(argtycall)) - (callExp, ty, var) - end - - function typeNdimsCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType = Variability.PARAMETER - local ty::M_Type = TYPE_INTEGER() - local callExp::Expression - - local args::List{Expression} - local named_args::List{NamedArg} - local arg_ty::M_Type - - @match P_Call.UNTYPED_CALL(arguments = args, named_args = named_args) = call - assertNoNamedParams("ndims", named_args, info) - if listLength(args) != 1 - Error.addSourceMessage(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "ndims(Any) => Integer"), info) - fail() - end - #= The number of dimensions an expression has is always known, - =# - #= so we might as well evaluate the ndims call here. - =# - @assign (_, arg_ty, _) = Typing.typeExp(listHead(args), origin, info) - @assign callExp = INTEGER_EXPRESSION(Type.dimensionCount(arg_ty)) - (callExp, ty, variability) - end - - function typePreCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - @assign (callExp, ty, variability) = typePreChangeCall("pre", call, origin, info) - (callExp, ty, variability) - end - - function typeChangeCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - @assign (callExp, ty, variability) = typePreChangeCall("change", call, origin, info) - @assign ty = setArrayElementType(ty, TYPE_BOOLEAN()) - (callExp, ty, variability) - end - - function typePreChangeCall(name::String, call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType = Variability.DISCRETE - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local var::VariabilityType - local fn::M_Function - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams(name, named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Any) => Any"), info) - end - #= pre/change may not be used in a function context. - =# - if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) - Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) - end - @assign (arg, ty, var) = Typing.typeExp(listHead(args), origin, info) - if ! isCref(arg) - Error.addSourceMessage(Error.ARGUMENT_MUST_BE_VARIABLE, list("First", toString(fn_ref), ""), info) - fail() - end - if var == Variability.CONTINUOUS - Error.addSourceMessageAndFail(Error.INVALID_ARGUMENT_VARIABILITY, list("1", toString(fn_ref), P_Prefixes.variabilityString(Variability.DISCRETE), toString(arg), P_Prefixes.variabilityString(var)), info) - end - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign callExp = CALL(P_Call.makeTypedCall(fn, list(arg), var, ty)) - (callExp, ty, variability) - end - - function typeDerCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local fn::M_Function - local ety::M_Type - - #= der may not be used in a function context. - =# - if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) - Error.addSourceMessage(Error.EXP_INVALID_IN_FUNCTION, list("der"), info) - fail() - end - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("der", named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "der(Real) => Real"), info) - end - @match list(arg) = args - @assign (arg, ty, variability) = Typing.typeExp(arg, origin, info) - @assign ety = arrayElementType(ty) - if Type.isInteger(ety) - @assign ty = setArrayElementType(ty, TYPE_REAL()) - @assign arg = typeCast(arg, TYPE_REAL()) - elseif ! Type.isReal(ety) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("1", toString(fn_ref), "", toString(arg), Type.toString(ty), "Real"), info) - end - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) - (callExp, ty, variability) - end - - function typeDiagonalCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local dim::Dimension - local fn::M_Function - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("diagonal", named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "diagonal(Any[n]) => Any[n, n]"), info) - end - @assign (arg, ty, variability) = Typing.typeExp(listHead(args), origin, info) - @assign ty = begin - @match ty begin - ARRAY_TYPE(dimensions = dim <| nil()) => begin - ARRAY_TYPE(ty.elementType, list(dim, dim)) - end - - _ => begin - Error.addSourceMessage(Error.ARG_TYPE_MISMATCH, list("1", toString(fn_ref), "", toString(arg), Type.toString(ty), "Any[:]"), info) - fail() - end - end - end - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) - (callExp, ty, variability) - end - - function typeEdgeCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType = Variability.DISCRETE - local ty::M_Type - local callExp::Expression - - local argtycall::Call - local fn::M_Function - local args::List{TypedArg} - local arg::TypedArg - local fn_node::InstNode - local ca::CallAttributes - - #= edge may not be used in a function context. - =# - if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) - Error.addSourceMessage(Error.EXP_INVALID_IN_FUNCTION, list("edge"), info) - fail() - end - @match (@match P_Call.ARG_TYPED_CALL(CREF(node = fn_node), args, _) = argtycall) = P_Call.typeNormalCall(call, origin, info) - @assign argtycall = P_Call.matchTypedNormalCall(argtycall, origin, info) - @assign ty = P_Call.typeOf(argtycall) - @assign callExp = CALL_EXPRESSION(P_Call.unboxArgs(argtycall)) - @match list(arg) = args - if ! isCref(Util.tuple31(arg)) - Error.addSourceMessage(Error.ARGUMENT_MUST_BE_VARIABLE, list("First", "edge", ""), info) - fail() - end - (callExp, ty, variability) - end - - function typeMinMaxCall(name::String, call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local fn::M_Function - local arg1::Expression - local arg2::Expression - local ty1::M_Type - local ty2::M_Type - local var1::VariabilityType - local var2::VariabilityType - local mk::TypeCheck.MatchKind - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams(name, named_args, info) - @assign (args, ty, var) = begin - @match args begin - arg1 <| nil() => begin - @assign (arg1, ty1, var) = Typing.typeExp(arg1, origin, info) - @assign ty = arrayElementType(ty1) - if ! (isArray(ty1) && Type.isBasic(ty)) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("1", name, "", toString(arg1), Type.toString(ty1), "Any[:, ...]"), info) - end - #= If the argument is an array with a single element we can just - =# - #= return that element instead of making a min/max call. - =# - if Type.isSingleElementArray(ty1) - @assign callExp = applySubscript(first(listHead(arrayDims(ty1))), arg1) - return - end - (list(arg1), ty, var) - end - - arg1 <| arg2 <| nil() => begin - @assign (arg1, ty1, var1) = Typing.typeExp(arg1, origin, info) - @assign (arg2, ty2, var2) = Typing.typeExp(arg2, origin, info) - if ! Type.isBasic(ty1) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("1", name, "", toString(arg1), Type.toString(ty1), "Any"), info) - end - if ! Type.isBasic(ty2) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("2", name, "", toString(arg2), Type.toString(ty2), "Any"), info) - end - @assign (arg1, arg2, ty, mk) = TypeCheck.matchExpressions(arg1, ty1, arg2, ty2) - if ! TypeCheck.isValidArgumentMatch(mk) - Error.addSourceMessage(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), name + "(Any[:, ...]) => Any\\n" + name + "(Any, Any) => Any"), info) - end - (list(arg1, arg2), ty, variabilityMax(var1, var2)) - end - - _ => begin - Error.addSourceMessage(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), name + "(Any[:, ...]) => Any\\n" + name + "(Any, Any) => Any"), info) - fail() - end - end - end - @assign fn = listHead(P_Function.typeRefCache(fn_ref)) - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, args, var, ty)) - (callExp, ty, var) - end - - function typeSumCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local fn::M_Function - local expanded::Bool - local op::Operator - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("sum", named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "sum(Any[:, ...]) => Any"), info) - end - @assign (arg, ty, variability) = Typing.typeExp(listHead(args), origin, info) - @assign ty = arrayElementType(ty) - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) - (callExp, ty, variability) - end - - function typeProductCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local fn::M_Function - local expanded::Bool - local op::Operator - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("product", named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "product(Any[:, ...]) => Any"), info) - end - @assign (arg, ty, variability) = Typing.typeExp(listHead(args), origin, info) - @assign ty = arrayElementType(ty) - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) - (callExp, ty, variability) - end - - function typeSmoothCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg1::Expression - local arg2::Expression - local ty1::M_Type - local ty2::M_Type - local var::VariabilityType - local fn::M_Function - local mk::TypeCheck.MatchKind - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("smooth", named_args, info) - if listLength(args) != 2 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "smooth(Integer, Any) => Any"), info) - end - @match list(arg1, arg2) = args - @assign (arg1, ty1, var) = Typing.typeExp(arg1, origin, info) - @assign (arg2, ty2, variability) = Typing.typeExp(arg2, origin, info) - #= First argument must be Integer. - =# - if ! Type.isInteger(ty1) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("1", toString(fn_ref), "", toString(arg1), Type.toString(ty1), "Integer"), info) - end - #= First argument must be a parameter expression. - =# - if var > Variability.PARAMETER - Error.addSourceMessageAndFail(Error.INVALID_ARGUMENT_VARIABILITY, list("1", toString(fn_ref), P_Prefixes.variabilityString(Variability.PARAMETER), toString(arg1), P_Prefixes.variabilityString(variability)), info) - end - #= Second argument must be Real, array of allowed expressions or record - =# - #= containing only components of allowed expressions. - =# - #= TODO: Also handle records here. - =# - @assign (arg2, ty, mk) = TypeCheck.matchTypes(ty2, setArrayElementType(ty2, TYPE_REAL()), arg2, true) - if ! TypeCheck.isValidArgumentMatch(mk) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("2", toString(fn_ref), "", toString(arg2), Type.toString(ty2), "Real\\n Real[:, ...]\\n Real record\\n Real record[:, ...]"), info) - end - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg1, arg2), var, ty)) - (callExp, ty, variability) +function needSpecialHandling(call::Call) ::Bool + local special::Bool + + @assign () = begin + @match call begin + UNTYPED_CALL(__) => begin + @match C_FUNCTION(specialBuiltin = special) = getFuncCache(classScope(node(call.ref))) + () + end + + _ => begin + Error.assertion(false, getInstanceName() + " got unknown call: " + P_Call.toString(call), sourceInfo()) + fail() + end + end + end + special +end + +function typeSpecial(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, VariabilityType} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local cref::ComponentRef + local fn_node::InstNode + local first::Expression + local rest::List{Expression} + local name::String + local next_origin::ORIGIN_Type + + @match UNTYPED_CALL(ref = cref) = call + @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) + @assign (callExp, ty, variability) = begin + @match firstName(cref) begin + "String" => begin + typeStringCall(call, next_origin, info) + end + + "actualStream" => begin + typeActualInStreamCall("actualStream", call, next_origin, info) + end + + "branch" => begin + typeBranchCall(call, next_origin, info) + end + + "cardinality" => begin + typeCardinalityCall(call, next_origin, info) + end + + "cat" => begin + typeCatCall(call, next_origin, info) + end + + "change" => begin + typeChangeCall(call, next_origin, info) + end + + "der" => begin + typeDerCall(call, next_origin, info) + end + + "diagonal" => begin + typeDiagonalCall(call, next_origin, info) + end + + "edge" => begin + typeEdgeCall(call, next_origin, info) + end + + "fill" => begin + typeFillCall(call, next_origin, info) + end + + "getInstanceName" => begin + typeGetInstanceName(call) + end + + "initial" => begin + typeDiscreteCall(call, next_origin, info) + end + + "inStream" => begin + typeActualInStreamCall("inStream", call, next_origin, info) + end + + "isRoot" => begin + typeIsRootCall(call, next_origin, info) + end + + "matrix" => begin + typeMatrixCall(call, next_origin, info) + end + + "max" => begin + typeMinMaxCall("max", call, next_origin, info) + end + + "min" => begin + typeMinMaxCall("min", call, next_origin, info) + end + + "ndims" => begin + typeNdimsCall(call, next_origin, info) + end + + "noEvent" => begin + typeNoEventCall(call, next_origin, info) + end + + "ones" => begin + typeZerosOnesCall("ones", call, next_origin, info) + end + + "potentialRoot" => begin + typePotentialRootCall(call, next_origin, info) + end + + "pre" => begin + typePreCall(call, next_origin, info) + end + + "product" => begin + typeProductCall(call, next_origin, info) + end + + "root" => begin + typeRootCall(call, next_origin, info) + end + + "rooted" => begin + typeRootedCall(call, next_origin, info) + end + + "uniqueRoot" => begin + typeUniqueRootCall(call, next_origin, info) + end + + "uniqueRootIndices" => begin + typeUniqueRootIndicesCall(call, next_origin, info) + end + + "scalar" => begin + typeScalarCall(call, next_origin, info) + end + + "smooth" => begin + typeSmoothCall(call, next_origin, info) + end + + "sum" => begin + typeSumCall(call, next_origin, info) + end + + "symmetric" => begin + typeSymmetricCall(call, next_origin, info) + end + + "terminal" => begin + typeDiscreteCall(call, next_origin, info) + end + + "transpose" => begin + typeTransposeCall(call, next_origin, info) + end + + "vector" => begin + typeVectorCall(call, next_origin, info) + end + + "zeros" => begin + typeZerosOnesCall("zeros", call, next_origin, info) + end + + "Clock" where (Config.synchronousFeaturesAllowed()) => begin + typeClockCall(call, next_origin, info) + end + + "sample" => begin + typeSampleCall(call, next_origin, info) + end + + "DynamicSelect" => begin + typeDynamicSelectCall("DynamicSelect", call, next_origin, info) + end + + _ => begin + #= /* + case \"hold\" guard Config.synchronousFeaturesAllowed() then typeHoldCall(call, next_origin, info); + case \"shiftSample\" guard Config.synchronousFeaturesAllowed() then typeShiftSampleCall(call, next_origin, info); + case \"backSample\" guard Config.synchronousFeaturesAllowed() then typeBackSampleCall(call, next_origin, info); + case \"noClock\" guard Config.synchronousFeaturesAllowed() then typeNoClockCall(call, next_origin, info); + case \"transition\" guard Config.synchronousFeaturesAllowed() then typeTransitionCall(call, next_origin, info); + case \"initialState\" guard Config.synchronousFeaturesAllowed() then typeInitialStateCall(call, next_origin, info); + case \"activeState\" guard Config.synchronousFeaturesAllowed() then typeActiveStateCall(call, next_origin, info); + case \"ticksInState\" guard Config.synchronousFeaturesAllowed() then typeTicksInStateCall(call, next_origin, info); + case \"timeInState\" guard Config.synchronousFeaturesAllowed() then typeTimeInStateCall(call, next_origin, info); + */ =# + Error.assertion(false, getInstanceName() + " got unhandled builtin function: " + P_Call.toString(call), sourceInfo()) + fail() + end + end + end +(callExp, ty, variability) +end + +function makeSizeExp(posArgs::List{<:Expression}, namedArgs::List{<:NamedArg}, info::SourceInfo) ::Expression + local callExp::Expression + + local argc::Integer = listLength(posArgs) + local arg1::Expression + local arg2::Expression + + assertNoNamedParams("size", namedArgs, info) + @assign callExp = begin + @match posArgs begin + arg1 <| nil() => begin + SIZE_EXPRESSION(arg1, NONE()) + end + + arg1 <| arg2 <| nil() => begin + SIZE_EXPRESSION(arg1, SOME(arg2)) + end + + _ => begin + Error.addSourceMessage(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list("size" + ListUtil.toString(posArgs, toString, "", "(", ", ", ")", true), "size(Any[:, ...]) => Integer[:]\\n size(Any[:, ...], Integer) => Integer"), info) + fail() + end + end + end + callExp +end + +function makeArrayExp(posArgs::List{<:Expression}, namedArgs::List{<:NamedArg}, info::SourceInfo) ::Expression + local arrayExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local ty::M_Type + + assertNoNamedParams("array", namedArgs, info) + #= array can take any number of arguments, but needs at least one. + =# + if listEmpty(posArgs) + Error.addSourceMessage(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list("array" + ListUtil.toString(posArgs, toString, "", "(", ", ", ")", true), "array(Any, Any, ...) => Any[:]"), info) + fail() + end + @assign arrayExp = makeArray(TYPE_UNKNOWN(), posArgs) + arrayExp +end + +function makeCatExp(n::Integer, args::List{<:Expression}, tys::List{<:M_Type}, variability::VariabilityType, info::SourceInfo) ::Tuple{Expression, M_Type} + local ty::M_Type + local callExp::Expression + + local arg2::Expression + local args2::List{Expression} = nil + local res::List{Expression} = nil + local tys2::List{M_Type} = tys + local tys3::List{M_Type} + local dimsLst::List{List{Dimension}} = nil + local dims::List{Dimension} + local resTy::M_Type = TYPE_UNKNOWN() + local ty1::M_Type + local ty2::M_Type + local resTyToMatch::M_Type + local mk::TypeCheck.MatchKind + local maxn::Integer + local pos::Integer + local sumDim::Dimension + + Error.assertion(listLength(args) == listLength(tys) && listLength(args) >= 1, getInstanceName() + " got wrong input sizes", sourceInfo()) + #= First: Get the number of dimensions and the element type + =# + for arg in args + @match _cons(ty, tys2) = tys2 + @assign dimsLst = _cons(arrayDims(ty), dimsLst) + if Type.isEqual(resTy, TYPE_UNKNOWN()) + @assign resTy = arrayElementType(ty) + else + @assign (_, _, ty1, mk) = TypeCheck.matchExpressions(INTEGER_EXPRESSION(0), arrayElementType(ty), INTEGER_EXPRESSION(0), resTy) + if TypeCheck.isCompatibleMatch(mk) + @assign resTy = ty1 + end + end + end + @assign maxn = max(listLength(d) for d in dimsLst) + if maxn != min(listLength(d) for d in dimsLst) + Error.addSourceMessageAndFail(Error.NF_DIFFERENT_NUM_DIM_IN_ARGUMENTS, list(stringDelimitList(List(String(listLength(d)) for d in dimsLst), ", "), "cat"), info) + end + if n < 1 || n > maxn + Error.addSourceMessageAndFail(Error.NF_CAT_WRONG_DIMENSION, list(String(maxn), String(n)), info) + end + @assign tys2 = tys + @assign tys3 = nil + @assign args2 = nil + @assign pos = listLength(args) + 2 + #= Second: Try to match the element type of all the arguments + =# + for arg in args + @match _cons(ty, tys2) = tys2 + @assign pos = pos - 1 + @assign ty2 = setArrayElementType(ty, resTy) + @assign (arg2, ty1, mk) = TypeCheck.matchTypes(ty, ty2, arg, allowUnknown = true) + if TypeCheck.isIncompatibleMatch(mk) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list(String(pos), "cat", "arg", toString(arg), Type.toString(ty), Type.toString(ty2)), info) + end + @assign args2 = _cons(arg2, args2) + @assign tys3 = _cons(ty1, tys3) + end + #= Third: We now have matched the element types of all arguments + =# + #= Try to match the dimensions as well + =# + @assign resTy = TYPE_UNKNOWN() + @assign tys2 = tys3 + for arg in args2 + @match _cons(ty, tys2) = tys2 + if Type.isEqual(resTy, TYPE_UNKNOWN()) + @assign resTy = ty + else + @assign (_, _, ty1, mk) = TypeCheck.matchExpressions(INTEGER_EXPRESSION(0), ty, INTEGER_EXPRESSION(0), resTy) + if TypeCheck.isCompatibleMatch(mk) + @assign resTy = ty1 + end + end + end + #= Got the supertype of the dimensions; trying to match all arguments + =# + #= with the concatenated dimension set to unknown. + =# + @assign dims = arrayDims(resTy) + @assign resTyToMatch = ARRAY_TYPE(arrayElementType(resTy), ListUtil.set(dims, n, P_Dimension.Dimension.UNKNOWN())) + @assign dims = List(listGet(lst, n) for lst in dimsLst) + @assign sumDim = P_Dimension.Dimension.fromInteger(0) + for d in dims + @assign sumDim = P_Dimension.Dimension.add(sumDim, d) + end + #= Create the concatenated dimension + =# + @assign resTy = ARRAY_TYPE(arrayElementType(resTy), ListUtil.set(arrayDims(resTy), n, sumDim)) + @assign tys2 = tys3 + @assign tys3 = nil + @assign res = nil + @assign pos = listLength(args) + 2 + for arg in args2 + @match _cons(ty, tys2) = tys2 + @assign pos = pos - 1 + @assign (arg2, ty1, mk) = TypeCheck.matchTypes(ty, resTyToMatch, arg, allowUnknown = true) + if TypeCheck.isIncompatibleMatch(mk) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list(String(pos), "cat", "arg", toString(arg), Type.toString(ty), Type.toString(resTyToMatch)), info) + end + @assign res = _cons(arg2, res) + @assign tys3 = _cons(ty1, tys3) + end + #= We have all except dimension n having equal sizes; with matching types + =# + @assign ty = resTy + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(NFBuiltinFuncs.CAT, _cons(INTEGER_EXPRESSION(n), res), variability, resTy)) + (callExp, ty) +end + +function assertNoNamedParams(fnName::String, namedArgs::List{<:NamedArg}, info::SourceInfo) + if ! listEmpty(namedArgs) + Error.addSourceMessage(Error.NO_SUCH_PARAMETER, list(fnName, Util.tuple21(listHead(namedArgs))), info) + fail() + end +end + +function typeStringCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType + local outType::M_Type + local callExp::Expression + + local arg_ty::M_Type + local args::List{TypedArg} + local named_args::List{TypedNamedArg} + local ty_call::Call + + @match (@match P_Call.ARG_TYPED_CALL(_, args, named_args) = ty_call) = P_Call.typeNormalCall(call, origin, info) + @match _cons((_, arg_ty, _), _) = args + @assign arg_ty = arrayElementType(arg_ty) + if isComplex(arg_ty) + @assign (callExp, outType, var) = typeOverloadedStringCall(arg_ty, args, named_args, ty_call, origin, info) + else + @assign (callExp, outType, var) = typeBuiltinStringCall(ty_call, origin, info) + end + (callExp, outType, var) +end + +function typeBuiltinStringCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType + local ty::M_Type + local callExp::Expression + + local ty_call::Call + + @assign ty_call = P_Call.matchTypedNormalCall(call, origin, info) + @assign ty = P_Call.typeOf(ty_call) + @assign var = P_Call.variability(ty_call) + @assign callExp = CALL_EXPRESSION(ty_call) + (callExp, ty, var) +end + +function typeOverloadedStringCall(overloadedType::M_Type, args::List{<:TypedArg}, namedArgs::List{<:TypedNamedArg}, call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType = Variability.CONSTANT + local outType::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local candidates::List{M_Function} + local recopnode::InstNode + local matchedFunc::MatchedFunction + local matchedFunctions::List{MatchedFunction} + local exactMatches::List{MatchedFunction} + + @match TYPE_COMPLEX(cls = recopnode) = overloadedType + try + @assign fn_ref = P_Function.lookupFunctionSimple("'String'", recopnode) + catch + typeBuiltinStringCall(call, origin, info) + fail() + end + #= If there's no 'String' overload, let the normal String handler print the error. + =# + @assign fn_ref = P_Function.instFunctionRef(fn_ref, info(recopnode)) + @assign candidates = P_Function.typeRefCache(fn_ref) + #= for fn in candidates loop + =# + #= TypeCheck.checkValidOperatorOverload(\"'String'\", fn, recopnode); + =# + #= end for; + =# + @assign matchedFunctions = P_Function.matchFunctionsSilent(candidates, args, namedArgs, info) + @assign exactMatches = P_MatchedFunction.getExactMatches(matchedFunctions) + if listEmpty(exactMatches) + Error.addSourceMessage(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.typedString(call), P_Function.candidateFuncListString(candidates)), info) + fail() + end + if listLength(exactMatches) == 1 + @match _cons(matchedFunc, _) = exactMatches + @assign outType = P_Function.returnType(matchedFunc.func) + for arg in matchedFunc.args + @assign var = variabilityMax(var, Util.tuple33(arg)) + end + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(matchedFunc.func, List(Util.tuple31(a) for a in matchedFunc.args), var, outType)) + return (callExp, outType, var) + else + Error.addSourceMessage(Error.AMBIGUOUS_MATCHING_FUNCTIONS_NFINST, list(P_Call.typedString(call), P_Function.candidateFuncListString(List(mfn.func for mfn in matchedFunctions))), info) + fail() + end + (callExp, outType, var) +end + +""" #= Types a function call that can be typed normally, but which always has + discrete variability regardless of the variability of the arguments. =#""" + function typeDiscreteCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType = Variability.DISCRETE + local ty::M_Type + local callExp::Expression + + local argtycall::Call + local fn::M_Function + local args::List{TypedArg} + local start::TypedArg + local interval::TypedArg + + @assign argtycall = P_Call.typeMatchNormalCall(call, origin, info) + @assign ty = P_Call.typeOf(argtycall) + @assign callExp = CALL_EXPRESSION(P_Call.unboxArgs(argtycall)) + (callExp, ty, var) + end + +function typeNdimsCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType = Variability.PARAMETER + local ty::M_Type = TYPE_INTEGER() + local callExp::Expression + + local args::List{Expression} + local named_args::List{NamedArg} + local arg_ty::M_Type + + @match UNTYPED_CALL(arguments = args, named_args = named_args) = call + assertNoNamedParams("ndims", named_args, info) + if listLength(args) != 1 + Error.addSourceMessage(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "ndims(Any) => Integer"), info) + fail() + end + #= The number of dimensions an expression has is always known, + =# + #= so we might as well evaluate the ndims call here. + =# + @assign (_, arg_ty, _) = typeExp(listHead(args), origin, info) + @assign callExp = INTEGER_EXPRESSION(Type.dimensionCount(arg_ty)) + (callExp, ty, variability) +end + +function typePreCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + @assign (callExp, ty, variability) = typePreChangeCall("pre", call, origin, info) + (callExp, ty, variability) +end + +function typeChangeCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + @assign (callExp, ty, variability) = typePreChangeCall("change", call, origin, info) + @assign ty = setArrayElementType(ty, TYPE_BOOLEAN()) + (callExp, ty, variability) +end + +function typePreChangeCall(@nospecialize(name::String), @nospecialize(call::Call), origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType = Variability.DISCRETE + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local var::VariabilityType + local fn::M_Function + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams(name, named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Any) => Any"), info) + end + #= pre/change may not be used in a function context. + =# + if flagSet(origin, ORIGIN_FUNCTION) + Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) + end + @assign (arg, ty, var) = typeExp(listHead(args), origin, info) + if ! isCref(arg) + Error.addSourceMessage(Error.ARGUMENT_MUST_BE_VARIABLE, list("First", toString(fn_ref), ""), info) + fail() + end + if var == Variability.CONTINUOUS + Error.addSourceMessageAndFail(Error.INVALID_ARGUMENT_VARIABILITY, list("1", toString(fn_ref), P_Prefixes.variabilityString(Variability.DISCRETE), toString(arg), P_Prefixes.variabilityString(var)), info) + end + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign callExp = CALL(P_Call.makeTypedCall(fn, list(arg), var, ty)) + (callExp, ty, variability) +end + +function typeDerCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, NFType, VariabilityType} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local fn::M_Function + local ety::M_Type + + #= der may not be used in a function context. + =# + if flagSet(origin, ORIGIN_FUNCTION) + Error.addSourceMessage(Error.EXP_INVALID_IN_FUNCTION, list("der"), info) + fail() + end + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("der", named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "der(Real) => Real"), info) + end + @error "@match list(arg) = args" + arg = listHead(args) + @assign (arg, ty, variability) = typeExp(arg, origin, info) + @assign ety = arrayElementType(ty) + if isInteger(ety) + @assign ty = setArrayElementType(ty, TYPE_REAL()) + @assign arg = typeCast(arg, TYPE_REAL()) + elseif ! isReal(ety) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("1", toString(fn_ref), "", toString(arg), Type.toString(ty), "Real"), info) + end + @error "@match list(fn) = P_Function.typeRefCache(fn_ref) TODO" + fn = listHead(typeRefCache(fn_ref)) + @assign callExp = CALL_EXPRESSION(makeTypedCall(fn, list(arg), variability, ty)) + (callExp, ty, variability) +end + +function typeDiagonalCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local dim::Dimension + local fn::M_Function + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("diagonal", named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "diagonal(Any[n]) => Any[n, n]"), info) + end + @assign (arg, ty, variability) = typeExp(listHead(args), origin, info) + @assign ty = begin + @match ty begin + ARRAY_TYPE(dimensions = dim <| nil()) => begin + ARRAY_TYPE(ty.elementType, list(dim, dim)) + end + + _ => begin + Error.addSourceMessage(Error.ARG_TYPE_MISMATCH, list("1", toString(fn_ref), "", toString(arg), Type.toString(ty), "Any[:]"), info) + fail() + end + end + end + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) + (callExp, ty, variability) +end + +function typeEdgeCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType = Variability.DISCRETE + local ty::M_Type + local callExp::Expression + + local argtycall::Call + local fn::M_Function + local args::List{TypedArg} + local arg::TypedArg + local fn_node::InstNode + local ca::CallAttributes + + #= edge may not be used in a function context. + =# + if flagSet(origin, ORIGIN_FUNCTION) + Error.addSourceMessage(Error.EXP_INVALID_IN_FUNCTION, list("edge"), info) + fail() + end + @match (@match P_Call.ARG_TYPED_CALL(CREF(node = fn_node), args, _) = argtycall) = P_Call.typeNormalCall(call, origin, info) + @assign argtycall = P_Call.matchTypedNormalCall(argtycall, origin, info) + @assign ty = P_Call.typeOf(argtycall) + @assign callExp = CALL_EXPRESSION(P_Call.unboxArgs(argtycall)) + @match list(arg) = args + if ! isCref(Util.tuple31(arg)) + Error.addSourceMessage(Error.ARGUMENT_MUST_BE_VARIABLE, list("First", "edge", ""), info) + fail() + end + (callExp, ty, variability) +end + +function typeMinMaxCall(name::String, call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local fn::M_Function + local arg1::Expression + local arg2::Expression + local ty1::M_Type + local ty2::M_Type + local var1::VariabilityType + local var2::VariabilityType + local mk::TypeCheck.MatchKind + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams(name, named_args, info) + @assign (args, ty, var) = begin + @match args begin + arg1 <| nil() => begin + @assign (arg1, ty1, var) = typeExp(arg1, origin, info) + @assign ty = arrayElementType(ty1) + if ! (isArray(ty1) && Type.isBasic(ty)) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("1", name, "", toString(arg1), Type.toString(ty1), "Any[:, ...]"), info) end - - function typeFillCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local fill_arg::Expression - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("fill", named_args, info) - #= fill can take any number of arguments, but needs at least two. - =# - if listLength(args) < 2 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "fill(Any, Integer, ...) => Any[:, ...]"), info) - end - @match _cons(fill_arg, args) = args - #= Type the first argument, which is the fill value. - =# - @assign (fill_arg, ty, _) = Typing.typeExp(fill_arg, origin, info) - @assign (callExp, ty, variability) = typeFillCall2(fn_ref, ty, fill_arg, args, origin, info) - (callExp, ty, variability) + #= If the argument is an array with a single element we can just + =# + #= return that element instead of making a min/max call. + =# + if Type.isSingleElementArray(ty1) + @assign callExp = applySubscript(first(listHead(arrayDims(ty1))), arg1) + return end - - function typeFillCall2(fnRef::ComponentRef, fillType::M_Type, fillArg::Expression, dimensionArgs::List{<:Expression}, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType = Variability.CONSTANT - local ty::M_Type - local callExp::Expression - - local fill_arg::Expression - local ty_args::List{Expression} - local arg_var::VariabilityType - local arg_ty::M_Type - local fn::M_Function - local dims::List{Dimension} - local evaluated::Bool - - @assign ty_args = list(fillArg) - @assign dims = nil - @assign evaluated = true - #= Type the dimension arguments. - =# - for arg in dimensionArgs - @assign (arg, arg_ty, arg_var) = Typing.typeExp(arg, origin, info) - if arg_var <= Variability.STRUCTURAL_PARAMETER && ! ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) && ! containsIterator(arg, origin) - @assign arg = Ceval.evalExp(arg) - @assign arg_ty = typeOf(arg) - else - @assign evaluated = false - end - if ! Type.isInteger(arg_ty) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list(intString(listLength(ty_args) + 1), toString(fnRef), "", toString(arg), Type.toString(arg_ty), "Integer"), info) - end - @assign variability = variabilityMax(variability, arg_var) - @assign ty_args = _cons(arg, ty_args) - @assign dims = _cons(P_Dimension.Dimension.fromExp(arg, arg_var), dims) - end - #= Each dimension argument must be an Integer expression. - =# - @assign ty_args = listReverseInPlace(ty_args) - @assign dims = listReverseInPlace(dims) - @match list(fn) = P_Function.typeRefCache(fnRef) - @assign ty = Type.liftArrayLeftList(fillType, dims) - if evaluated - @assign callExp = Ceval.evalBuiltinFill(ty_args) - else - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(NFBuiltinFuncs.FILL_FUNC, ty_args, variability, ty)) - end - (callExp, ty, variability) + (list(arg1), ty, var) + end + + arg1 <| arg2 <| nil() => begin + @assign (arg1, ty1, var1) = typeExp(arg1, origin, info) + @assign (arg2, ty2, var2) = typeExp(arg2, origin, info) + if ! Type.isBasic(ty1) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("1", name, "", toString(arg1), Type.toString(ty1), "Any"), info) end - - function typeZerosOnesCall(name::String, call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local fill_arg::Expression - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams(name, named_args, info) - #= zeros/ones can take any number of arguments, but needs at least one. - =# - if listEmpty(args) - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Integer, ...) => Integer[:, ...]"), info) - end - @assign fill_arg = INTEGER_EXPRESSION(if name == "ones" - 1 - else - 0 - end) - @assign (callExp, ty, variability) = typeFillCall2(fn_ref, TYPE_INTEGER(), fill_arg, args, origin, info) - (callExp, ty, variability) + if ! Type.isBasic(ty2) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("2", name, "", toString(arg2), Type.toString(ty2), "Any"), info) end - - function typeScalarCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local fn::M_Function - local expanded::Bool - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("scalar", named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "scalar(Any[1, ...]) => Any"), info) - end - @assign (arg, ty, variability) = Typing.typeExp(listHead(args), origin, info) - #= scalar requires all dimensions of the array to be 1. - =# - for dim in arrayDims(ty) - if P_Dimension.Dimension.isKnown(dim) && ! P_Dimension.Dimension.size(dim) == 1 - Error.addSourceMessageAndFail(Error.INVALID_ARRAY_DIM_IN_SCALAR_OP, list(Type.toString(ty)), info) - end - end - @assign (arg, expanded) = P_ExpandExp.ExpandExp.expand(arg) - @assign ty = arrayElementType(ty) - if expanded - @assign args = arrayScalarElements(arg) - if listLength(args) != 1 - Error.assertion(false, getInstanceName() + " failed to expand scalar(" + toString(arg) + ") correctly", info) - end - @assign callExp = listHead(args) - else - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign callExp = CALL(P_Call.makeTypedCall(fn, list(arg), variability, ty)) - end - (callExp, ty, variability) + @assign (arg1, arg2, ty, mk) = TypeCheck.matchExpressions(arg1, ty1, arg2, ty2) + if ! TypeCheck.isValidArgumentMatch(mk) + Error.addSourceMessage(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), name + "(Any[:, ...]) => Any\\n" + name + "(Any, Any) => Any"), info) end - - function typeVectorCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local var::VariabilityType - local fn::M_Function - local vector_dim::Dimension = P_Dimension.Dimension.fromInteger(1) - local dim_found::Bool = false - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("vector", named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "vector(Any) => Any[:]\\n vector(Any[:, ...]) => Any[:]"), info) - end - @assign (arg, ty, variability) = Typing.typeExp(listHead(args), origin, info) - #= vector requires that at most one dimension is > 1, and that dimension - =# - #= determines the type of the vector call. - =# - for dim in arrayDims(ty) - if ! P_Dimension.Dimension.isKnown(dim) || P_Dimension.Dimension.size(dim) > 1 - if dim_found - Error.addSourceMessageAndFail(Error.NF_VECTOR_INVALID_DIMENSIONS, list(Type.toString(ty), P_Call.toString(call)), info) + (list(arg1, arg2), ty, variabilityMax(var1, var2)) + end + + _ => begin + Error.addSourceMessage(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), name + "(Any[:, ...]) => Any\\n" + name + "(Any, Any) => Any"), info) + fail() + end + end + end + @assign fn = listHead(P_Function.typeRefCache(fn_ref)) + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, args, var, ty)) + (callExp, ty, var) +end + +function typeSumCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local fn::M_Function + local expanded::Bool + local op::Operator + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("sum", named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "sum(Any[:, ...]) => Any"), info) + end + @assign (arg, ty, variability) = typeExp(listHead(args), origin, info) + @assign ty = arrayElementType(ty) + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) + (callExp, ty, variability) +end + +function typeProductCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local fn::M_Function + local expanded::Bool + local op::Operator + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("product", named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "product(Any[:, ...]) => Any"), info) + end + @assign (arg, ty, variability) = typeExp(listHead(args), origin, info) + @assign ty = arrayElementType(ty) + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) + (callExp, ty, variability) +end + +function typeSmoothCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg1::Expression + local arg2::Expression + local ty1::M_Type + local ty2::M_Type + local var::VariabilityType + local fn::M_Function + local mk::TypeCheck.MatchKind + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("smooth", named_args, info) + if listLength(args) != 2 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "smooth(Integer, Any) => Any"), info) + end + @match list(arg1, arg2) = args + @assign (arg1, ty1, var) = typeExp(arg1, origin, info) + @assign (arg2, ty2, variability) = typeExp(arg2, origin, info) + #= First argument must be Integer. + =# + if ! isInteger(ty1) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("1", toString(fn_ref), "", toString(arg1), Type.toString(ty1), "Integer"), info) + end + #= First argument must be a parameter expression. + =# + if var > Variability.PARAMETER + Error.addSourceMessageAndFail(Error.INVALID_ARGUMENT_VARIABILITY, list("1", toString(fn_ref), P_Prefixes.variabilityString(Variability.PARAMETER), toString(arg1), P_Prefixes.variabilityString(variability)), info) + end + #= Second argument must be Real, array of allowed expressions or record + =# + #= containing only components of allowed expressions. + =# + #= TODO: Also handle records here. + =# + @assign (arg2, ty, mk) = TypeCheck.matchTypes(ty2, setArrayElementType(ty2, TYPE_REAL()), arg2, true) + if ! TypeCheck.isValidArgumentMatch(mk) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("2", toString(fn_ref), "", toString(arg2), Type.toString(ty2), "Real\\n Real[:, ...]\\n Real record\\n Real record[:, ...]"), info) + end + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg1, arg2), var, ty)) + (callExp, ty, variability) +end + +function typeFillCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local fill_arg::Expression + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("fill", named_args, info) + #= fill can take any number of arguments, but needs at least two. + =# + if listLength(args) < 2 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "fill(Any, Integer, ...) => Any[:, ...]"), info) + end + @match _cons(fill_arg, args) = args + #= Type the first argument, which is the fill value. + =# + @assign (fill_arg, ty, _) = typeExp(fill_arg, origin, info) + @assign (callExp, ty, variability) = typeFillCall2(fn_ref, ty, fill_arg, args, origin, info) + (callExp, ty, variability) +end + +function typeFillCall2(fnRef::ComponentRef, fillType::M_Type, fillArg::Expression, dimensionArgs::List{<:Expression}, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType = Variability.CONSTANT + local ty::M_Type + local callExp::Expression + + local fill_arg::Expression + local ty_args::List{Expression} + local arg_var::VariabilityType + local arg_ty::M_Type + local fn::M_Function + local dims::List{Dimension} + local evaluated::Bool + + @assign ty_args = list(fillArg) + @assign dims = nil + @assign evaluated = true + #= Type the dimension arguments. + =# + for arg in dimensionArgs + @assign (arg, arg_ty, arg_var) = typeExp(arg, origin, info) + if arg_var <= Variability.STRUCTURAL_PARAMETER && ! flagSet(origin, ORIGIN_FUNCTION) && ! containsIterator(arg, origin) + @assign arg = Ceval.evalExp(arg) + @assign arg_ty = typeOf(arg) + else + @assign evaluated = false + end + if ! isInteger(arg_ty) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list(intString(listLength(ty_args) + 1), toString(fnRef), "", toString(arg), Type.toString(arg_ty), "Integer"), info) + end + @assign variability = variabilityMax(variability, arg_var) + @assign ty_args = _cons(arg, ty_args) + @assign dims = _cons(P_Dimension.Dimension.fromExp(arg, arg_var), dims) + end + #= Each dimension argument must be an Integer expression. + =# + @assign ty_args = listReverseInPlace(ty_args) + @assign dims = listReverseInPlace(dims) + @match list(fn) = P_Function.typeRefCache(fnRef) + @assign ty = Type.liftArrayLeftList(fillType, dims) + if evaluated + @assign callExp = Ceval.evalBuiltinFill(ty_args) + else + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(NFBuiltinFuncs.FILL_FUNC, ty_args, variability, ty)) + end + (callExp, ty, variability) +end + +function typeZerosOnesCall(name::String, call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local fill_arg::Expression + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams(name, named_args, info) + #= zeros/ones can take any number of arguments, but needs at least one. + =# + if listEmpty(args) + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Integer, ...) => Integer[:, ...]"), info) + end + @assign fill_arg = INTEGER_EXPRESSION(if name == "ones" + 1 + else + 0 + end) + @assign (callExp, ty, variability) = typeFillCall2(fn_ref, TYPE_INTEGER(), fill_arg, args, origin, info) + (callExp, ty, variability) +end + +function typeScalarCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local fn::M_Function + local expanded::Bool + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("scalar", named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "scalar(Any[1, ...]) => Any"), info) + end + @assign (arg, ty, variability) = typeExp(listHead(args), origin, info) + #= scalar requires all dimensions of the array to be 1. + =# + for dim in arrayDims(ty) + if P_Dimension.Dimension.isKnown(dim) && ! P_Dimension.Dimension.size(dim) == 1 + Error.addSourceMessageAndFail(Error.INVALID_ARRAY_DIM_IN_SCALAR_OP, list(Type.toString(ty)), info) + end + end + @assign (arg, expanded) = P_ExpandExp.ExpandExp.expand(arg) + @assign ty = arrayElementType(ty) + if expanded + @assign args = arrayScalarElements(arg) + if listLength(args) != 1 + Error.assertion(false, getInstanceName() + " failed to expand scalar(" + toString(arg) + ") correctly", info) + end + @assign callExp = listHead(args) + else + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign callExp = CALL(P_Call.makeTypedCall(fn, list(arg), variability, ty)) + end + (callExp, ty, variability) +end + +function typeVectorCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local var::VariabilityType + local fn::M_Function + local vector_dim::Dimension = P_Dimension.Dimension.fromInteger(1) + local dim_found::Bool = false + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("vector", named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "vector(Any) => Any[:]\\n vector(Any[:, ...]) => Any[:]"), info) + end + @assign (arg, ty, variability) = typeExp(listHead(args), origin, info) + #= vector requires that at most one dimension is > 1, and that dimension + =# + #= determines the type of the vector call. + =# + for dim in arrayDims(ty) + if ! P_Dimension.Dimension.isKnown(dim) || P_Dimension.Dimension.size(dim) > 1 + if dim_found + Error.addSourceMessageAndFail(Error.NF_VECTOR_INVALID_DIMENSIONS, list(Type.toString(ty), P_Call.toString(call)), info) + else + @assign vector_dim = dim + @assign dim_found = true + end + end + end + @assign ty = ARRAY_TYPE(arrayElementType(ty), list(vector_dim)) + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) + (callExp, ty, variability) +end + +function typeMatrixCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local var::VariabilityType + local fn::M_Function + local dims::List{Dimension} + local dim1::Dimension + local dim2::Dimension + local i::Integer + local ndims::Integer + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("matrix", named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "vector(Any) => Any[:]\\n vector(Any[:, ...]) => Any[:]"), info) + end + @assign (arg, ty, variability) = typeExp(listHead(args), origin, info) + @assign dims = arrayDims(ty) + @assign ndims = listLength(dims) + if ndims < 2 + @assign (callExp, ty) = promote(arg, ty, 2) + elseif ndims == 2 + @assign callExp = arg + else + @match _cons(dim1, _cons(dim2, dims)) = dims + @assign i = 3 + for dim in dims + if P_Dimension.Dimension.isKnown(dim) && P_Dimension.Dimension.size(dim) > 1 + Error.addSourceMessageAndFail(Error.INVALID_ARRAY_DIM_IN_CONVERSION_OP, list(String(i), "matrix", "1", P_Dimension.Dimension.toString(dim)), info) + end + @assign i = i + 1 + end + @assign ty = ARRAY_TYPE(arrayElementType(ty), list(dim1, dim2)) + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) + end + #= matrix(A) where A is a scalar or vector returns promote(A, 2). + =# + #= matrix(A) where A is a matrix just returns A. + =# + #= matrix requires all but the first two dimensions to have size 1. + =# + (callExp, ty, variability) +end + +function typeCatCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local res::List{Expression} + local named_args::List{NamedArg} + local tys::List{M_Type} + local arg::Expression + local var::VariabilityType + local mk::TypeCheck.MatchKind + local fn::M_Function + local n::Integer + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("cat", named_args, info) + if listLength(args) < 2 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "cat(Integer, Any[:,:], ...) => Any[:]"), info) + end + @match _cons(arg, args) = args + @assign (arg, ty, variability) = typeExp(arg, origin, info) + @assign (arg, ty, mk) = TypeCheck.matchTypes(ty, TYPE_INTEGER(), arg) + if variability > Variability.PARAMETER + Error.addSourceMessageAndFail(Error.NF_CAT_FIRST_ARG_EVAL, list(toString(arg), P_Prefixes.variabilityString(variability)), info) + end + @match INTEGER_EXPRESSION(n) = Ceval.evalExp(arg, Ceval.P_EvalTarget.GENERIC(info)) + @assign res = nil + @assign tys = nil + for a in args + @assign (arg, ty, var) = typeExp(a, origin, info) + @assign variability = variabilityMax(var, variability) + @assign res = _cons(arg, res) + @assign tys = _cons(ty, tys) + end + @assign (callExp, ty) = makeCatExp(n, listReverse(res), listReverse(tys), variability, info) + (callExp, ty, variability) +end + +function typeSymmetricCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local fn::M_Function + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("symmetric", named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "symmetric(Any[n, n]) => Any[n, n]"), info) + end + @assign (arg, ty, variability) = typeExp(listHead(args), origin, info) + if ! Type.isSquareMatrix(ty) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("1", toString(fn_ref), "", toString(arg), Type.toString(ty), "Any[n, n]"), info) + end + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) + (callExp, ty, variability) +end + +function typeTransposeCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local dim1::Dimension + local dim2::Dimension + local rest_dims::List{Dimension} + local fn::M_Function + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("transpose", named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "transpose(Any[n, m, ...]) => Any[m, n, ...]"), info) + end + @assign (arg, ty, variability) = typeExp(listHead(args), origin, info) + @assign ty = begin + @match ty begin + ARRAY_TYPE(dimensions = dim1 <| dim2 <| rest_dims) => begin + ARRAY_TYPE(ty.elementType, _cons(dim2, _cons(dim1, rest_dims))) + end + + _ => begin + Error.addSourceMessage(Error.ARG_TYPE_MISMATCH, list("1", toString(fn_ref), "", toString(arg), Type.toString(ty), "Any[:, :, ...]"), info) + fail() + end + end + end + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) + (callExp, ty, variability) +end + +function typeCardinalityCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType = Variability.PARAMETER + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local fn::M_Function + local node::InstNode + + #= cardinality may only be used in a condition of an assert or + =# + #= if-statement/equation (the specification says only if-statement, + =# + #= but e.g. the MSL only uses them in if-equations and asserts). + =# + if ! (flagSet(origin, ExpOrigin.CONDITION) && (flagSet(origin, ExpOrigin.IF) || flagSet(origin, ExpOrigin.ASSERT))) + Error.addSourceMessageAndFail(Error.INVALID_CARDINALITY_CONTEXT, nil, info) + end + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("cardinality", named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector) => Integer"), info) + end + if flagSet(origin, ORIGIN_FUNCTION) + Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) + end + @assign (arg, ty) = typeExp(listHead(args), origin, info) + if ! isCref(arg) + Error.addSourceMessageAndFail(Error.ARGUMENT_MUST_BE_VARIABLE, list("First", toString(fn_ref), ""), info) + end + @assign node = node(toCref(arg)) + if ! (Type.isScalar(ty) && isComponent(node) && P_Component.isConnector(component(node))) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("1", toString(fn_ref), "", toString(arg), Type.toString(ty), "connector"), info) + end + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign ty = TYPE_INTEGER() + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), var, ty)) + #= TODO: Check cardinality restrictions, 3.7.2.3. + =# + System.setUsesCardinality(true) + (callExp, ty, var) +end + +function typeBranchCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType = Variability.PARAMETER + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg1::Expression + local arg2::Expression + local fn::M_Function + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("Connections.branch", named_args, info) + if listLength(args) != 2 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector, Connector)"), info) + end + if flagSet(origin, ORIGIN_FUNCTION) + Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) + end + @match list(arg1, arg2) = args + @assign (arg1, ty) = typeExp(arg1, origin, info) + checkConnectionsArgument(arg1, ty, fn_ref, 1, info) + @assign (arg2, ty) = typeExp(arg2, origin, info) + checkConnectionsArgument(arg2, ty, fn_ref, 2, info) + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign ty = TYPE_NORETCALL() + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg1, arg2), var, ty)) + (callExp, ty, var) +end + +function typeIsRootCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType = Variability.PARAMETER + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local fn::M_Function + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("Connections.isRoot", named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector)"), info) + end + if flagSet(origin, ORIGIN_FUNCTION) + Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) + end + @assign (arg, ty) = typeExp(listHead(args), origin, info) + checkConnectionsArgument(arg, ty, fn_ref, 1, info) + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign ty = TYPE_BOOLEAN() + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), var, ty)) + (callExp, ty, var) +end + +function typePotentialRootCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType = Variability.PARAMETER + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg1::Expression + local arg2::Expression + local fn::M_Function + local args_len::Integer + local name::String + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + for narg in named_args + @assign (name, arg2) = narg + if name == "priority" + @assign args = ListUtil.appendElt(arg2, args) + else + Error.addSourceMessageAndFail(Error.NO_SUCH_PARAMETER, list(toString(fn_ref), name), info) + end + end + @assign args_len = listLength(args) + if args_len < 1 || args_len > 2 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector, Integer = 0)"), info) + end + if flagSet(origin, ORIGIN_FUNCTION) + Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) + end + @match _cons(arg1, args) = args + @assign (arg1, ty) = typeExp(arg1, origin, info) + checkConnectionsArgument(arg1, ty, fn_ref, 1, info) + if args_len == 2 + @assign arg2 = listHead(args) + @assign (arg2, ty) = typeExp(arg2, origin, info) + if ! isInteger(ty) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("2", toString(fn_ref), "", toString(arg2), Type.toString(ty), "Integer"), info) + end + else + @assign arg2 = INTEGER_EXPRESSION(0) + end + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign ty = TYPE_NORETCALL() + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg1, arg2), var, ty)) + (callExp, ty, var) +end + +function typeRootCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType = Variability.PARAMETER + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local fn::M_Function + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("Connections.root", named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector)"), info) + end + if flagSet(origin, ORIGIN_FUNCTION) + Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) + end + @assign (arg, ty) = typeExp(listHead(args), origin, info) + checkConnectionsArgument(arg, ty, fn_ref, 1, info) + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign ty = TYPE_NORETCALL() + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), var, ty)) + (callExp, ty, var) +end + +function typeRootedCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType = Variability.PARAMETER + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local fn::M_Function + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("Connections.rooted", named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector)"), info) + end + if flagSet(origin, ORIGIN_FUNCTION) + Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) + end + @assign (arg, ty) = typeExp(listHead(args), origin, info) + checkConnectionsArgument(arg, ty, fn_ref, 1, info) + if isSimple(fn_ref) + Error.addSourceMessage(Error.DEPRECATED_API_CALL, list("rooted", "Connections.rooted"), info) + end + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign ty = TYPE_BOOLEAN() + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), var, ty)) + (callExp, ty, var) +end + +""" #= see also typeUniqueRootIndicesCall =#""" +function typeUniqueRootCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType = Variability.PARAMETER + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg1::Expression + local arg2::Expression + local fn::M_Function + local args_len::Integer + local name::String + + Error.addSourceMessage(Error.NON_STANDARD_OPERATOR, list("Connections.uniqueRoot"), info) + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + for narg in named_args + @assign (name, arg2) = narg + if name == "message" + @assign args = ListUtil.appendElt(arg2, args) + else + Error.addSourceMessageAndFail(Error.NO_SUCH_PARAMETER, list(toString(fn_ref), name), info) + end + end + @assign args_len = listLength(args) + if args_len < 1 || args_len > 2 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector, String = \\\\)"), info) + end + if flagSet(origin, ORIGIN_FUNCTION) + Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) + end + @match _cons(arg1, args) = args + @assign (arg1, ty) = typeExp(arg1, origin, info) + checkConnectionsArgument(arg1, ty, fn_ref, 1, info) + if args_len == 2 + @assign arg2 = listHead(args) + @assign (arg2, ty) = typeExp(arg2, origin, info) + if ! Type.isString(ty) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("2", toString(fn_ref), "", toString(arg2), Type.toString(ty), "String"), info) + end + else + @assign arg2 = STRING_EXPRESSION("") + end + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign ty = TYPE_NORETCALL() + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg1, arg2), var, ty)) + (callExp, ty, var) +end + +""" #= See Modelica_StateGraph2: + https:github.com/modelica/Modelica_StateGraph2 + and + https:trac.modelica.org/Modelica/ticket/984 + and + http:www.ep.liu.se/ecp/043/041/ecp09430108.pdf + for a specification of this operator =#""" + function typeUniqueRootIndicesCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType = Variability.PARAMETER + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg1::Expression + local arg2::Expression + local arg3::Expression + local fn::M_Function + local args_len::Integer + local name::String + local ty1::M_Type + local ty2::M_Type + local ty3::M_Type + + Error.addSourceMessage(Error.NON_STANDARD_OPERATOR, list("Connections.uniqueRootIndices"), info) + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + for narg in named_args + @assign (name, arg3) = narg + if name == "message" + @assign args = ListUtil.appendElt(arg3, args) + else + Error.addSourceMessageAndFail(Error.NO_SUCH_PARAMETER, list(toString(fn_ref), name), info) + end + end + @assign args_len = listLength(args) + if args_len < 2 || args_len > 3 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector, Connector, String = \\\\)"), info) + end + if flagSet(origin, ORIGIN_FUNCTION) + Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) + end + @match _cons(arg1, _cons(arg2, args)) = args + @assign (arg1, ty1) = typeExp(arg1, origin, info) + checkConnectionsArgument(arg1, ty1, fn_ref, 1, info) + @assign (arg2, ty2) = typeExp(arg2, origin, info) + checkConnectionsArgument(arg2, ty2, fn_ref, 1, info) + if args_len == 3 + @assign arg3 = listHead(args) + @assign (arg3, ty3) = typeExp(arg3, origin, info) + if ! Type.isString(ty3) + Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("3", toString(fn_ref), "", toString(arg2), Type.toString(ty3), "String"), info) + end else - @assign vector_dim = dim - @assign dim_found = true + @assign arg2 = STRING_EXPRESSION("") end + @match list(fn) = P_Function.typeRefCache(fn_ref) + assert(listLength(arrayDims(ty1)) == listLength(arrayDims(ty2)), "the first two parameters need to have the same size") + @assign ty = ARRAY_TYPE(Type.TYPE_INTEGER(), arrayDims(ty1)) + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg1, arg2), var, ty)) + (callExp, ty, var) end - end - @assign ty = ARRAY_TYPE(arrayElementType(ty), list(vector_dim)) - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) - (callExp, ty, variability) - end - function typeMatrixCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local var::VariabilityType - local fn::M_Function - local dims::List{Dimension} - local dim1::Dimension - local dim2::Dimension - local i::Integer - local ndims::Integer - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("matrix", named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "vector(Any) => Any[:]\\n vector(Any[:, ...]) => Any[:]"), info) - end - @assign (arg, ty, variability) = Typing.typeExp(listHead(args), origin, info) - @assign dims = arrayDims(ty) - @assign ndims = listLength(dims) - if ndims < 2 - @assign (callExp, ty) = promote(arg, ty, 2) - elseif ndims == 2 - @assign callExp = arg - else - @match _cons(dim1, _cons(dim2, dims)) = dims - @assign i = 3 - for dim in dims - if P_Dimension.Dimension.isKnown(dim) && P_Dimension.Dimension.size(dim) > 1 - Error.addSourceMessageAndFail(Error.INVALID_ARRAY_DIM_IN_CONVERSION_OP, list(String(i), "matrix", "1", P_Dimension.Dimension.toString(dim)), info) - end - @assign i = i + 1 - end - @assign ty = ARRAY_TYPE(arrayElementType(ty), list(dim1, dim2)) - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) - end - #= matrix(A) where A is a scalar or vector returns promote(A, 2). - =# - #= matrix(A) where A is a matrix just returns A. - =# - #= matrix requires all but the first two dimensions to have size 1. - =# - (callExp, ty, variability) - end - - function typeCatCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local res::List{Expression} - local named_args::List{NamedArg} - local tys::List{M_Type} - local arg::Expression - local var::VariabilityType - local mk::TypeCheck.MatchKind - local fn::M_Function - local n::Integer - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("cat", named_args, info) - if listLength(args) < 2 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "cat(Integer, Any[:,:], ...) => Any[:]"), info) - end - @match _cons(arg, args) = args - @assign (arg, ty, variability) = Typing.typeExp(arg, origin, info) - @assign (arg, ty, mk) = TypeCheck.matchTypes(ty, TYPE_INTEGER(), arg) - if variability > Variability.PARAMETER - Error.addSourceMessageAndFail(Error.NF_CAT_FIRST_ARG_EVAL, list(toString(arg), P_Prefixes.variabilityString(variability)), info) - end - @match INTEGER_EXPRESSION(n) = Ceval.evalExp(arg, Ceval.P_EvalTarget.GENERIC(info)) - @assign res = nil - @assign tys = nil - for a in args - @assign (arg, ty, var) = Typing.typeExp(a, origin, info) - @assign variability = variabilityMax(var, variability) - @assign res = _cons(arg, res) - @assign tys = _cons(ty, tys) - end - @assign (callExp, ty) = makeCatExp(n, listReverse(res), listReverse(tys), variability, info) - (callExp, ty, variability) - end - - function typeSymmetricCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local fn::M_Function - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("symmetric", named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "symmetric(Any[n, n]) => Any[n, n]"), info) - end - @assign (arg, ty, variability) = Typing.typeExp(listHead(args), origin, info) - if ! Type.isSquareMatrix(ty) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("1", toString(fn_ref), "", toString(arg), Type.toString(ty), "Any[n, n]"), info) - end - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) - (callExp, ty, variability) - end - - function typeTransposeCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local dim1::Dimension - local dim2::Dimension - local rest_dims::List{Dimension} - local fn::M_Function - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("transpose", named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "transpose(Any[n, m, ...]) => Any[m, n, ...]"), info) - end - @assign (arg, ty, variability) = Typing.typeExp(listHead(args), origin, info) - @assign ty = begin - @match ty begin - ARRAY_TYPE(dimensions = dim1 <| dim2 <| rest_dims) => begin - ARRAY_TYPE(ty.elementType, _cons(dim2, _cons(dim1, rest_dims))) +function checkConnectionsArgument(arg::Expression, ty::M_Type, fnRef::ComponentRef, argIndex::Integer, info::SourceInfo) + @assign () = begin + local ty2::M_Type + local node::InstNode + local valid_cref::Bool + local isConnector::Bool + @match arg begin + CREF_EXPRESSION(__) => begin + @assign (valid_cref, isConnector) = begin + @match arg.cref begin + CREF(node = node, origin = P_NFComponentRef.Origin.CREF, restCref = CREF(ty = ty2, origin = P_NFComponentRef.Origin.CREF)) => begin + #= check form A.R + =# + @assign ty2 = begin + @match ty2 begin + ARRAY_TYPE(__) where (listLength(subscriptsAllFlat(arg.cref)) == listLength(ty2.dimensions)) => begin + ty2.elementType end _ => begin - Error.addSourceMessage(Error.ARG_TYPE_MISMATCH, list("1", toString(fn_ref), "", toString(arg), Type.toString(ty), "Any[:, :, ...]"), info) - fail() + ty2 end end end - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) - (callExp, ty, variability) - end + (isOverdetermined(getClass(node)), Type.isConnector(ty2)) + end - function typeCardinalityCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType = Variability.PARAMETER - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local fn::M_Function - local node::InstNode - - #= cardinality may only be used in a condition of an assert or - =# - #= if-statement/equation (the specification says only if-statement, - =# - #= but e.g. the MSL only uses them in if-equations and asserts). - =# - if ! (ExpOrigin.flagSet(origin, ExpOrigin.CONDITION) && (ExpOrigin.flagSet(origin, ExpOrigin.IF) || ExpOrigin.flagSet(origin, ExpOrigin.ASSERT))) - Error.addSourceMessageAndFail(Error.INVALID_CARDINALITY_CONTEXT, nil, info) - end - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("cardinality", named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector) => Integer"), info) - end - if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) - Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) - end - @assign (arg, ty) = Typing.typeExp(listHead(args), origin, info) - if ! isCref(arg) - Error.addSourceMessageAndFail(Error.ARGUMENT_MUST_BE_VARIABLE, list("First", toString(fn_ref), ""), info) - end - @assign node = node(toCref(arg)) - if ! (Type.isScalar(ty) && isComponent(node) && P_Component.isConnector(component(node))) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("1", toString(fn_ref), "", toString(arg), Type.toString(ty), "connector"), info) - end - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign ty = TYPE_INTEGER() - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), var, ty)) - #= TODO: Check cardinality restrictions, 3.7.2.3. - =# - System.setUsesCardinality(true) - (callExp, ty, var) - end - - function typeBranchCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType = Variability.PARAMETER - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg1::Expression - local arg2::Expression - local fn::M_Function - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("Connections.branch", named_args, info) - if listLength(args) != 2 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector, Connector)"), info) - end - if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) - Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) - end - @match list(arg1, arg2) = args - @assign (arg1, ty) = Typing.typeExp(arg1, origin, info) - checkConnectionsArgument(arg1, ty, fn_ref, 1, info) - @assign (arg2, ty) = Typing.typeExp(arg2, origin, info) - checkConnectionsArgument(arg2, ty, fn_ref, 2, info) - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign ty = TYPE_NORETCALL() - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg1, arg2), var, ty)) - (callExp, ty, var) - end - - function typeIsRootCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType = Variability.PARAMETER - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local fn::M_Function - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("Connections.isRoot", named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector)"), info) - end - if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) - Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) - end - @assign (arg, ty) = Typing.typeExp(listHead(args), origin, info) - checkConnectionsArgument(arg, ty, fn_ref, 1, info) - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign ty = TYPE_BOOLEAN() - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), var, ty)) - (callExp, ty, var) - end - - function typePotentialRootCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType = Variability.PARAMETER - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg1::Expression - local arg2::Expression - local fn::M_Function - local args_len::Integer - local name::String - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - for narg in named_args - @assign (name, arg2) = narg - if name == "priority" - @assign args = ListUtil.appendElt(arg2, args) - else - Error.addSourceMessageAndFail(Error.NO_SUCH_PARAMETER, list(toString(fn_ref), name), info) - end - end - @assign args_len = listLength(args) - if args_len < 1 || args_len > 2 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector, Integer = 0)"), info) - end - if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) - Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) - end - @match _cons(arg1, args) = args - @assign (arg1, ty) = Typing.typeExp(arg1, origin, info) - checkConnectionsArgument(arg1, ty, fn_ref, 1, info) - if args_len == 2 - @assign arg2 = listHead(args) - @assign (arg2, ty) = Typing.typeExp(arg2, origin, info) - if ! Type.isInteger(ty) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("2", toString(fn_ref), "", toString(arg2), Type.toString(ty), "Integer"), info) - end - else - @assign arg2 = INTEGER_EXPRESSION(0) - end - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign ty = TYPE_NORETCALL() - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg1, arg2), var, ty)) - (callExp, ty, var) - end - - function typeRootCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType = Variability.PARAMETER - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local fn::M_Function - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("Connections.root", named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector)"), info) - end - if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) - Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) - end - @assign (arg, ty) = Typing.typeExp(listHead(args), origin, info) - checkConnectionsArgument(arg, ty, fn_ref, 1, info) - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign ty = TYPE_NORETCALL() - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), var, ty)) - (callExp, ty, var) - end - - function typeRootedCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType = Variability.PARAMETER - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local fn::M_Function - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("Connections.rooted", named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector)"), info) - end - if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) - Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) - end - @assign (arg, ty) = Typing.typeExp(listHead(args), origin, info) - checkConnectionsArgument(arg, ty, fn_ref, 1, info) - if isSimple(fn_ref) - Error.addSourceMessage(Error.DEPRECATED_API_CALL, list("rooted", "Connections.rooted"), info) - end - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign ty = TYPE_BOOLEAN() - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), var, ty)) - (callExp, ty, var) - end - - """ #= see also typeUniqueRootIndicesCall =#""" - function typeUniqueRootCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType = Variability.PARAMETER - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg1::Expression - local arg2::Expression - local fn::M_Function - local args_len::Integer - local name::String - - Error.addSourceMessage(Error.NON_STANDARD_OPERATOR, list("Connections.uniqueRoot"), info) - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - for narg in named_args - @assign (name, arg2) = narg - if name == "message" - @assign args = ListUtil.appendElt(arg2, args) - else - Error.addSourceMessageAndFail(Error.NO_SUCH_PARAMETER, list(toString(fn_ref), name), info) - end - end - @assign args_len = listLength(args) - if args_len < 1 || args_len > 2 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector, String = \\\\)"), info) - end - if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) - Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) - end - @match _cons(arg1, args) = args - @assign (arg1, ty) = Typing.typeExp(arg1, origin, info) - checkConnectionsArgument(arg1, ty, fn_ref, 1, info) - if args_len == 2 - @assign arg2 = listHead(args) - @assign (arg2, ty) = Typing.typeExp(arg2, origin, info) - if ! Type.isString(ty) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("2", toString(fn_ref), "", toString(arg2), Type.toString(ty), "String"), info) - end - else - @assign arg2 = STRING_EXPRESSION("") - end - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign ty = TYPE_NORETCALL() - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg1, arg2), var, ty)) - (callExp, ty, var) - end - - """ #= See Modelica_StateGraph2: - https:github.com/modelica/Modelica_StateGraph2 - and - https:trac.modelica.org/Modelica/ticket/984 - and - http:www.ep.liu.se/ecp/043/041/ecp09430108.pdf - for a specification of this operator =#""" - function typeUniqueRootIndicesCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType = Variability.PARAMETER - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg1::Expression - local arg2::Expression - local arg3::Expression - local fn::M_Function - local args_len::Integer - local name::String - local ty1::M_Type - local ty2::M_Type - local ty3::M_Type - - Error.addSourceMessage(Error.NON_STANDARD_OPERATOR, list("Connections.uniqueRootIndices"), info) - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - for narg in named_args - @assign (name, arg3) = narg - if name == "message" - @assign args = ListUtil.appendElt(arg3, args) - else - Error.addSourceMessageAndFail(Error.NO_SUCH_PARAMETER, list(toString(fn_ref), name), info) - end - end - @assign args_len = listLength(args) - if args_len < 2 || args_len > 3 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(Connector, Connector, String = \\\\)"), info) - end - if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) - Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION, list(toString(fn_ref)), info) - end - @match _cons(arg1, _cons(arg2, args)) = args - @assign (arg1, ty1) = Typing.typeExp(arg1, origin, info) - checkConnectionsArgument(arg1, ty1, fn_ref, 1, info) - @assign (arg2, ty2) = Typing.typeExp(arg2, origin, info) - checkConnectionsArgument(arg2, ty2, fn_ref, 1, info) - if args_len == 3 - @assign arg3 = listHead(args) - @assign (arg3, ty3) = Typing.typeExp(arg3, origin, info) - if ! Type.isString(ty3) - Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH, list("3", toString(fn_ref), "", toString(arg2), Type.toString(ty3), "String"), info) - end - else - @assign arg2 = STRING_EXPRESSION("") - end - @match list(fn) = P_Function.typeRefCache(fn_ref) - assert(listLength(arrayDims(ty1)) == listLength(arrayDims(ty2)), "the first two parameters need to have the same size") - @assign ty = ARRAY_TYPE(Type.TYPE_INTEGER(), arrayDims(ty1)) - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg1, arg2), var, ty)) - (callExp, ty, var) - end - - function checkConnectionsArgument(arg::Expression, ty::M_Type, fnRef::ComponentRef, argIndex::Integer, info::SourceInfo) - @assign () = begin - local ty2::M_Type - local node::InstNode - local valid_cref::Bool - local isConnector::Bool - @match arg begin - CREF_EXPRESSION(__) => begin - @assign (valid_cref, isConnector) = begin - @match arg.cref begin - CREF(node = node, origin = P_NFComponentRef.Origin.CREF, restCref = CREF(ty = ty2, origin = P_NFComponentRef.Origin.CREF)) => begin - #= check form A.R - =# - @assign ty2 = begin - @match ty2 begin - ARRAY_TYPE(__) where (listLength(subscriptsAllFlat(arg.cref)) == listLength(ty2.dimensions)) => begin - ty2.elementType - end - - _ => begin - ty2 - end - end - end - (isOverdetermined(getClass(node)), Type.isConnector(ty2)) - end - - CREF(node = node, ty = ty2) => begin - #= adrpo #5821, allow for R only instead of A.R and issue a warning - =# - @assign ty2 = begin - @match ty2 begin - ARRAY_TYPE(__) where (listLength(subscriptsAllFlat(arg.cref)) == listLength(ty2.dimensions)) => begin - ty2.elementType - end - - _ => begin - ty2 - end - end - end - (isOverdetermined(getClass(node)), Type.isConnector(ty2)) - end - - _ => begin - (false, false) - end - end - end - if ! (valid_cref && isConnector) - if valid_cref - Error.addSourceMessage(if argIndex == 1 - Error.W_INVALID_ARGUMENT_TYPE_BRANCH_FIRST - else - Error.W_INVALID_ARGUMENT_TYPE_BRANCH_SECOND - end, list(toString(arg.cref), toString(fnRef)), info) - else - Error.addSourceMessageAndFail(if argIndex == 1 - Error.INVALID_ARGUMENT_TYPE_BRANCH_FIRST - else - Error.INVALID_ARGUMENT_TYPE_BRANCH_SECOND - end, list(toString(arg.cref), toString(fnRef)), info) - end - end - () + CREF(node = node, ty = ty2) => begin + #= adrpo #5821, allow for R only instead of A.R and issue a warning + =# + @assign ty2 = begin + @match ty2 begin + ARRAY_TYPE(__) where (listLength(subscriptsAllFlat(arg.cref)) == listLength(ty2.dimensions)) => begin + ty2.elementType end _ => begin - Error.addSourceMessage(Error.ARG_TYPE_MISMATCH, list(String(argIndex), toString(fnRef), "", toString(arg), Type.toString(ty), "overconstrained type/record"), info) - fail() + ty2 end end end - end + (isOverdetermined(getClass(node)), Type.isConnector(ty2)) + end - function typeNoEventCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local fn::M_Function - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams("noEvent", named_args, info) - #= noEvent takes exactly one argument. - =# - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "noEvent(Any) => Any"), info) - end - @match list(arg) = args - @assign (arg, ty, variability) = Typing.typeExp(arg, ExpOrigin.setFlag(origin, ExpOrigin.NOEVENT), info) - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) - (callExp, ty, variability) + _ => begin + (false, false) + end + end end - - function typeGetInstanceName(call::Call) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType = Variability.CONSTANT - local ty::M_Type = TYPE_STRING() - local result::Expression - - local scope::InstNode - - @match P_Call.UNTYPED_CALL(call_scope = scope) = call - @assign result = STRING_EXPRESSION(AbsynUtil.pathString(scopePath(scope, includeRoot = true))) - (result, ty, var) + if ! (valid_cref && isConnector) + if valid_cref + Error.addSourceMessage(if argIndex == 1 + Error.W_INVALID_ARGUMENT_TYPE_BRANCH_FIRST + else + Error.W_INVALID_ARGUMENT_TYPE_BRANCH_SECOND + end, list(toString(arg.cref), toString(fnRef)), info) + else + Error.addSourceMessageAndFail(if argIndex == 1 + Error.INVALID_ARGUMENT_TYPE_BRANCH_FIRST + else + Error.INVALID_ARGUMENT_TYPE_BRANCH_SECOND + end, list(toString(arg.cref), toString(fnRef)), info) + end end - - function typeClockCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType = Variability.PARAMETER - local outType::M_Type = TYPE_CLOCK() - local callExp::Expression - - local ty_call::Call - local args::List{Expression} - local args_count::Integer - local e1::Expression - local e2::Expression - - @match P_Call.TYPED_CALL(arguments = args) = P_Call.typeMatchNormalCall(call, origin, info) - @assign args_count = listLength(args) - @assign callExp = begin - @match args begin - nil() => begin - P_Expression.Expression.CLKCONST(P_Expression.P_ClockKind.Expression.INFERRED_CLOCK()) - end - - e1 <| nil() => begin - P_Expression.Expression.CLKCONST(P_Expression.P_ClockKind.REAL_EXPRESSION_CLOCK(e1)) - end - - e1 <| e2 <| nil() => begin - #= Clock() - inferred clock. - =# - #= Clock(interval) - real clock. - =# - @assign e2 = Ceval.evalExp(e2) - @assign callExp = begin - @match typeOf(e2) begin - TYPE_INTEGER(__) => begin - #= Clock(intervalCounter, resolution) - integer clock. - =# - Error.assertionOrAddSourceMessage(integerValue(e2) >= 1, Error.WRONG_VALUE_OF_ARG, list("Clock", "resolution", toString(e2), "=> 1"), info) - P_Expression.Expression.CLKCONST(INTEGER_EXPRESSION_CLOCK(e1, e2)) - end - - TYPE_REAL(__) => begin - P_Expression.Expression.CLKCONST(P_Expression.Expression.BOOLEAN_CLOCK(e1, e2)) - end - - TYPE_STRING(__) => begin - P_Expression.Expression.CLKCONST(P_Expression.Expression.SOLVER_CLOCK(e1, e2)) - end - end - end - #= Clock(condition, startInterval) - boolean clock. - =# - #= Clock(c, solverMethod) - solver clock. - =# - callExp - end - end - end - (callExp, outType, var) + () + end + + _ => begin + Error.addSourceMessage(Error.ARG_TYPE_MISMATCH, list(String(argIndex), toString(fnRef), "", toString(arg), Type.toString(ty), "overconstrained type/record"), info) + fail() + end + end + end +end + +function typeNoEventCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local fn::M_Function + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams("noEvent", named_args, info) + #= noEvent takes exactly one argument. + =# + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), "noEvent(Any) => Any"), info) + end + @match list(arg) = args + @assign (arg, ty, variability) = typeExp(arg, setFlag(origin, ORIGIN_NOEVENT), info) + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), variability, ty)) + (callExp, ty, variability) +end + +function typeGetInstanceName(call::Call) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType = Variability.CONSTANT + local ty::M_Type = TYPE_STRING() + local result::Expression + + local scope::InstNode + + @match UNTYPED_CALL(call_scope = scope) = call + @assign result = STRING_EXPRESSION(AbsynUtil.pathString(scopePath(scope, includeRoot = true))) + (result, ty, var) +end + +function typeClockCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType = Variability.PARAMETER + local outType::M_Type = TYPE_CLOCK() + local callExp::Expression + + local ty_call::Call + local args::List{Expression} + local args_count::Integer + local e1::Expression + local e2::Expression + + @match P_Call.TYPED_CALL(arguments = args) = P_Call.typeMatchNormalCall(call, origin, info) + @assign args_count = listLength(args) + @assign callExp = begin + @match args begin + nil() => begin + P_Expression.Expression.CLKCONST(P_Expression.P_ClockKind.Expression.INFERRED_CLOCK()) + end + + e1 <| nil() => begin + P_Expression.Expression.CLKCONST(P_Expression.P_ClockKind.REAL_EXPRESSION_CLOCK(e1)) + end + + e1 <| e2 <| nil() => begin + #= Clock() - inferred clock. + =# + #= Clock(interval) - real clock. + =# + @assign e2 = Ceval.evalExp(e2) + @assign callExp = begin + @match typeOf(e2) begin + TYPE_INTEGER(__) => begin + #= Clock(intervalCounter, resolution) - integer clock. + =# + Error.assertionOrAddSourceMessage(integerValue(e2) >= 1, Error.WRONG_VALUE_OF_ARG, list("Clock", "resolution", toString(e2), "=> 1"), info) + P_Expression.Expression.CLKCONST(INTEGER_EXPRESSION_CLOCK(e1, e2)) + end + + TYPE_REAL(__) => begin + P_Expression.Expression.CLKCONST(P_Expression.BOOLEAN_EXPRESSION_CLOCK(e1, e2)) + end + + TYPE_STRING(__) => begin + P_Expression.Expression.CLKCONST(P_Expression.Expression.SOLVER_CLOCK(e1, e2)) + end + end end - - function typeSampleCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local var::VariabilityType - local outType::M_Type - local callExp::Expression - - local ty_call::Call - local arg_ty::M_Type - local args::List{TypedArg} - local namedArgs::List{TypedNamedArg} - local e::Expression - local e1::Expression - local e2::Expression - local t::M_Type - local t1::M_Type - local t2::M_Type - local v::VariabilityType - local v1::VariabilityType - local v2::VariabilityType - local fn_ref::ComponentRef - local normalSample::M_Function - local clockedSample::M_Function - local recopnode::InstNode - - @match P_Call.ARG_TYPED_CALL(fn_ref, args, namedArgs) = P_Call.typeNormalCall(call, origin, info) - @assign recopnode = node(fn_ref) - @assign fn_ref = P_Function.instFunctionRef(fn_ref, info(recopnode)) - @match list(normalSample, clockedSample) = P_Function.typeRefCache(fn_ref) - @assign (callExp, outType, var) = begin - @match (args, namedArgs) begin - ((e, t, v) <| (e1, TYPE_INTEGER(__), v1) <| nil(), nil()) => begin - #= sample(start, Real interval) - the usual stuff - =# - if valueEq(t, TYPE_INTEGER()) - @assign e = CAST_EXPRESSION(TYPE_REAL(), e) - end - @assign ty_call = P_Call.makeTypedCall(normalSample, list(e, CAST_EXPRESSION(TYPE_REAL(), e1)), Variability.PARAMETER, TYPE_BOOLEAN()) - (CALL_EXPRESSION(ty_call), TYPE_BOOLEAN(), Variability.PARAMETER) - end - - ((e, t, v) <| (e1, TYPE_REAL(__), v1) <| nil(), nil()) => begin - #= sample(start, Real interval) - the usual stuff - =# - if valueEq(t, TYPE_INTEGER()) - @assign e = CAST_EXPRESSION(TYPE_REAL(), e) - end - @assign ty_call = P_Call.makeTypedCall(normalSample, list(e, e1), Variability.PARAMETER, TYPE_BOOLEAN()) - (CALL_EXPRESSION(ty_call), TYPE_BOOLEAN(), Variability.PARAMETER) - end - - ((e, t, v) <| nil(), ("interval", e1, TYPE_REAL(__), v1) <| nil()) => begin - #= sample(start, Real interval = value) - the usual stuff - =# - if valueEq(t, TYPE_INTEGER()) - @assign e = CAST_EXPRESSION(TYPE_REAL(), e) - end - @assign ty_call = P_Call.makeTypedCall(normalSample, list(e, e1), Variability.PARAMETER, TYPE_BOOLEAN()) - (CALL_EXPRESSION(ty_call), TYPE_BOOLEAN(), Variability.PARAMETER) - end - - ((e, t, v) <| nil(), nil()) where (Config.synchronousFeaturesAllowed()) => begin - #= sample(u) - inferred clock - =# - @assign ty_call = P_Call.makeTypedCall(clockedSample, list(e, P_Expression.Expression.CLKCONST(P_Expression.P_ClockKind.Expression.INFERRED_CLOCK())), v, t) - (CALL_EXPRESSION(ty_call), t, v) - end - - ((e, t, v) <| (e1, TYPE_CLOCK(__), v1) <| nil(), nil()) where (Config.synchronousFeaturesAllowed()) => begin - #= sample(u, c) - specified clock - =# - @assign ty_call = P_Call.makeTypedCall(clockedSample, list(e, e1), v, t) - (CALL_EXPRESSION(ty_call), t, v) - end - - ((e, t, v) <| nil(), ("c", e1, TYPE_CLOCK(__), v1) <| nil()) where (Config.synchronousFeaturesAllowed()) => begin - #= sample(u, Clock c = c) - specified clock - =# - @assign ty_call = P_Call.makeTypedCall(clockedSample, list(e, e1), v, t) - (CALL_EXPRESSION(ty_call), t, v) - end - - _ => begin - Error.addSourceMessage(Error.WRONG_TYPE_OR_NO_OF_ARGS, list(P_Call.toString(call), ""), info) - fail() - end - end - end - (callExp, outType, var) + #= Clock(condition, startInterval) - boolean clock. + =# + #= Clock(c, solverMethod) - solver clock. + =# + callExp + end + end + end + (callExp, outType, var) +end + +function typeSampleCall(call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local var::VariabilityType + local outType::M_Type + local callExp::Expression + + local ty_call::Call + local arg_ty::M_Type + local args::List{TypedArg} + local namedArgs::List{TypedNamedArg} + local e::Expression + local e1::Expression + local e2::Expression + local t::M_Type + local t1::M_Type + local t2::M_Type + local v::VariabilityType + local v1::VariabilityType + local v2::VariabilityType + local fn_ref::ComponentRef + local normalSample::M_Function + local clockedSample::M_Function + local recopnode::InstNode + + @match P_Call.ARG_TYPED_CALL(fn_ref, args, namedArgs) = P_Call.typeNormalCall(call, origin, info) + @assign recopnode = node(fn_ref) + @assign fn_ref = P_Function.instFunctionRef(fn_ref, info(recopnode)) + @match list(normalSample, clockedSample) = P_Function.typeRefCache(fn_ref) + @assign (callExp, outType, var) = begin + @match (args, namedArgs) begin + ((e, t, v) <| (e1, TYPE_INTEGER(__), v1) <| nil(), nil()) => begin + #= sample(start, Real interval) - the usual stuff + =# + if valueEq(t, TYPE_INTEGER()) + @assign e = CAST_EXPRESSION(TYPE_REAL(), e) end - - function typeActualInStreamCall(name::String, call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType = Variability.DISCRETE - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local arg_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg::Expression - local var::VariabilityType - local fn::M_Function - local arg_node::InstNode - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams(name, named_args, info) - if listLength(args) != 1 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(stream variable) => Real"), info) - end - @assign (arg, ty, var) = Typing.typeExp(listHead(args), origin, info) - @assign arg = P_ExpandExp.ExpandExp.expand(arg) - @match list(fn) = P_Function.typeRefCache(fn_ref) - @assign callExp = typeActualInStreamCall2(name, fn, arg, var, info) - (callExp, ty, variability) + @assign ty_call = P_Call.makeTypedCall(normalSample, list(e, CAST_EXPRESSION(TYPE_REAL(), e1)), Variability.PARAMETER, TYPE_BOOLEAN()) + (CALL_EXPRESSION(ty_call), TYPE_BOOLEAN(), Variability.PARAMETER) + end + + ((e, t, v) <| (e1, TYPE_REAL(__), v1) <| nil(), nil()) => begin + #= sample(start, Real interval) - the usual stuff + =# + if valueEq(t, TYPE_INTEGER()) + @assign e = CAST_EXPRESSION(TYPE_REAL(), e) end - - function typeActualInStreamCall2(name::String, fn::M_Function, arg::Expression, var::VariabilityType, info::SourceInfo) ::Expression - local callExp::Expression - - @assign callExp = begin - local arg_node::InstNode - @match arg begin - CREF_EXPRESSION(__) => begin - @assign arg_node = node(arg.cref) - #= The argument of actualStream/inStream must be a stream variable. - =# - if ! isComponent(arg_node) || ! ConnectorType.isStream(P_Component.connectorType(component(arg_node))) - Error.addSourceMessageAndFail(Error.NON_STREAM_OPERAND_IN_STREAM_OPERATOR, list(toString(arg.cref), name), info) - end - #= The argument of actualStream/inStream must have subscripts that can be evaluated. - =# - for sub in subscriptsAllFlat(arg.cref) - if variability(sub) > Variability.PARAMETER - Error.addSourceMessageAndFail(Error.CONNECTOR_NON_PARAMETER_SUBSCRIPT, list(toString(arg.cref), toString(sub)), info) - end - end - CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), var, arg.ty)) - end - - ARRAY_EXPRESSION(__) => begin - @assign arg.elements = List(typeActualInStreamCall2(name, fn, e, var, info) for e in arg.elements) - arg - end - - _ => begin - Error.addSourceMessage(Error.NON_STREAM_OPERAND_IN_STREAM_OPERATOR, list(toString(arg), name), info) - fail() - end - end - end - callExp + @assign ty_call = P_Call.makeTypedCall(normalSample, list(e, e1), Variability.PARAMETER, TYPE_BOOLEAN()) + (CALL_EXPRESSION(ty_call), TYPE_BOOLEAN(), Variability.PARAMETER) + end + + ((e, t, v) <| nil(), ("interval", e1, TYPE_REAL(__), v1) <| nil()) => begin + #= sample(start, Real interval = value) - the usual stuff + =# + if valueEq(t, TYPE_INTEGER()) + @assign e = CAST_EXPRESSION(TYPE_REAL(), e) end - - function typeDynamicSelectCall(name::String, call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} - local variability::VariabilityType = Variability.CONTINUOUS - local ty::M_Type - local callExp::Expression - - local fn_ref::ComponentRef - local arg_ref::ComponentRef - local args::List{Expression} - local named_args::List{NamedArg} - local arg1::Expression - local arg2::Expression - local var1::VariabilityType - local var2::VariabilityType - local fn::M_Function - local arg_node::InstNode - local ty1::M_Type - local ty2::M_Type - local expStatic::Expression - local expDynamic::Expression - - @match P_Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call - assertNoNamedParams(name, named_args, info) - if listLength(args) != 2 - Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(static expression, dynamic expression)"), info) - end - @match list(expStatic, expDynamic) = List(unbox(arg) for arg in args) - @assign (arg1, ty1, var1) = Typing.typeExp(expStatic, origin, info) - @assign arg1 = P_ExpandExp.ExpandExp.expand(arg1) - #= if we cannot typecheck the dynamic part, ignore it! - =# - #= https:trac.openmodelica.org/OpenModelica/ticket/5631 - =# - try - @assign (arg2, ty2, var2) = Typing.typeExp(expDynamic, origin, info) - catch - @assign variability = var1 - @assign callExp = arg1 - return (callExp, ty, variability) - end - @assign arg2 = P_ExpandExp.ExpandExp.expand(arg2) - @assign ty = ty1 - @assign variability = var2 - @match list(fn) = P_Function.typeRefCache(fn_ref) - if Flags.isSet(Flags.NF_API_DYNAMIC_SELECT) - @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg1, arg2), variability, ty1)) - else - @assign variability = var1 - @assign callExp = arg1 - end - (callExp, ty, variability) + @assign ty_call = P_Call.makeTypedCall(normalSample, list(e, e1), Variability.PARAMETER, TYPE_BOOLEAN()) + (CALL_EXPRESSION(ty_call), TYPE_BOOLEAN(), Variability.PARAMETER) + end + + ((e, t, v) <| nil(), nil()) where (Config.synchronousFeaturesAllowed()) => begin + #= sample(u) - inferred clock + =# + @assign ty_call = P_Call.makeTypedCall(clockedSample, list(e, P_Expression.Expression.CLKCONST(P_Expression.P_ClockKind.Expression.INFERRED_CLOCK())), v, t) + (CALL_EXPRESSION(ty_call), t, v) + end + + ((e, t, v) <| (e1, TYPE_CLOCK(__), v1) <| nil(), nil()) where (Config.synchronousFeaturesAllowed()) => begin + #= sample(u, c) - specified clock + =# + @assign ty_call = P_Call.makeTypedCall(clockedSample, list(e, e1), v, t) + (CALL_EXPRESSION(ty_call), t, v) + end + + ((e, t, v) <| nil(), ("c", e1, TYPE_CLOCK(__), v1) <| nil()) where (Config.synchronousFeaturesAllowed()) => begin + #= sample(u, Clock c = c) - specified clock + =# + @assign ty_call = P_Call.makeTypedCall(clockedSample, list(e, e1), v, t) + (CALL_EXPRESSION(ty_call), t, v) + end + + _ => begin + Error.addSourceMessage(Error.WRONG_TYPE_OR_NO_OF_ARGS, list(P_Call.toString(call), ""), info) + fail() + end + end + end + (callExp, outType, var) +end + +function typeActualInStreamCall(name::String, call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType = Variability.DISCRETE + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local arg_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg::Expression + local var::VariabilityType + local fn::M_Function + local arg_node::InstNode + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams(name, named_args, info) + if listLength(args) != 1 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(stream variable) => Real"), info) + end + @assign (arg, ty, var) = typeExp(listHead(args), origin, info) + @assign arg = P_ExpandExp.ExpandExp.expand(arg) + @match list(fn) = P_Function.typeRefCache(fn_ref) + @assign callExp = typeActualInStreamCall2(name, fn, arg, var, info) + (callExp, ty, variability) +end + +function typeActualInStreamCall2(name::String, fn::M_Function, arg::Expression, var::VariabilityType, info::SourceInfo) ::Expression + local callExp::Expression + + @assign callExp = begin + local arg_node::InstNode + @match arg begin + CREF_EXPRESSION(__) => begin + @assign arg_node = node(arg.cref) + #= The argument of actualStream/inStream must be a stream variable. + =# + if ! isComponent(arg_node) || ! ConnectorType.isStream(P_Component.connectorType(component(arg_node))) + Error.addSourceMessageAndFail(Error.NON_STREAM_OPERAND_IN_STREAM_OPERATOR, list(toString(arg.cref), name), info) end - - @exportAll() + #= The argument of actualStream/inStream must have subscripts that can be evaluated. + =# + for sub in subscriptsAllFlat(arg.cref) + if variability(sub) > Variability.PARAMETER + Error.addSourceMessageAndFail(Error.CONNECTOR_NON_PARAMETER_SUBSCRIPT, list(toString(arg.cref), toString(sub)), info) + end + end + CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg), var, arg.ty)) + end + + ARRAY_EXPRESSION(__) => begin + @assign arg.elements = List(typeActualInStreamCall2(name, fn, e, var, info) for e in arg.elements) + arg + end + + _ => begin + Error.addSourceMessage(Error.NON_STREAM_OPERAND_IN_STREAM_OPERATOR, list(toString(arg), name), info) + fail() + end + end + end + callExp +end + +function typeDynamicSelectCall(name::String, call::Call, origin::ORIGIN_Type, info::SourceInfo) ::Tuple{Expression, M_Type, Variability} + local variability::VariabilityType = Variability.CONTINUOUS + local ty::M_Type + local callExp::Expression + + local fn_ref::ComponentRef + local arg_ref::ComponentRef + local args::List{Expression} + local named_args::List{NamedArg} + local arg1::Expression + local arg2::Expression + local var1::VariabilityType + local var2::VariabilityType + local fn::M_Function + local arg_node::InstNode + local ty1::M_Type + local ty2::M_Type + local expStatic::Expression + local expDynamic::Expression + + @match UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) = call + assertNoNamedParams(name, named_args, info) + if listLength(args) != 2 + Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST, list(P_Call.toString(call), toString(fn_ref) + "(static expression, dynamic expression)"), info) + end + @match list(expStatic, expDynamic) = List(unbox(arg) for arg in args) + @assign (arg1, ty1, var1) = typeExp(expStatic, origin, info) + @assign arg1 = P_ExpandExp.ExpandExp.expand(arg1) + #= if we cannot typecheck the dynamic part, ignore it! + =# + #= https:trac.openmodelica.org/OpenModelica/ticket/5631 + =# + try + @assign (arg2, ty2, var2) = typeExp(expDynamic, origin, info) + catch + @assign variability = var1 + @assign callExp = arg1 + return (callExp, ty, variability) + end + @assign arg2 = P_ExpandExp.ExpandExp.expand(arg2) + @assign ty = ty1 + @assign variability = var2 + @match list(fn) = P_Function.typeRefCache(fn_ref) + if Flags.isSet(Flags.NF_API_DYNAMIC_SELECT) + @assign callExp = CALL_EXPRESSION(P_Call.makeTypedCall(fn, list(arg1, arg2), variability, ty1)) + else + @assign variability = var1 + @assign callExp = arg1 end + (callExp, ty, variability) +end diff --git a/src/NewFrontend/NFBuiltinFuncs.jl b/src/NewFrontend/NFBuiltinFuncs.jl index da1765f..da9a78f 100644 --- a/src/NewFrontend/NFBuiltinFuncs.jl +++ b/src/NewFrontend/NFBuiltinFuncs.jl @@ -83,8 +83,8 @@ const DUMMY_ELEMENT = SCode.Encapsulated.ENCAPSULATED(), SCode.Partial.NOT_PARTIAL(), SCode.RESTRICTION_R_FUNCTION(SCode.FunctionRestriction.FR_NORMAL_FUNCTION(false)), - SCode.ClassDef.PARTS(nil, nil, nil, nil, nil, nil, nil, NONE()), - SCode.Comment.COMMENT(NONE(), NONE()), + SCode.PARTS(nil, nil, nil, nil, nil, nil, nil, NONE()), + SCode.COMMENT(NONE(), NONE()), AbsynUtil.dummyInfo, )::SCode.Element #= Default Integer parameter. @@ -93,8 +93,8 @@ const INT_COMPONENT = TYPED_COMPONENT( NFInstNode.EMPTY_NODE(), TYPE_INTEGER(), - NFBinding.EMPTY_BINDING, - NFBinding.EMPTY_BINDING, + EMPTY_BINDING, + EMPTY_BINDING, NFComponent.DEFAULT_ATTR, NONE(), NONE(), @@ -114,8 +114,8 @@ const REAL_COMPONENT = TYPED_COMPONENT( NFInstNode.EMPTY_NODE(), TYPE_REAL(), - NFBinding.EMPTY_BINDING, - NFBinding.EMPTY_BINDING, + EMPTY_BINDING, + EMPTY_BINDING, NFComponent.DEFAULT_ATTR, NONE(), NONE(), @@ -135,8 +135,8 @@ const BOOL_COMPONENT = TYPED_COMPONENT( NFInstNode.EMPTY_NODE(), TYPE_BOOLEAN(), - NFBinding.EMPTY_BINDING, - NFBinding.EMPTY_BINDING, + EMPTY_BINDING, + EMPTY_BINDING, NFComponent.DEFAULT_ATTR, NONE(), NONE(), @@ -156,8 +156,8 @@ const STRING_COMPONENT = TYPED_COMPONENT( NFInstNode.EMPTY_NODE(), TYPE_STRING(), - NFBinding.EMPTY_BINDING, - NFBinding.EMPTY_BINDING, + EMPTY_BINDING, + EMPTY_BINDING, NFComponent.DEFAULT_ATTR, NONE(), NONE(), @@ -177,8 +177,8 @@ const ENUM_COMPONENT = TYPED_COMPONENT( NFInstNode.EMPTY_NODE(), TYPE_ENUMERATION_ANY(), - NFBinding.EMPTY_BINDING, - NFBinding.EMPTY_BINDING, + EMPTY_BINDING, + EMPTY_BINDING, NFComponent.DEFAULT_ATTR, NONE(), NONE(), @@ -305,7 +305,7 @@ const STRING_REAL = P_Slot.SLOT( "leftJustified", SlotType.NAMED, - SOME(P_Expression.Expression.BOOLEAN(true)), + SOME(P_Expression.BOOLEAN_EXPRESSION(true)), NONE(), 4, SlotEvalStatus.NOT_EVALUATED, @@ -379,7 +379,7 @@ const STRING_INT = P_Slot.SLOT( "leftJustified", SlotType.NAMED, - SOME(P_Expression.Expression.BOOLEAN(true)), + SOME(P_Expression.BOOLEAN_EXPRESSION(true)), NONE(), 3, SlotEvalStatus.NOT_EVALUATED, @@ -420,7 +420,7 @@ const STRING_BOOL = P_Slot.SLOT( "leftJustified", SlotType.NAMED, - SOME(P_Expression.Expression.BOOLEAN(true)), + SOME(P_Expression.BOOLEAN_EXPRESSION(true)), NONE(), 3, SlotEvalStatus.NOT_EVALUATED, @@ -461,7 +461,7 @@ const STRING_ENUM = P_Slot.SLOT( "leftJustified", SlotType.NAMED, - SOME(P_Expression.Expression.BOOLEAN(true)), + SOME(P_Expression.BOOLEAN_EXPRESSION(true)), NONE(), 3, SlotEvalStatus.NOT_EVALUATED, @@ -705,8 +705,8 @@ const CLOCK_COMPONENT = TYPED_COMPONENT( NFInstNode.EMPTY_NODE(), TYPE_CLOCK(), - NFBinding.EMPTY_BINDING, - NFBinding.EMPTY_BINDING, + EMPTY_BINDING, + EMPTY_BINDING, NFComponent.DEFAULT_ATTR, NONE(), NONE(), diff --git a/src/NewFrontend/NFCall.jl b/src/NewFrontend/NFCall.jl index 603c7e6..084642c 100644 --- a/src/NewFrontend/NFCall.jl +++ b/src/NewFrontend/NFCall.jl @@ -72,9 +72,8 @@ end @UniontypeDecl CallAttributes -function toDAE(attr::CallAttributes, returnType::NFType)::DAE.P_CallAttributes - local fattr::DAE.P_CallAttributes - +function toDAE(attr::CallAttributes, returnType::NFType)::DAE.CallAttributes + local fattr::DAE.CallAttributes @assign fattr = DAE.CALL_ATTR( toDAE(returnType), attr.tuple_, @@ -209,9 +208,8 @@ function isVectorizeable(call::Call)::Bool return isVect end -function toDAE(call::Call)::DAE.Exp +function toDAE(@nospecialize(call::Call))::DAE.Exp local daeCall::DAE.Exp - @assign daeCall = begin local fold_id::String local res_id::String @@ -219,12 +217,11 @@ function toDAE(call::Call)::DAE.Exp @match call begin TYPED_CALL(__) => begin DAE.CALL( - P_Function.nameConsiderBuiltin(call.fn), - List(P_Expression.Expression.toDAE(e) for e in call.arguments), - P_CallAttributes.toDAE(call.attributes, call.ty), + nameConsiderBuiltin(call.fn), + list(toDAE(e) for e in call.arguments), + toDAE(call.attributes, call.ty), ) end - TYPED_ARRAY_CONSTRUCTOR(__) => begin @assign fold_id = Util.getTempVariableIndex() @assign res_id = Util.getTempVariableIndex() @@ -690,7 +687,8 @@ function isExternal(call::Call)::Bool end TYPED_CALL(__) => begin - P_Function.isExternal(call.fn) + #isExternal(call.fn) TODO + true end _ => begin @@ -951,21 +949,19 @@ function unboxArgs(call::Call)::Call end function makeTypedCall( - fn::M_Function, - args::List{<:Expression}, - variability::VariabilityType, + @nospecialize(fn::M_Function), + @nospecialize(args::List{<:Expression}), + @nospecialize( variability::VariabilityType), returnType::NFType = fn.returnType, )::Call local call::Call - local ca::CallAttributes - - @assign ca = P_CallAttributes.CALL_ATTR( - Type.isTuple(returnType), - P_Function.isBuiltin(fn), - P_Function.isImpure(fn), - P_Function.isFunctionPointer(fn), - P_Function.inlineBuiltin(fn), + @assign ca = CALL_ATTR( + isTuple(returnType), + isBuiltin(fn), + isImpure(fn), + isFunctionPointer(fn), + inlineBuiltin(fn), DAE.NO_TAIL(), ) @assign call = TYPED_CALL(fn, returnType, variability, args, ca) @@ -997,10 +993,10 @@ function typeNormalCall(call::Call, origin::ORIGIN_Type, info::SourceInfo)::Call end function typeCall( - callExp::Expression, - origin::ORIGIN_Type, - info::SourceInfo, -)::Tuple{Expression, NFType, Variability} + @nospecialize(callExp::Expression), + @nospecialize(origin::ORIGIN_Type), + @nospecialize(info::SourceInfo), +)::Tuple{Expression, NFType, VariabilityType} local var::VariabilityType local ty::NFType local outExp::Expression @@ -1014,8 +1010,8 @@ function typeCall( @assign outExp = begin @match call begin UNTYPED_CALL(ref = cref) => begin - if BuiltinCall.needSpecialHandling(call) - @assign (outExp, ty, var) = BuiltinCall.typeSpecial(call, origin, info) + if needSpecialHandling(call) + @assign (outExp, ty, var) = typeSpecial(call, origin, info) else @assign ty_call = typeMatchNormalCall(call, origin, info) @assign ty = typeOf(ty_call) @@ -1519,7 +1515,7 @@ function checkMatchingFunctions(call::Call, info::SourceInfo)::MatchedFunction =# if P_Function.isBuiltin(matchedFunc.func) @assign func = matchedFunc.func - @assign func.path = P_Function.nameConsiderBuiltin(func) + @assign func.path = nameConsiderBuiltin(func) @assign matchedFunc.func = func end return matchedFunc @@ -1538,16 +1534,16 @@ function typeArgs(call::Call, origin::ORIGIN_Type, info::SourceInfo)::Call @match call begin UNTYPED_CALL(__) => begin @assign typedArgs = nil - @assign next_origin = ExpOrigin.setFlag(origin, ExpOrigin.SUBEXPRESSION) + @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) for arg in call.arguments - @assign (arg, arg_ty, arg_var) = Typing.typeExp(arg, next_origin, info) + @assign (arg, arg_ty, arg_var) = typeExp(arg, next_origin, info) @assign typedArgs = _cons((arg, arg_ty, arg_var), typedArgs) end @assign typedArgs = listReverse(typedArgs) @assign typedNamedArgs = nil for narg in call.named_args @assign (name, arg) = narg - @assign (arg, arg_ty, arg_var) = Typing.typeExp(arg, next_origin, info) + @assign (arg, arg_ty, arg_var) = typeExp(arg, next_origin, info) @assign typedNamedArgs = _cons((name, arg, arg_ty, arg_var), typedNamedArgs) end @assign typedNamedArgs = listReverse(typedNamedArgs) @@ -1723,11 +1719,11 @@ function typeReduction( @match call begin UNTYPED_REDUCTION(__) => begin @assign variability = Variability.CONSTANT - @assign next_origin = ExpOrigin.setFlag(origin, ExpOrigin.SUBEXPRESSION) + @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) for i in call.iters @assign (iter, range) = i @assign (range, _, iter_var) = - Typing.typeIterator(iter, range, origin, structural = false) + typeIterator(iter, range, origin, structural = false) @assign variability = Variability.variabilityMax(variability, iter_var) @assign iters = _cons((iter, range), iters) end @@ -1735,7 +1731,7 @@ function typeReduction( #= ExpOrigin.FOR is used here as a marker that this expression may contain iterators. =# @assign next_origin = intBitOr(next_origin, ExpOrigin.FOR) - @assign (arg, ty, exp_var) = Typing.typeExp(call.exp, next_origin, info) + @assign (arg, ty, exp_var) = typeExp(call.exp, next_origin, info) @assign variability = Variability.variabilityMax(variability, exp_var) @match list(fn) = P_Function.typeRefCache(call.ref) TypeCheck.checkReductionType(ty, P_Function.name(fn), call.exp, info) @@ -1789,12 +1785,12 @@ function typeArrayConstructor( @assign variability = Variability.CONSTANT #= The size of the expression must be known unless we're in a function. =# - @assign is_structural = ExpOrigin.flagNotSet(origin, ExpOrigin.FUNCTION) - @assign next_origin = ExpOrigin.setFlag(origin, ExpOrigin.SUBEXPRESSION) + @assign is_structural = ExpOrigin.flagNotSet(origin, ORIGIN_FUNCTION) + @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) for i in call.iters @assign (iter, range) = i @assign (range, iter_ty, iter_var) = - Typing.typeIterator(iter, range, next_origin, is_structural) + typeIterator(iter, range, next_origin, is_structural) if is_structural @assign range = Ceval.evalExp(range, Ceval.P_EvalTarget.RANGE(info)) @assign iter_ty = typeOf(range) @@ -1807,7 +1803,7 @@ function typeArrayConstructor( #= ExpOrigin.FOR is used here as a marker that this expression may contain iterators. =# @assign next_origin = intBitOr(next_origin, ExpOrigin.FOR) - @assign (arg, ty, exp_var) = Typing.typeExp(call.exp, next_origin, info) + @assign (arg, ty, exp_var) = typeExp(call.exp, next_origin, info) @assign variability = Variability.variabilityMax(variability, exp_var) @assign ty = Type.liftArrayLeftList(ty, dims) @assign variability = Variability.variabilityMax(variability, exp_var) @@ -1984,10 +1980,10 @@ function instNormalCall( @assign callExp = begin @match name begin "size" => begin - BuiltinCall.makeSizeExp(args, named_args, info) + makeSizeExp(args, named_args, info) end "array" => begin - BuiltinCall.makeArrayExp(args, named_args, info) + makeArrayExp(args, named_args, info) end _ => begin #= size creates Expression.SIZE instead of Expression.CALL. @@ -1998,7 +1994,7 @@ function instNormalCall( =# #= Absyn.FOR_ITER_FARG and that is handled in instIteratorCall. =# - @assign fn_ref = instFunction(functionName, scope, info) + @assign (fn_ref, _, _) = instFunction(functionName, scope, info) CALL_EXPRESSION(UNTYPED_CALL(fn_ref, args, named_args, scope)) end end diff --git a/src/NewFrontend/NFCeval.jl b/src/NewFrontend/NFCeval.jl index 12e2252..b5d6eba 100644 --- a/src/NewFrontend/NFCeval.jl +++ b/src/NewFrontend/NFCeval.jl @@ -33,7 +33,7 @@ FuncT = Function ReductionFn = Function Expression = NFExpression Operator = NFOperator -import ..DAE + #import ..ElementSource @UniontypeDecl EvalTarget @@ -426,11 +426,11 @@ function evalComponentBinding( local start_exp::Option{Expression} @assign exp_origin = if isFunction(explicitParent(node)) - ExpOrigin.FUNCTION + ORIGIN_FUNCTION else - ExpOrigin.CLASS + ORIGIN_CLASS end - Typing.typeComponentBinding(node, exp_origin, typeChildren = false) + typeComponentBinding(node, exp_origin, typeChildren = false) @assign comp = component(node) @assign binding = P_Component.getBinding(comp) if isUnbound(binding) @@ -749,7 +749,7 @@ function makeComponentBinding( end _ => begin - NFBinding.EMPTY_BINDING + EMPTY_BINDING end end end @@ -945,10 +945,10 @@ function evalRangeExp(rangeExp::Expression)::Expression (TYPE_REAL(), expl) end - (P_Expression.Expression.BOOLEAN(__), P_Expression.Expression.BOOLEAN(__)) => + (P_Expression.BOOLEAN_EXPRESSION(__), P_Expression.BOOLEAN_EXPRESSION(__)) => begin @assign expl = - List(P_Expression.Expression.BOOLEAN(b) for b = (start.value):(stop.value)) + List(P_Expression.BOOLEAN_EXPRESSION(b) for b = (start.value):(stop.value)) (TYPE_BOOLEAN(), expl) end @@ -1767,7 +1767,7 @@ function evalLogicBinaryAnd( @assign exp = begin local expl::List{Expression} @matchcontinue exp1 begin - P_Expression.Expression.BOOLEAN(__) => begin + P_Expression.BOOLEAN_EXPRESSION(__) => begin if exp1.value evalExp_impl(exp2, target) else @@ -1813,7 +1813,7 @@ function evalLogicBinaryOr( @assign exp = begin local expl::List{Expression} @match exp1 begin - P_Expression.Expression.BOOLEAN(__) => begin + P_Expression.BOOLEAN_EXPRESSION(__) => begin if exp1.value exp1 else @@ -1877,8 +1877,8 @@ function evalLogicUnaryNot(exp1::Expression)::Expression @assign exp = begin @match exp1 begin - P_Expression.Expression.BOOLEAN(__) => begin - P_Expression.Expression.BOOLEAN(!exp1.value) + P_Expression.BOOLEAN_EXPRESSION(__) => begin + P_Expression.BOOLEAN_EXPRESSION(!exp1.value) end ARRAY_EXPRESSION(__) => begin @@ -1981,7 +1981,7 @@ function evalRelationOp_dispatch( end end end - @assign exp = P_Expression.Expression.BOOLEAN(res) + @assign exp = P_Expression.BOOLEAN_EXPRESSION(res) return exp end @@ -1998,7 +1998,7 @@ function evalRelationLess(exp1::Expression, exp2::Expression)::Bool exp1.value < exp2.value end - (P_Expression.Expression.BOOLEAN(__), P_Expression.Expression.BOOLEAN(__)) => begin + (P_Expression.BOOLEAN_EXPRESSION(__), P_Expression.BOOLEAN_EXPRESSION(__)) => begin exp1.value < exp2.value end @@ -2043,7 +2043,7 @@ function evalRelationLessEq(exp1::Expression, exp2::Expression)::Bool exp1.value <= exp2.value end - (P_Expression.Expression.BOOLEAN(__), P_Expression.Expression.BOOLEAN(__)) => begin + (P_Expression.BOOLEAN_EXPRESSION(__), P_Expression.BOOLEAN_EXPRESSION(__)) => begin exp1.value <= exp2.value end @@ -2088,7 +2088,7 @@ function evalRelationGreater(exp1::Expression, exp2::Expression)::Bool exp1.value > exp2.value end - (P_Expression.Expression.BOOLEAN(__), P_Expression.Expression.BOOLEAN(__)) => begin + (P_Expression.BOOLEAN_EXPRESSION(__), P_Expression.BOOLEAN_EXPRESSION(__)) => begin exp1.value > exp2.value end @@ -2133,7 +2133,7 @@ function evalRelationGreaterEq(exp1::Expression, exp2::Expression)::Bool exp1.value >= exp2.value end - (P_Expression.Expression.BOOLEAN(__), P_Expression.Expression.BOOLEAN(__)) => begin + (P_Expression.BOOLEAN_EXPRESSION(__), P_Expression.BOOLEAN_EXPRESSION(__)) => begin exp1.value >= exp2.value end @@ -2178,7 +2178,7 @@ function evalRelationEqual(exp1::Expression, exp2::Expression)::Bool exp1.value == exp2.value end - (P_Expression.Expression.BOOLEAN(__), P_Expression.Expression.BOOLEAN(__)) => begin + (P_Expression.BOOLEAN_EXPRESSION(__), P_Expression.BOOLEAN_EXPRESSION(__)) => begin exp1.value == exp2.value end @@ -2223,7 +2223,7 @@ function evalRelationNotEqual(exp1::Expression, exp2::Expression)::Bool exp1.value != exp2.value end - (P_Expression.Expression.BOOLEAN(__), P_Expression.Expression.BOOLEAN(__)) => begin + (P_Expression.BOOLEAN_EXPRESSION(__), P_Expression.BOOLEAN_EXPRESSION(__)) => begin exp1.value != exp2.value end @@ -2287,7 +2287,7 @@ function evalIfExp2(ifExp::Expression, target::EvalTarget)::Expression ) = ifExp @assign result = begin @match cond begin - P_Expression.Expression.BOOLEAN(__) => begin + P_Expression.BOOLEAN_EXPRESSION(__) => begin evalExp_impl(if cond.value btrue else @@ -2346,7 +2346,7 @@ function evalCall(call::Call, target::EvalTarget)::Expression if P_Function.isBuiltin(c.fn) P_Expression.Expression.bindingExpMap( CALL_EXPRESSION(c), - (target) -> evalBuiltinCallExp(target = target), + (target) -> evalxp(target = target), ) else P_Expression.Expression.bindingExpMap( @@ -2373,26 +2373,23 @@ function evalCall(call::Call, target::EvalTarget)::Expression return exp end -function evalBuiltinCallExp(callExp::Expression, target::EvalTarget)::Expression +function evalxp(callExp::Expression, target::EvalTarget)::Expression local result::Expression - local fn::M_Function local args::List{Expression} - - @match CALL_EXPRESSION(call = P_Call.TYPED_CALL(fn = fn, arguments = args)) = - callExp - @assign result = evalBuiltinCall(fn, args, target) + @match CALL_EXPRESSION(call = TYPED_CALL(fn = fn, arguments = args)) = callExp + @assign result = evalfn(args, target) return result end -function evalBuiltinCall( +function eval( fn::M_Function, args::List{<:Expression}, target::EvalTarget, )::Expression local result::Expression - local fn_path::Absyn.Path = P_Function.nameConsiderBuiltin(fn) + local fn_path::Absyn.Path = nameConsiderBuiltin(fn) @assign result = begin @match AbsynUtil.pathFirstIdent(fn_path) begin @@ -3328,7 +3325,7 @@ function evalBuiltinMax2(exp1::Expression, exp2::Expression)::Expression end end - (P_Expression.Expression.BOOLEAN(__), P_Expression.Expression.BOOLEAN(__)) => begin + (P_Expression.BOOLEAN_EXPRESSION(__), P_Expression.BOOLEAN_EXPRESSION(__)) => begin if exp1.value < exp2.value exp2 else @@ -3425,7 +3422,7 @@ function evalBuiltinMin2(exp1::Expression, exp2::Expression)::Expression end end - (P_Expression.Expression.BOOLEAN(__), P_Expression.Expression.BOOLEAN(__)) => begin + (P_Expression.BOOLEAN_EXPRESSION(__), P_Expression.BOOLEAN_EXPRESSION(__)) => begin if exp1.value > exp2.value exp2 else @@ -3834,14 +3831,14 @@ function evalBuiltinString(args::List{<:Expression})::Expression @match args begin arg <| INTEGER_EXPRESSION(min_len) <| - P_Expression.Expression.BOOLEAN(left_justified) <| nil() => begin + P_Expression.BOOLEAN_EXPRESSION(left_justified) <| nil() => begin @assign str = begin @match arg begin INTEGER_EXPRESSION(__) => begin intString(arg.value) end - P_Expression.Expression.BOOLEAN(__) => begin + P_Expression.BOOLEAN_EXPRESSION(__) => begin boolString(arg.value) end @@ -3869,7 +3866,7 @@ function evalBuiltinString(args::List{<:Expression})::Expression P_Expression.REAL_EXPRESSION(r) <| INTEGER_EXPRESSION(significant_digits) <| INTEGER_EXPRESSION(min_len) <| - P_Expression.Expression.BOOLEAN(left_justified) <| nil() => begin + P_Expression.BOOLEAN_EXPRESSION(left_justified) <| nil() => begin @assign format = "%" + ( @@ -4343,9 +4340,9 @@ function evalBooleanClock(args::List{<:Expression})::Expression local interval::Expression @match args begin condition && - P_Expression.Expression.BOOLEAN(__) <| interval && + P_Expression.BOOLEAN_EXPRESSION(__) <| interval && P_Expression.REAL_EXPRESSION(__) <| nil() => begin - P_Expression.Expression.CLKCONST(P_Expression.P_ClockKind.Expression.BOOLEAN_CLOCK( + P_Expression.Expression.CLKCONST(P_Expression.P_ClockKind.BOOLEAN_EXPRESSION_CLOCK( condition, interval, )) @@ -4621,11 +4618,11 @@ function evalSize( if isSome(optIndex) @assign index_exp = evalExp_impl(Util.getOption(optIndex), target) @assign index = P_Expression.Expression.toInteger(index_exp) - @assign (dim, _, ty_err) = Typing.typeExpDim(exp, index, ExpOrigin.CLASS, info) - Typing.checkSizeTypingError(ty_err, exp, index, info) + @assign (dim, _, ty_err) = typeExpDim(exp, index, ORIGIN_CLASS, info) + checkSizeTypingError(ty_err, exp, index, info) @assign outExp = P_Dimension.Dimension.sizeExp(dim) else - @assign (outExp, ty) = Typing.typeExp(exp, ExpOrigin.CLASS, info) + @assign (outExp, ty) = typeExp(exp, ORIGIN_CLASS, info) @assign expl = List(P_Dimension.Dimension.sizeExp(d) for d in arrayDims(ty)) @assign dim = P_Dimension.Dimension.fromInteger(listLength(expl), Variability.PARAMETER) @assign outExp = diff --git a/src/NewFrontend/NFClass.jl b/src/NewFrontend/NFClass.jl index 4b20184..dca69dc 100644 --- a/src/NewFrontend/NFClass.jl +++ b/src/NewFrontend/NFClass.jl @@ -865,7 +865,7 @@ function lookupAttributeBinding(name::String, cls::Class)::Binding @assign attr_node = lookupElement(name, classTree(cls)) @assign binding = P_Component.getBinding(component(attr_node)) catch - @assign binding = NFBinding.EMPTY_BINDING + @assign binding = EMPTY_BINDING end return binding end diff --git a/src/NewFrontend/NFComponent.jl b/src/NewFrontend/NFComponent.jl index 47cc223..0e786b7 100644 --- a/src/NewFrontend/NFComponent.jl +++ b/src/NewFrontend/NFComponent.jl @@ -1,12 +1,6 @@ - Restriction = NFRestriction - - using MetaModelica using ExportAll - - -import ..DAE Dimension = NFDimension M_Type = NFType Expression = NFExpression @@ -271,7 +265,7 @@ function comment(component::Component)::Option{SCode.Comment} return comment end -function dimensionCount(component::Component)::Integer +function dimensionCount(@nospecialize(component::Component))::Integer local count::Integer @assign count = begin @match component begin @@ -740,7 +734,7 @@ function getCondition(component::Component)::Binding end _ => begin - NFBinding.EMPTY_BINDING + EMPTY_BINDING end end end @@ -850,7 +844,7 @@ function getBinding(component::Component)::Binding end _ => begin - NFBinding.EMPTY_BINDING + EMPTY_BINDING end end end diff --git a/src/NewFrontend/NFConnectEquations.jl b/src/NewFrontend/NFConnectEquations.jl index de37590..3f7ee46 100644 --- a/src/NewFrontend/NFConnectEquations.jl +++ b/src/NewFrontend/NFConnectEquations.jl @@ -79,7 +79,7 @@ import ..NFBinding.P_Binding import ..NFFunction.P_Function import ..Global import ..NFBuiltinCall -BuiltinCall = NFBuiltinCall += NFBuiltinCall import ..NFComplexType ComplexType = NFComplexType import ..P_NFExpandExp @@ -412,7 +412,7 @@ function makeEqualityAssert( @assign ty = getComponentType(lhsCref) @assign lhs_exp = P_Expression.Expression.fromCref(lhsCref) @assign rhs_exp = P_Expression.Expression.fromCref(rhsCref) - if Type.isReal(ty) + if isReal(ty) @assign exp = BINARY_EXPRESSION(lhs_exp, P_Operator.Operator.makeSub(ty), rhs_exp) @assign exp = CALL_EXPRESSION(P_Call.makeTypedCall( diff --git a/src/NewFrontend/NFConvertDAE.jl b/src/NewFrontend/NFConvertDAE.jl index 9c02789..8bb8df2 100644 --- a/src/NewFrontend/NFConvertDAE.jl +++ b/src/NewFrontend/NFConvertDAE.jl @@ -2,7 +2,7 @@ import ..ComponentReference import ..Flags import ..Util -import ..DAE +import DAE function convert( flatModel::FlatModel, @@ -623,18 +623,15 @@ function convertStateSelectAttribute(binding::Binding)::Option{DAE.StateSelect} local node::InstNode local name::String local exp::Expression = - P_Expression.Expression.getBindingExp(getTypedExp(binding)) - + getBindingExp(getTypedExp(binding)) @assign name = begin @match exp begin - P_Expression.Expression.ENUM_LITERAL(__) => begin + ENUM_LITERAL(__) => begin exp.name end - CREF_EXPRESSION(cref = CREF(node = node)) => begin name(node) end - _ => begin Error.assertion( false, @@ -921,20 +918,20 @@ function convertInitialEquation( local body::List{DAE.Element} @match eq begin EQUATION_EQUALITY(__) => begin - @assign e1 = P_Expression.Expression.toDAE(eq.lhs) - @assign e2 = P_Expression.Expression.toDAE(eq.rhs) + @assign e1 = toDAE(eq.lhs) + @assign e2 = toDAE(eq.rhs) _cons(if isComplex(eq.ty) - DAE.Element.INITIAL_COMPLEX_EQUATION(e1, e2, eq.source) + DAE.INITIAL_COMPLEX_EQUATION(e1, e2, eq.source) else - DAE.Element.INITIALEQUATION(e1, e2, eq.source) + DAE.INITIALEQUATION(e1, e2, eq.source) end, elements) end EQUATION_ARRAY_EQUALITY(__) => begin - @assign e1 = P_Expression.Expression.toDAE(eq.lhs) - @assign e2 = P_Expression.Expression.toDAE(eq.rhs) - @assign dims = List(P_Dimension.Dimension.toDAE(d) for d in arrayDims(eq.ty)) - _cons(DAE.Element.INITIAL_ARRAY_EQUATION(dims, e1, e2, eq.source), elements) + @assign e1 = toDAE(eq.lhs) + @assign e2 = toDAE(eq.rhs) + @assign dims = list(toDAE(d) for d in arrayDims(eq.ty)) + _cons(DAE.INITIAL_ARRAY_EQUATION(dims, e1, e2, eq.source), elements) end EQUATION_FOR(__) => begin @@ -1501,7 +1498,7 @@ function makeTypeVar(component::InstNode)::DAE.Var local attr::Attributes @assign comp = component(resolveOuter(component)) - @assign attr = P_Component.getAttributes(comp) + @assign attr = getAttributes(comp) @assign typeVar = DAE.TYPES_VAR( name(component), toDAE(attr, visibility(component)), @@ -1522,7 +1519,7 @@ function makeTypeRecordVar(component::InstNode)::DAE.Var local bind_from_outside::Bool local ty::M_Type @assign comp = component(component) - @assign attr = P_Component.getAttributes(comp) + @assign attr = getAttributes(comp) if P_Component.isConst(comp) && P_Component.hasBinding(comp) @assign vis = Visibility.PROTECTED else diff --git a/src/NewFrontend/NFDimension.jl b/src/NewFrontend/NFDimension.jl index 53c1bac..aa503af 100644 --- a/src/NewFrontend/NFDimension.jl +++ b/src/NewFrontend/NFDimension.jl @@ -155,7 +155,7 @@ function endExp(dim::Dimension, cref::ComponentRef, index::Integer)::Expression end BOOLEAN(__) => begin - P_Expression.Expression.BOOLEAN(true) + P_Expression.BOOLEAN_EXPRESSION(true) end DIMENSION_ENUM(enumType = ty && TYPE_ENUMERATION(__)) => begin diff --git a/src/NewFrontend/NFEvalFunction.jl b/src/NewFrontend/NFEvalFunction.jl index 0f21110..b0bfa25 100644 --- a/src/NewFrontend/NFEvalFunction.jl +++ b/src/NewFrontend/NFEvalFunction.jl @@ -191,7 +191,7 @@ function evaluateExternal(fn::M_Function, args::List{<:Expression})::Expression ann = ann, ) = getSections(getClass(fn.node)) if lang == "builtin" - @assign result = Ceval.evalBuiltinCall(fn, args, P_EvalTarget.IGNORE_ERRORS()) + @assign result = Ceval.evalfn, args, P_EvalTarget.IGNORE_ERRORS()) elseif isKnownExternalFunc(name, ann) @assign result = evaluateKnownExternal(name, args) else @@ -1278,7 +1278,7 @@ function evaluateKnownExternal(name::String, args::List{<:Expression})::Expressi @assign (s1, b) = ModelicaExternalC.Streams_readLine(s1, i) TUPLE_EXPRESSION( TYPE_TUPLE(list(TYPE_STRING(), TYPE_BOOLEAN()), NONE()), - list(STRING_EXPRESSION(s1), P_Expression.Expression.BOOLEAN(b)), + list(STRING_EXPRESSION(s1), P_Expression.BOOLEAN_EXPRESSION(b)), ) end @@ -1295,7 +1295,7 @@ function evaluateKnownExternal(name::String, args::List{<:Expression})::Expressi ( "ModelicaStrings_compare", STRING_EXPRESSION(s1) <| - STRING_EXPRESSION(s2) <| P_Expression.Expression.BOOLEAN(b) <| nil(), + STRING_EXPRESSION(s2) <| P_Expression.BOOLEAN_EXPRESSION(b) <| nil(), ) => begin @assign i = ModelicaExternalC.Strings_compare(s1, s2, b) listGet(COMPARE_LITERALS, i) @@ -1308,7 +1308,7 @@ function evaluateKnownExternal(name::String, args::List{<:Expression})::Expressi ( "ModelicaStrings_scanReal", STRING_EXPRESSION(s1) <| - INTEGER_EXPRESSION(i) <| P_Expression.Expression.BOOLEAN(b) <| nil(), + INTEGER_EXPRESSION(i) <| P_Expression.BOOLEAN_EXPRESSION(b) <| nil(), ) => begin @assign (i, r) = ModelicaExternalC.Strings_scanReal(s1, i, b) TUPLE_EXPRESSION( @@ -1320,7 +1320,7 @@ function evaluateKnownExternal(name::String, args::List{<:Expression})::Expressi ( "ModelicaStrings_scanInteger", STRING_EXPRESSION(s1) <| - INTEGER_EXPRESSION(i) <| P_Expression.Expression.BOOLEAN(b) <| nil(), + INTEGER_EXPRESSION(i) <| P_Expression.BOOLEAN_EXPRESSION(b) <| nil(), ) => begin @assign (i, i2) = ModelicaExternalC.Strings_scanInteger(s1, i, b) TUPLE_EXPRESSION( @@ -1394,7 +1394,7 @@ function evaluateKnownExternal(name::String, args::List{<:Expression})::Expressi STRING_EXPRESSION(s1) <| STRING_EXPRESSION(s2) <| INTEGER_EXPRESSION(i) <| - INTEGER_EXPRESSION(i2) <| P_Expression.Expression.BOOLEAN(b) <| nil(), + INTEGER_EXPRESSION(i2) <| P_Expression.BOOLEAN_EXPRESSION(b) <| nil(), ) => begin evaluateModelicaIO_readRealMatrix(s1, s2, i, i2, b) end @@ -1431,8 +1431,8 @@ function evaluateOpenModelicaRegex(args::List{<:Expression})::Expression STRING_EXPRESSION(str) <| STRING_EXPRESSION(re) <| INTEGER_EXPRESSION(i) <| - P_Expression.Expression.BOOLEAN(extended) <| - P_Expression.Expression.BOOLEAN(insensitive) <| nil() => begin + P_Expression.BOOLEAN_EXPRESSION(extended) <| + P_Expression.BOOLEAN_EXPRESSION(insensitive) <| nil() => begin @assign (n, strs) = System.regex(str, re, i, extended, insensitive) @assign expl = List(STRING_EXPRESSION(s) for s in strs) @assign strs_ty = diff --git a/src/NewFrontend/NFExpandExp.jl b/src/NewFrontend/NFExpandExp.jl index f6bfcb6..9b450f5 100644 --- a/src/NewFrontend/NFExpandExp.jl +++ b/src/NewFrontend/NFExpandExp.jl @@ -907,7 +907,7 @@ function expandBuiltinCat(args::List{<:Expression}, call::Call)::Tuple{Expressio return (exp, expanded) end -function expandBuiltinCall( +function expand fn::M_Function, args::List{<:Expression}, call::Call, @@ -915,7 +915,7 @@ function expandBuiltinCall( local expanded::Bool local outExp::Expression - local fn_path::Absyn.Path = P_Function.nameConsiderBuiltin(fn) + local fn_path::Absyn.Path = nameConsiderBuiltin(fn) @assign (outExp, expanded) = begin @match AbsynUtil.pathFirstIdent(fn_path) begin @@ -960,7 +960,7 @@ function expandCall(call::Call, exp::Expression)::Tuple{Expression, Bool} P_Call.TYPED_CALL( __, ) where {(P_Function.isBuiltin(call.fn) && !P_Function.isImpure(call.fn))} => begin - expandBuiltinCall(call.fn, call.arguments, call) + expandcall.fn, call.arguments, call) end P_Call.TYPED_ARRAY_CONSTRUCTOR(__) => begin @@ -1002,8 +1002,8 @@ function expandTypename(ty::M_Type)::Expression P_Expression.Expression.makeArray( ty, list( - P_Expression.Expression.BOOLEAN(false), - P_Expression.Expression.BOOLEAN(true), + P_Expression.BOOLEAN_EXPRESSION(false), + P_Expression.BOOLEAN_EXPRESSION(true), ), true, ) diff --git a/src/NewFrontend/NFExpandableConnectors.jl b/src/NewFrontend/NFExpandableConnectors.jl index f426a49..a348e33 100644 --- a/src/NewFrontend/NFExpandableConnectors.jl +++ b/src/NewFrontend/NFExpandableConnectors.jl @@ -445,7 +445,7 @@ function augmentExpandableConnector( @assign var = VARIABLE( elem_name, ty, - NFBinding.EMPTY_BINDING, + EMPTY_BINDING, Visibility.PUBLIC, NFComponent.DEFAULT_ATTR, nil, @@ -482,7 +482,7 @@ function augmentExpandableConnector( end #= Create a normal non-expandable complex type for the augmented expandable connector. =# - @assign complex_ty = Typing.makeConnectorType(cls_tree, isExpandable = false) + @assign complex_ty = makeConnectorType(cls_tree, isExpandable = false) @assign ty = TYPE_COMPLEX(cls_node, complex_ty) @assign cls = setType(ty, cls) updateClass(cls, cls_node) @@ -549,7 +549,7 @@ end function updatePotentiallyPresentVariable(var::Variable)::Variable if ConnectorType.isPotentiallyPresent(var.attributes.connectorType) @assign var.attributes = - P_Component.getAttributes(component(node(var.name))) + getAttributes(component(node(var.name))) end return var end diff --git a/src/NewFrontend/NFExpression.jl b/src/NewFrontend/NFExpression.jl index c42c759..8c36c6c 100644 --- a/src/NewFrontend/NFExpression.jl +++ b/src/NewFrontend/NFExpression.jl @@ -13,21 +13,17 @@ Expression = NFExpression c::Expression solverMethod #= string type =#::Expression end - @Record BOOLEAN_CLOCK begin condition::Expression startInterval #= real type >= 0.0 =#::Expression end - @Record REAL_CLOCK begin interval::Expression end - @Record INTEGER_CLOCK begin intervalCounter::Expression resolution #= integer type >= 1 =#::Expression end - @Record INFERRED_CLOCK begin end end diff --git a/src/NewFrontend/NFFlatModel.jl b/src/NewFrontend/NFFlatModel.jl index 0e4e21a..008597f 100644 --- a/src/NewFrontend/NFFlatModel.jl +++ b/src/NewFrontend/NFFlatModel.jl @@ -53,7 +53,7 @@ function reconstructRecordInstance( end end if listEmpty(field_exps) - @assign record_binding = NFBinding.EMPTY_BINDING + @assign record_binding = EMPTY_BINDING else @assign field_exps = listReverseInPlace(field_exps) @assign record_exp = P_Expression.Expression.makeRecord( @@ -69,7 +69,7 @@ function reconstructRecordInstance( record_ty, record_binding, visibility(record_node), - P_Component.getAttributes(record_comp), + getAttributes(record_comp), nil, P_Component.comment(record_comp), info(record_node), diff --git a/src/NewFrontend/NFFlatten.jl b/src/NewFrontend/NFFlatten.jl index 69f71e4..1d22495 100644 --- a/src/NewFrontend/NFFlatten.jl +++ b/src/NewFrontend/NFFlatten.jl @@ -275,7 +275,7 @@ function isDeletedComponent(condition::Binding, prefix::ComponentRef)::Bool end @assign isDeleted = begin @match exp begin - P_Expression.Expression.BOOLEAN(__) => begin + P_Expression.BOOLEAN_EXPRESSION(__) => begin !exp.value end @@ -424,7 +424,7 @@ function flattenSimpleComponent( # ElementSource.createElementSource(info), # ) # @assign sections = prependEquation(eq, sections) - # @assign binding = NFBinding.EMPTY_BINDING + # @assign binding = EMPTY_BINDING # end # end @assign name = prefixScope(comp_node, ty, nil, prefix) @@ -439,7 +439,7 @@ function flattenSimpleComponent( ( "fixed", FLAT_BINDING( - P_Expression.Expression.BOOLEAN(false), + P_Expression.BOOLEAN_EXPRESSION(false), Variability.CONSTANT, ), ), @@ -494,7 +494,7 @@ function getRecordBindings(binding::Binding, comps::Array{<:InstNode})::List{Bin @match binding_exp begin RECORD_EXPRESSION(__) => begin List(if P_Expression.Expression.isEmpty(e) - NFBinding.EMPTY_BINDING + EMPTY_BINDING else FLAT_BINDING(e, var) end for e in binding_exp.elements) @@ -582,7 +582,7 @@ function flattenComplexComponent( sections, isInitial = comp_var <= Variability.PARAMETER, ) - @assign opt_binding = SOME(NFBinding.EMPTY_BINDING) + @assign opt_binding = SOME(EMPTY_BINDING) else @assign binding = setTypedExp(binding_exp, binding) @assign opt_binding = SOME(binding) @@ -823,7 +823,7 @@ function vectorizeAlgorithm( P_Pointer.create(P_Component.ITERATOR( TYPE_INTEGER(), Variability.IMPLICITLY_DISCRETE, - P_Component.info(Pointer.access(prefix_node.component)), + P_Component.info(P_Pointer.access(prefix_node.component)), )), prefix_node.parent, NORMAL_COMP(), @@ -971,7 +971,7 @@ function flattenBinding( end CEVAL_BINDING(__) => begin - NFBinding.EMPTY_BINDING + EMPTY_BINDING end FLAT_BINDING(__) => begin @@ -1917,7 +1917,7 @@ function collectExpFuncs_traverse(exp::Expression, funcs::FunctionTree)::Functio local fn::M_Function @match exp begin CALL_EXPRESSION(__) => begin - @assign funcs = flattenFunction(P_Call.typedFunction(exp.call), funcs) + @assign funcs = flattenFunction(typedFunction(exp.call), funcs) () end @@ -1946,11 +1946,11 @@ RECORD_EXPRESSION(__) => begin return funcs end -function flattenFunction(func::M_Function, funcs::FunctionTree)::FunctionTree +function flattenFunction(@nospecialize(func::M_Function), @nospecialize(funcs::FunctionTree))::FunctionTree local fn::M_Function = func - if !P_Function.isCollected(fn) + if !isCollected(fn) @assign fn = EvalConstants.evaluateFunction(fn) SimplifyModel.simplifyFunction(fn) P_Function.collect(fn) diff --git a/src/NewFrontend/NFFunction.jl b/src/NewFrontend/NFFunction.jl index 3abdbb3..16e413d 100644 --- a/src/NewFrontend/NFFunction.jl +++ b/src/NewFrontend/NFFunction.jl @@ -177,13 +177,13 @@ function getExactVectorizedMatches( matchedFunctions::List{<:MatchedFunction}, )::List{MatchedFunction} local outFuncs::List{MatchedFunction} = - List(mf for mf in matchedFunctions if isExactVectorized(mf.mk)) + list(mf for mf in matchedFunctions if isExactVectorized(mf.mk)) return outFuncs end function getExactMatches(matchedFunctions::List{<:MatchedFunction})::List{MatchedFunction} local outFuncs::List{MatchedFunction} = - List(mf for mf in matchedFunctions if isExact(mf.mk)) + list(mf for mf in matchedFunctions if isExact(mf.mk)) return outFuncs end @@ -204,6 +204,7 @@ FunctionStatus = (() -> begin #= Enumeration =# () -> (BUILTIN; INITIAL; EVALUATED; SIMPLIFIED; COLLECTED) #= The function has been added to the function tree. =# end)() +const FunctionStatusType = Integer using MetaModelica @@ -223,28 +224,25 @@ MapFn = Function outputs::List{InstNode} locals::List{InstNode} slots::List{Slot} - returnType::M_Type + returnType::NFType attributes::DAE.FunctionAttributes derivatives::List{FunctionDerivative} - status::Pointer{FunctionStatus} - callCounter::Pointer{Integer} #= Used during function evaluation to limit recursion. =# + status::Pointer + callCounter::Pointer end end - function getLocalArguments(fn::M_Function)::List{Expression} local localArgs::List{Expression} = nil - local binding::Binding - for l in fn.locals if isComponent(l) - @assign binding = P_Component.getBinding(component(l)) - Error.assertion( - hasExp(binding), - getInstanceName() + " got local component without binding", - sourceInfo(), - ) + @assign binding = getBinding(component(l)) + # Error.assertion( + # hasExp(binding), + # getInstanceName() + " got local component without binding", + # sourceInfo(), + # ) @assign localArgs = _cons(getExp(binding), localArgs) end end @@ -486,7 +484,7 @@ function toDAE(fn::M_Function, def::DAE.FunctionDefinition)::DAE.P_Function @assign unused_inputs = analyseUnusedParameters(fn) @assign defs = _cons( def, - List( + list( P_FunctionDerivative.FunctionDerivative.toDAE(fn_der) for fn_der in fn.derivatives ), ) @@ -507,13 +505,11 @@ end function isDefaultRecordConstructor(fn::M_Function)::Bool local isConstructor::Bool - @assign isConstructor = begin @match restriction(getClass(fn.node)) begin - P_Restriction.Restriction.RECORD_CONSTRUCTOR(__) => begin + RESTRICTION_RECORD_CONSTRUCTOR(__) => begin true end - _ => begin false end @@ -524,13 +520,11 @@ end function inlineBuiltin(fn::M_Function)::DAE.InlineType local inlineType::DAE.InlineType - @assign inlineType = begin @match fn.attributes.isBuiltin begin - DAE.FunctionBuiltin.FUNCTION_BUILTIN_PTR(__) => begin - DAE.InlineType.BUILTIN_EARLY_INLINE() + DAE.FUNCTION_BUILTIN_PTR(__) => begin + DAE.BUILTIN_EARLY_INLINE() end - _ => begin fn.attributes.inline end @@ -597,13 +591,11 @@ end function isSpecialBuiltin(fn::M_Function)::Bool local special::Bool - local path::Absyn.Path - if !isBuiltin(fn) @assign special = false else - @assign path = P_Function.nameConsiderBuiltin(fn) + @assign path = nameConsiderBuiltin(fn) if !AbsynUtil.pathIsIdent(path) @assign special = false else @@ -834,10 +826,9 @@ function isBuiltinAttr(attrs::DAE.FunctionAttributes)::Bool @assign isBuiltin = begin @match attrs.isBuiltin begin - DAE.FunctionBuiltin.FUNCTION_NOT_BUILTIN(__) => begin + DAE.FUNCTION_NOT_BUILTIN(__) => begin false end - _ => begin true end @@ -923,7 +914,7 @@ function typePartialApplication( local arg_ty::M_Type local arg_var::VariabilityType local fn::M_Function - local next_origin::ORIGIN_Type = ExpOrigin.setFlag(origin, ExpOrigin.SUBEXPRESSION) + local next_origin::ORIGIN_Type = setFlag(origin, ORIGIN_SUBEXPRESSION) local inputs::List{InstNode} local slots::List{Slot} @@ -944,7 +935,7 @@ function typePartialApplication( Variability.CONSTANT end for arg in args - @assign (arg, arg_ty, arg_var) = Typing.typeExp(arg, origin, info) + @assign (arg, arg_ty, arg_var) = typeExp(arg, origin, info) @match _cons(arg_name, rest_names) = rest_names @assign (arg, inputs, slots) = applyPartialApplicationArg(arg_name, arg, arg_ty, inputs, slots, fn, info) @@ -978,14 +969,14 @@ function typeFunctionBody(fn::M_Function)::M_Function #= Type the bindings of the outputs and local variables. =# for c in fn.outputs - Typing.typeComponentBinding(c, ExpOrigin.FUNCTION) + typeComponentBinding(c, ORIGIN_FUNCTION) end for c in fn.locals - Typing.typeComponentBinding(c, ExpOrigin.FUNCTION) + typeComponentBinding(c, ORIGIN_FUNCTION) end #= Type the algorithm section of the function, if it has one. =# - Typing.typeFunctionSections(fn.node, ExpOrigin.FUNCTION) + typeFunctionSections(fn.node, ORIGIN_FUNCTION) #= Type any derivatives of the function. =# for fn_der in fn.derivatives @@ -1001,8 +992,8 @@ function typeFunctionSignature(fn::M_Function)::M_Function local node::InstNode = fn.node if !isTyped(fn) - Typing.typeClassType(node, NFBinding.EMPTY_BINDING, ExpOrigin.FUNCTION, node) - Typing.typeComponents(node, ExpOrigin.FUNCTION) + typeClassType(node, EMPTY_BINDING, ORIGIN_FUNCTION, node) + typeComponents(node, ORIGIN_FUNCTION) if isPartial(node) applyComponents( classTree(getClass(node)), @@ -1010,7 +1001,7 @@ function typeFunctionSignature(fn::M_Function)::M_Function ) end for c in fn.inputs - Typing.typeComponentBinding(c, ExpOrigin.FUNCTION) + typeComponentBinding(c, ORIGIN_FUNCTION) end @assign fn.slots = makeSlots(fn.inputs) checkParamTypes(fn) @@ -1040,20 +1031,18 @@ end they are not already typed. =#""" function typeNodeCache(functionNode::InstNode)::List{M_Function} local functions::List{M_Function} - local fn_node::InstNode local typed::Bool local special::Bool local name::String - @assign fn_node = classScope(functionNode) @match C_FUNCTION(functions, typed, special) = getFuncCache(fn_node) #= Type the function(s) if not already done. =# if !typed - @assign functions = List(typeFunctionSignature(f) for f in functions) + @assign functions = list(typeFunctionSignature(f) for f in functions) setFuncCache(fn_node, C_FUNCTION(functions, true, special)) - @assign functions = List(typeFunctionBody(f) for f in functions) + @assign functions = list(typeFunctionBody(f) for f in functions) setFuncCache(fn_node, C_FUNCTION(functions, true, special)) end return functions @@ -1063,13 +1052,11 @@ end they are not already typed. =#""" function typeRefCache(functionRef::ComponentRef)::List{M_Function} local functions::List{M_Function} - @assign functions = begin @match functionRef begin - CREF(__) => begin + COMPONENT_REF_CREF(__) => begin typeNodeCache(functionRef.node) end - _ => begin Error.assertion( false, @@ -1216,7 +1203,7 @@ function matchArgVectorized( if listEmpty(vectDims) @assign vectDims = fillUnknownVectorizedDims(vect_dims, argExp) @assign vectArg = argExp - elseif !ListUtil.isEqualOnTrue(vectDims, vect_dims, P_Dimension.Dimension.isEqual) + elseif !ListUtil.isEqualOnTrue(vectDims, vect_dims, isEqual) Error.addSourceMessage( Error.VECTORIZE_CALL_DIM_MISMATCH, list( @@ -1743,7 +1730,7 @@ function callString( str + ", " + stringDelimitList( - List( + list( Util.tuple21(arg) + " = " + toString(Util.tuple22(arg)) for arg in namedArgs ), @@ -1756,7 +1743,7 @@ end function candidateFuncListString(fns::List{<:M_Function})::String local s::String = - stringDelimitList(List(P_Function.signatureString(fn, true) for fn in fns), "\\n ") + stringDelimitList(list(P_Function.signatureString(fn, true) for fn in fns), "\\n ") return s end @@ -1873,17 +1860,14 @@ end (or shouldn't be added, e.g. if it's builtin), otherwise false. =#""" function isCollected(fn::M_Function)::Bool local collected::Bool - @assign collected = begin - @match Pointer.access(fn.status) begin + @match P_Pointer.access(fn.status) begin FunctionStatus.BUILTIN => begin true end - FunctionStatus.COLLECTED => begin true end - _ => begin false end @@ -1955,7 +1939,7 @@ function mapCachedFuncs(inNode::InstNode, mapFn::MapFn) @assign cache = begin @match cache begin C_FUNCTION(__) => begin - @assign cache.funcs = List(mapFn(fn) for fn in cache.funcs) + @assign cache.funcs = list(mapFn(fn) for fn in cache.funcs) cache end @@ -1988,14 +1972,16 @@ function getCachedFuncs(inNode::InstNode)::List{M_Function} end function instFunction3(fnNode::InstNode)::InstNode - - @assign fnNode = instantiate(fnNode) + @error "Calling inst function 3" + @assign fnNode = instantiateN1(fnNode, EMPTY_NODE()) #= Set up an empty function cache to signal that this function is =# - #= currently being instantiated, so recursive functions can be handled. + #= currently being instantiatdded, so recursive functions can be handled. =# + @error "Callng cache init func!" cacheInitFunc(fnNode) instExpressions(fnNode) + #@info "Returning in instfunction3" return fnNode end @@ -2012,14 +1998,14 @@ function instFunction2( @assign (fnNode, specialBuiltin) = begin local cdef::SCode.ClassDef local fn::M_Function - local cr::Absyn.P_ComponentRef.ComponentRef + local cr::Absyn.ComponentRef local sub_fnNode::InstNode local funcs::List{M_Function} local fn_ders::List{FunctionDerivative} @match def begin SCode.CLASS(__) where {(SCodeUtil.isOperatorRecord(def))} => begin @assign fnNode = instFunction3(fnNode) - @assign fnNode = OperatorOverloading.instConstructor(fnPath, fnNode, info) + @assign fnNode = instConstructor(fnPath, fnNode, info) (fnNode, false) end @@ -2048,15 +2034,17 @@ function instFunction2( SCode.CLASS(__) => begin if SCodeUtil.isOperator(def) - OperatorOverloading.checkOperatorRestrictions(fnNode) + checkOperatorRestrictions(fnNode) end + @error "Before set node type" @assign fnNode = setNodeType(ROOT_CLASS(parent), fnNode) + @error "After setNodeType" @assign fnNode = instFunction3(fnNode) @assign fn = new(fnPath, fnNode) @assign specialBuiltin = isSpecialBuiltin(fn) @assign fn.derivatives = - P_FunctionDerivative.FunctionDerivative.instDerivatives(fnNode, fn) + instDerivatives(fnNode, fn) @assign fnNode = cacheAddFunc(fnNode, fn, specialBuiltin) (fnNode, specialBuiltin) end @@ -2067,16 +2055,13 @@ end """ #= Instantiates the given InstNode as a function. =#""" function instFunctionNode(node::InstNode)::InstNode - local cache::CachedData - @assign cache = getFuncCache(node) @assign () = begin @match cache begin C_FUNCTION(__) => begin () end - _ => begin @assign node = instFunction2(scopePath(node), node, info(node)) @@ -2099,14 +2084,12 @@ function instFunctionRef( @assign fn_node = classScope(node(fn_ref)) @assign cache = getFuncCache(fn_node) - #= Check if a cached instantiation of this function already exists. - =# + #= Check if a cached instantiation of this function already exists. =# @assign (fn_node, specialBuiltin) = begin @match cache begin C_FUNCTION(__) => begin (fn_node, cache.specialBuiltin) end - _ => begin @assign parent = if isRedeclare(node(fn_ref)) || @@ -2133,9 +2116,7 @@ function instFunction( local specialBuiltin::Bool local fn_node::InstNode local fn_ref::ComponentRef - local cache::CachedData - @assign fn_ref = lookupFunction(functionName, scope, info) @assign (fn_ref, fn_node, specialBuiltin) = instFunctionRef(fn_ref, info) return (fn_ref, fn_node, specialBuiltin) @@ -2147,17 +2128,12 @@ function lookupFunction( info::SourceInfo, )::ComponentRef local functionRef::ComponentRef - local found_scope::InstNode local state::LookupState local functionPath::Absyn.Path local prefix::ComponentRef local is_class::Bool - try - @assign functionPath = AbsynUtil.crefToPath(functionName) - catch e - @error "Function path not found we have error $e" - end + @assign functionPath = AbsynUtil.crefToPath(functionName) #= Make sure the name is a path. =# @assign (functionRef, found_scope) = lookupFunctionName(functionName, scope, info) @@ -2190,14 +2166,13 @@ end function new(path::Absyn.Path, node::InstNode)::M_Function local fn::M_Function - local cls::Class local inputs::List{InstNode} local outputs::List{InstNode} local locals::List{InstNode} local slots::List{Slot} local attr::DAE.FunctionAttributes - local status::FunctionStatus + local status::FunctionStatusType @assign (inputs, outputs, locals) = collectParams(node) @assign attr = makeAttributes(node, inputs, outputs) @@ -2208,7 +2183,7 @@ function new(path::Absyn.Path, node::InstNode)::M_Function else FunctionStatus.INITIAL end - @assign fn = FUNCTION( + @assign fn = M_FUNCTION( path, node, inputs, @@ -2226,21 +2201,17 @@ end function isValidParamState(cls::InstNode)::Bool local isValid::Bool - @assign isValid = begin @match restriction(getClass(cls)) begin RESTRICTION_RECORD(__) => begin true end - RESTRICTION_TYPE(__) => begin true end - RESTRICTION_OPERATOR(__) => begin true end - RESTRICTION_FUNCTION(__) => begin true end @@ -2248,7 +2219,6 @@ function isValidParamState(cls::InstNode)::Bool RESTRICTION_EXTERNAL_OBJECT(__) => begin true end - _ => begin false end @@ -2257,9 +2227,8 @@ function isValidParamState(cls::InstNode)::Bool return isValid end -function isValidParamType(ty::M_Type)::Bool +function isValidParamType(ty::NFType)::Bool local isValid::Bool - @assign isValid = begin @match ty begin TYPE_INTEGER(__) => begin @@ -2320,7 +2289,6 @@ end function checkParamTypes2(params::List{<:InstNode}) local ty::M_Type - return for p in params @assign ty = getType(p) if !isValidParamType(ty) @@ -2343,15 +2311,15 @@ function checkParamTypes(fn::M_Function) end function makeAttributes( - node::InstNode, - inputs::List{<:InstNode}, - outputs::List{<:InstNode}, + @nospecialize(node::InstNode), + @nospecialize(inputs::List{<:InstNode}), + @nospecialize (outputs::List{<:InstNode}) )::DAE.FunctionAttributes local attr::DAE.FunctionAttributes local def::SCode.Element local params::Array{InstNode} - local res::SCode.P_Restriction.Restriction + local res::SCode.Restriction local fres::SCode.FunctionRestriction local is_partial::Bool local cmts::List{SCode.Comment} @@ -2359,12 +2327,12 @@ function makeAttributes( @assign def = definition(node) @assign res = SCodeUtil.getClassRestriction(def) - Error.assertion( - SCodeUtil.isFunctionRestriction(res), - getInstanceName() + " got non-function restriction", - sourceInfo(), - ) - @match SCode.P_Restriction.Restriction.R_FUNCTION(functionRestriction = fres) = res + # Error.assertion( + # SCodeUtil.isFunctionRestriction(res), + # getInstanceName() + " got non-function restriction", + # sourceInfo(), + # ) TODO + @match SCode.R_FUNCTION(functionRestriction = fres) = res @assign is_partial = SCodeUtil.isPartial(def) @assign cmts = getComments(node) @assign cmt = mergeFunctionAnnotations(cmts) @@ -2373,7 +2341,7 @@ function makeAttributes( local is_om_pure::Bool local has_out_params::Bool local has_unbox_args::Bool - local name::String + local nameVar::String local in_params::List{String} local out_params::List{String} local inline_ty::DAE.InlineType @@ -2381,11 +2349,11 @@ function makeAttributes( #= External function. =# @matchcontinue fres begin - SCode.FunctionRestriction.FR_EXTERNAL_FUNCTION(is_impure) => begin - @assign in_params = List(name(i) for i in inputs) - @assign out_params = List(name(o) for o in outputs) - @assign name = SCodeUtil.isBuiltinFunction(def, in_params, out_params) - @assign inline_ty = InstUtil.commentIsInlineFunc(cmt) + SCode.FR_EXTERNAL_FUNCTION(is_impure) => begin + @assign in_params = list(name(i) for i in inputs) + @assign out_params = list(name(o) for o in outputs) + @assign nameVar = SCodeUtil.isBuiltinFunction(def, in_params, out_params) + @assign inline_ty = commentIsInlineFunc(cmt) @assign is_impure = is_impure || hasImpure(cmt) @assign has_unbox_args = hasUnboxArgsAnnotation(cmt) DAE.FUNCTION_ATTRIBUTES( @@ -2393,33 +2361,33 @@ function makeAttributes( hasOMPure(cmt), is_impure, is_partial, - DAE.FUNCTION_BUILTIN(SOME(name), has_unbox_args), + DAE.FUNCTION_BUILTIN(SOME(nameVar), has_unbox_args), DAE.FP_NON_PARALLEL(), ) end - SCode.FunctionRestriction.FR_PARALLEL_FUNCTION(__) => begin + SCode.FR_PARALLEL_FUNCTION(__) => begin #= Parallel function: there are some builtin functions. =# - @assign in_params = List(name(i) for i in inputs) - @assign out_params = List(name(o) for o in outputs) - @assign name = SCodeUtil.isBuiltinFunction(def, in_params, out_params) - @assign inline_ty = InstUtil.commentIsInlineFunc(cmt) + @assign in_params = list(name(i) for i in inputs) + @assign out_params = list(name(o) for o in outputs) + @assign nameVar = SCodeUtil.isBuiltinFunction(def, in_params, out_params) + @assign inline_ty = commentIsInlineFunc(cmt) @assign has_unbox_args = hasUnboxArgsAnnotation(cmt) DAE.FUNCTION_ATTRIBUTES( inline_ty, hasOMPure(cmt), false, is_partial, - DAE.FUNCTION_BUILTIN(SOME(name), has_unbox_args), + DAE.FUNCTION_BUILTIN(SOME(nameVar), has_unbox_args), DAE.FP_PARALLEL_FUNCTION(), ) end - SCode.FunctionRestriction.FR_PARALLEL_FUNCTION(__) => begin + SCode.FR_PARALLEL_FUNCTION(__) => begin #= Parallel function: non-builtin. =# - @assign inline_ty = InstUtil.commentIsInlineFunc(cmt) + @assign inline_ty = commentIsInlineFunc(cmt) DAE.FUNCTION_ATTRIBUTES( inline_ty, hasOMPure(cmt), @@ -2430,7 +2398,7 @@ function makeAttributes( ) end - SCode.FunctionRestriction.FR_KERNEL_FUNCTION(__) => begin + SCode.FR_KERNEL_FUNCTION(__) => begin DAE.FUNCTION_ATTRIBUTES( DAE.NO_INLINE(), true, @@ -2446,13 +2414,14 @@ function makeAttributes( =# #= Normal function. =# - @assign inline_ty = InstUtil.commentIsInlineFunc(cmt) + # @assign inline_ty = commentIsInlineFunc(cmt) TODO + inline_ty = DAE.NO_INLINE() #TODO tmp #= In Modelica 3.2 and before, external functions with side-effects are not marked. =# @assign is_impure = SCodeUtil.isRestrictionImpure( res, - Config.languageStandardAtLeast(Config.LanguageStandard.V3_3) || +# Config.languageStandardAtLeast(Config.LanguageStandard.V3_3) || !listEmpty(outputs), ) || SCodeUtil.commentHasBooleanNamedAnnotation( cmt, @@ -2472,6 +2441,10 @@ function makeAttributes( return attr end +function commentIsInlineFunc(cmt::SCode.Comment) + return DAE.NO_INLINE() +end + """ #= Merges the function's comments from inherited classes. =#""" function mergeFunctionAnnotations(comments::List{<:SCode.Comment})::SCode.Comment local outComment::SCode.Comment @@ -2510,6 +2483,7 @@ function mergeFunctionAnnotations(comments::List{<:SCode.Comment})::SCode.Commen return outComment end + function getBuiltin(def::SCode.Element)::DAE.FunctionBuiltin local builtin::DAE.FunctionBuiltin = if SCodeUtil.isBuiltinElement(def) DAE.FUNCTION_BUILTIN_PTR() @@ -2531,32 +2505,32 @@ function hasOMPure(cmt::SCode.Comment)::Bool return res end -function makeSlot(component::InstNode, index::Integer)::Slot +function makeSlot(@nospecialize(componentArg::InstNode), @nospecialize(index::Integer))::Slot local slot::Slot - local comp::Component local default::Option{Expression} - local name::String - + local nameVar::String try - @assign comp = component(component) - @assign default = typedExp(P_Component.getImplicitBinding(comp)) - @assign name = name(component) - if stringGet(name, 1) == 36 - if stringLength(name) > 4 && substring(name, 1, 4) == "in_" - @assign name = substring(name, 5, stringLength(name)) + @assign comp = component(componentArg) + @assign default = typedExp(getImplicitBinding(comp)) + @assign nameVar = name(componentArg) + if stringGet(nameVar, 1) == 36 + if stringLength(nameVar) > 4 && substring(nameVar, 1, 4) == "in_" + @assign nameVar = substring(nameVar, 5, stringLength(nameVar)) end end @assign slot = SLOT( - name(component), + name(componentArg), SlotType.GENERIC, default, NONE(), index, SlotEvalStatus.NOT_EVALUATED, ) - catch - Error.assertion(false, getInstanceName() + " got invalid component", sourceInfo()) + catch e + # Error.assertion(false, getInstanceName() + " got invalid component", sourceInfo()) + @error "Error. Our error was $e" + fail() end #= Remove $in_ for OM input output arguments. =# @@ -2564,11 +2538,9 @@ function makeSlot(component::InstNode, index::Integer)::Slot return slot end -function makeSlots(inputs::List{<:InstNode})::List{Slot} +function makeSlots(@nospecialize(inputs::List{<:InstNode}))::List{Slot} local slots::List{Slot} = nil - local index::Integer = 1 - for i in inputs @assign slots = _cons(makeSlot(i, index), slots) @assign index = index + 1 @@ -2577,11 +2549,10 @@ function makeSlots(inputs::List{<:InstNode})::List{Slot} return slots end -function paramDirection(component::InstNode)::DirectionType +function paramDirection(@nospecialize(componentArg::InstNode))::DirectionType local direction::DirectionType - local cty::ConnectorType.TYPE - local io::InnerOuter + local io::Integer local vis::VisibilityType local var::VariabilityType @@ -2589,46 +2560,50 @@ function paramDirection(component::InstNode)::DirectionType connectorType = cty, direction = direction, innerOuter = io, - ) = P_Component.getAttributes(component(component)) - @assign vis = visibility(component) - @assign var = variability(component(component)) + ) = getAttributes(component(componentArg)) + @assign vis = visibility(componentArg) + @assign var = variability(component(componentArg)) #= Function components may not be connectors. =# - if ConnectorType.isFlowOrStream(cty) + if isFlowOrStream(cty) Error.addSourceMessage( Error.INNER_OUTER_FORMAL_PARAMETER, - list(ConnectorType.toString(cty), name(component)), - info(component), + list(ConnectorType.toString(cty), name(componentArg)), + info(componentArg), ) fail() end #= Function components may not be inner/outer. =# if io != InnerOuter.NOT_INNER_OUTER - Error.addSourceMessage( - Error.INNER_OUTER_FORMAL_PARAMETER, - list(P_Prefixes.innerOuterString(io), name(component)), - info(component), - ) + # Error.addSourceMessage( + # Error.INNER_OUTER_FORMAL_PARAMETER, + # list(P_Prefixes.innerOuterString(io), name(componentArg)), + # info(component), + # ) fail() end #= Formal parameters must be public, other function variables must be protected. =# if direction != Direction.NONE if vis == Visibility.PROTECTED - Error.addSourceMessage( - Error.PROTECTED_FORMAL_FUNCTION_VAR, - list(name(component)), - info(component), - ) + # Error.addSourceMessage( + # Error.PROTECTED_FORMAL_FUNCTION_VAR, + # list(name(componentArg)), + # info(componentArg), + # ) + @error "Formal parameters must be public, other function variables must be protected." fail() end elseif vis == Visibility.PUBLIC - Error.addSourceMessageAsError( - Error.NON_FORMAL_PUBLIC_FUNCTION_VAR, - list(name(component)), - info(component), - ) + # Error.addSourceMessageAsError( + # Error.NON_FORMAL_PUBLIC_FUNCTION_VAR, + # list(name(componentArg)), + # info(componentArg), + # ) +# componentArg), + # ) + @error "Non formal public funcition variable" fail() end return direction @@ -2636,7 +2611,7 @@ end """ #= Sorts all the function parameters as inputs, outputs and locals. =#""" function collectParams( - node::InstNode, + @nospecialize(node::InstNode), inputs::List{<:InstNode} = nil, outputs::List{<:InstNode} = nil, locals::List{<:InstNode} = nil, @@ -2646,15 +2621,15 @@ function collectParams( local comps::Array{InstNode} local n::InstNode - Error.assertion( - isClass(node), - getInstanceName() + " got non-class node", - sourceInfo(), - ) + # Error.assertion( + # isClass(node), + # getInstanceName() + " got non-class node", + # sourceInfo(), + # ) TODO @assign cls = getClass(node) @assign () = begin @match cls begin - INSTANCED_CLASS(elements = FLAT_TREE(components = comps)) => + INSTANCED_CLASS(elements = CLASS_TREE_FLAT_TREE(components = comps)) => begin for i = arrayLength(comps):(-1):1 @assign n = comps[i] @@ -2759,7 +2734,7 @@ function getBody2(node::InstNode)::List{Statement} @assign body = begin @match cls begin INSTANCED_CLASS( - sections = P_Sections.Sections.SECTIONS(algorithms = fn_body <| nil()), + sections = SECTIONS_SECTIONS(algorithms = fn_body <| nil()), ) => begin fn_body.statements end @@ -2767,7 +2742,7 @@ function getBody2(node::InstNode)::List{Statement} nil end INSTANCED_CLASS( - sections = P_Sections.Sections.SECTIONS(algorithms = _ <| _), + sections = SECTIONS_SECTIONS(algorithms = _ <| _), ) => begin Error.assertion( false, @@ -2791,7 +2766,7 @@ end function makeReturnType(fn::M_Function)::M_Type local returnType::M_Type local ret_tyl::List{M_Type} - @assign ret_tyl = List(getType(o) for o in fn.outputs) + @assign ret_tyl = list(getType(o) for o in fn.outputs) @assign returnType = begin @match ret_tyl begin nil() => begin diff --git a/src/NewFrontend/NFFunctionDerivative.jl b/src/NewFrontend/NFFunctionDerivative.jl index 755154d..8a1f545 100644 --- a/src/NewFrontend/NFFunctionDerivative.jl +++ b/src/NewFrontend/NFFunctionDerivative.jl @@ -75,7 +75,7 @@ function typeDerivative(fnDer::FunctionDerivative) P_Function.typeNodeCache(fnDer.derivativeFn) @assign info = info(fnDer.derivedFn) - @assign (order, order_ty, var) = Typing.typeExp(fnDer.order, ExpOrigin.FUNCTION, info) + @assign (order, order_ty, var) = typeExp(fnDer.order, ORIGIN_FUNCTION, info) @assign (order, _, mk) = TypeCheck.matchTypes(order_ty, TYPE_INTEGER(), order) if TypeCheck.isIncompatibleMatch(mk) Error.addSourceMessage( @@ -289,15 +289,15 @@ function getDerivativeAnnotations(definition::SCode.Element)::List{SCode.Mod} @assign derMods = begin local ann::SCode.Annotation @match definition begin - SCode.Element.CLASS( - classDef = SCode.ClassDef.PARTS( - externalDecl = SOME(SCode.ExternalDecl.EXTERNALDECL(annotation_ = SOME(ann))), + SCode.CLASS( + classDef = SCode.PARTS( + externalDecl = SOME(SCode.EXTERNALDECL(annotation_ = SOME(ann))), ), ) => begin SCodeUtil.lookupNamedAnnotations(ann, "derivative") end - SCode.Element.CLASS(cmt = SCode.Comment.COMMENT(annotation_ = SOME(ann))) => begin + SCode.CLASS(cmt = SCode.COMMENT(annotation_ = SOME(ann))) => begin SCodeUtil.lookupNamedAnnotations(ann, "derivative") end diff --git a/src/NewFrontend/NFInline.jl b/src/NewFrontend/NFInline.jl index 429d230..b5e3856 100644 --- a/src/NewFrontend/NFInline.jl +++ b/src/NewFrontend/NFInline.jl @@ -36,7 +36,7 @@ using ExportAll import ..P_NFComponentRef P_ComponentRef = P_NFComponentRef ComponentRef = P_NFComponentRef.NFComponentRef -import ..DAE.InlineType +import DAE.InlineType import ..P_NFDimension P_Dimension = P_NFDimension Dimension = P_NFDimension.NFDimension diff --git a/src/NewFrontend/NFInst.jl b/src/NewFrontend/NFInst.jl index cd29d65..3403461 100644 --- a/src/NewFrontend/NFInst.jl +++ b/src/NewFrontend/NFInst.jl @@ -1,6 +1,6 @@ import Absyn import SCode -import ..DAE +import DAE """ #= Instantiates a class given by its fully qualified path, with the result being a DAE. =#""" function instClassInProgram(classPath::Absyn.Path, program::SCode.Program)::Tuple{DAE.DAE_LIST, DAE.FunctionTree} @@ -61,29 +61,29 @@ import ..DAE #execStat("NFInst.updateImplicitVariability") #= Type the class. =# - @debug "typeClass(inst_cls, name)" + @info "TYPECLASS(inst_cls, name)" typeClass(inst_cls, name) - @debug "After type class" + @info "AFTER type class" #= Flatten the model and evaluate constants in it. =# - @debug "START FLATTENING!" + @info "START FLATTENING!" @assign flat_model = flatten(inst_cls, name) - @debug "CONSTANT EVALUATION" + @info "CONSTANT EVALUATION" @assign flat_model = evaluate(flat_model) - @debug "FLATTENING DONE: $flat_model" + @info "FLATTENING DONE: flat_model" #= Do unit checking =# # @assign flat_model = UnitCheck.checkUnits(flat_model) TODO #= Apply simplifications to the model.=# @assign flat_model = simplify(flat_model) #= Collect a tree of all functions that are still used in the flat model.=# - @debug "COLLECT FUNCTIONS" + @info "COLLECT FUNCTIONS" @assign funcs = collectFunctions(flat_model, name) - @debug "COLLECTED FUNCTIONS!" + @info "COLLECTED FUNCTIONS!" #= Collect package constants that couldn't be substituted with their values =# #= (e.g. because they where used with non-constant subscripts), and add them to the model. =# - @debug "COLLECT CONSTANTS" + @info "COLLECT CONSTANTS" @assign flat_model = collectConstants(flat_model, funcs) - @debug "COLLECTED CONSTANTS" + @info "COLLECTED CONSTANTS" # if Flags.getConfigBool(Flags.FLAT_MODELICA) @debug "PRINTING FLAT MODELICA" # printFlatString(flat_model, FunctionTreeImpl.listValues(funcs)) @@ -96,7 +96,7 @@ import ..DAE @assign flat_model.variables = ListUtil.filterOnFalse(flat_model.variables, isEmptyArray) # end #= Remove empty arrays from variables =# - @debug "VERIFYING MODEL" + @info "VERIFYING MODEL: " verify(flat_model) # if Flags.isSet(Flags.NF_DUMP_FLAT) # print("FlatModel:\\n" + toString(flat_model) + "\\n") @@ -244,7 +244,7 @@ function makeEnumerationType(literals::List{<:SCode.Enum}, scope::InstNode) ::M_ local path::Absyn.Path @assign path = scopePath(scope) - @assign lits = List(e.literal for e in literals) + @assign lits = list(e.literal for e in literals) @assign ty = TYPE_ENUMERATION(path, lits) ty end @@ -582,7 +582,7 @@ function expandClassDerived(element::SCode.Element, definition::SCode.ClassDef, @assign cls = getClass(node) @assign prefs = getPrefixes(cls) @assign attrs = instDerivedAttributes(sattrs) - @assign dims = List(DIMENSION_RAW_DIM(d) for d in AbsynUtil.typeSpecDimensions(ty)) + @assign dims = list(DIMENSION_RAW_DIM(d) for d in AbsynUtil.typeSpecDimensions(ty)) @assign mod = getModifier(cls) @assign res = P_Restriction.Restriction.fromSCode(SCodeUtil.getClassRestriction(element)) @assign cls = EXPANDED_DERIVED(ext_node, mod, listArray(dims), prefs, attrs, res) @@ -2008,7 +2008,6 @@ function instRecordConstructor(node::InstNode) C_FUNCTION(__) => begin () end - _ => begin cacheInitFunc(node) if SCodeUtil.isOperatorRecord(definition(node)) @@ -2148,11 +2147,11 @@ function instExp(absynExp::Absyn.Exp, scope::InstNode, info::SourceInfo) ::Expre end Absyn.STRING(__) => begin - Expression.STRING(System.unescapedString(absynExp.value)) + STRING_EXPRESSION(System.unescapedString(absynExp.value)) end Absyn.BOOL(__) => begin - Expression.BOOLEAN(absynExp.value) + BOOLEAN_EXPRESSION(absynExp.value) end Absyn.CREF(__) => begin @@ -2160,12 +2159,12 @@ function instExp(absynExp::Absyn.Exp, scope::InstNode, info::SourceInfo) ::Expre end Absyn.ARRAY(__) => begin - @assign expl = List(instExp(e, scope, info) for e in absynExp.arrayExp) + @assign expl = list(instExp(e, scope, info) for e in absynExp.arrayExp) makeArray(TYPE_UNKNOWN(), expl) end Absyn.MATRIX(__) => begin - @assign expll = List(List(instExp(e, scope, info) for e in el) for el in absynExp.matrix) + @assign expll = list(list(instExp(e, scope, info) for e in el) for el in absynExp.matrix) MATRIX_EXPRESSION(expll) end @@ -2177,7 +2176,7 @@ function instExp(absynExp::Absyn.Exp, scope::InstNode, info::SourceInfo) ::Expre end Absyn.TUPLE(__) => begin - @assign expl = List(instExp(e, scope, info) for e in absynExp.expressions) + @assign expl = list(instExp(e, scope, info) for e in absynExp.expressions) TUPLE_EXPRESSION(TYPE_UNKNOWN(), expl) end @@ -2340,11 +2339,9 @@ function instCrefFunction(cref::ComponentRef, info::SourceInfo) ::Expression crefExp end -function instCrefTypename(cref::ComponentRef, node::InstNode, info::SourceInfo) ::Expression +function instCrefTypename(@nospecialize(cref::ComponentRef), @nospecialize(node::InstNode), info::SourceInfo)x::Expression local crefExp::Expression - - local ty::M_Type - + local ty::NFType checkUnsubscriptableCref(cref, info) @assign ty = getType(node) @assign ty = begin @@ -2356,7 +2353,7 @@ function instCrefTypename(cref::ComponentRef, node::InstNode, info::SourceInfo) ARRAY_TYPE(ty, list(P_Dimension.Dimension.ENUM(ty))) end _ => begin - Error.assertion(false, getInstanceName() + " got unknown class node " + name(node), sourceInfo()) + #Error.assertion(false, getInstanceName() + " got unknown class node " + name(node), sourceInfo()) fail() end end @@ -2378,7 +2375,7 @@ function instCrefSubscripts(cref::ComponentRef, scope::InstNode, info::SourceInf @match cref begin COMPONENT_REF_CREF(__) => begin if ! listEmpty(cref.subscripts) - @assign cref.subscripts = List(instSubscript(s, scope, info) for s in cref.subscripts) + @assign cref.subscripts = list(instSubscript(s, scope, info) for s in cref.subscripts) end @assign rest_cr = instCrefSubscripts(cref.restCref, scope, info) if ! referenceEq(rest_cr, cref.restCref) @@ -2423,8 +2420,8 @@ function instPartEvalFunction(func::Absyn.ComponentRef, funcArgs::Absyn.Function @assign outExp = instCref(func, scope, info) if ! listEmpty(nargs) @assign fn_ref = P_Expression.Expression.toCref(outExp) - @assign args = List(instExp(arg.argValue, scope, info) for arg in nargs) - @assign arg_names = List(arg.argName for arg in nargs) + @assign args = list(instExp(arg.argValue, scope, info) for arg in nargs) + @assign arg_names = list(arg.argName for arg in nargs) @assign outExp = PARTIAL_FUNCTION_APPLICATION_EXPRESSION(fn_ref, args, arg_names, TYPE_UNKNOWN()) end outExp @@ -2484,28 +2481,27 @@ function instSections2(parts::SCode.ClassDef, scope::InstNode, sections::Section sections end -function instExternalDecl(extDecl::SCode.ExternalDecl, scope::InstNode) ::Sections +function instExternalDecl(@nospecialize(extDecl::SCode.ExternalDecl), @nospecialize(scope::InstNode)) ::Sections local sections::Sections - @assign sections = begin - local name::String + local nameVar::String local lang::String local args::List{Expression} local ret_cref::ComponentRef - local info::SourceInfo + local infoVar::SourceInfo @match extDecl begin SCode.EXTERNALDECL(__) => begin - @assign info = info(scope) - @assign name = Util.getOptionOrDefault(extDecl.funcName, name(scope)) + @assign infoVar = info(scope) + @assign nameVar = Util.getOptionOrDefault(extDecl.funcName, name(scope)) @assign lang = Util.getOptionOrDefault(extDecl.lang, "C") - checkExternalDeclLanguage(lang, info) - @assign args = List(instExp(arg, scope, info) for arg in extDecl.args) + checkExternalDeclLanguage(lang, infoVar) + @assign args = list(instExp(arg, scope, infoVar) for arg in extDecl.args) if isSome(extDecl.output_) - @assign ret_cref = Lookup.lookupLocalComponent(Util.getOption(extDecl.output_), scope, info) + @assign ret_cref = Lookup.lookupLocalComponent(Util.getOption(extDecl.output_), scope, infoVar) else - @assign ret_cref = ComponentRef.EMPTY() + @assign ret_cref = COMPONENT_REF_EMPTY() end - SECTIONS_EXTERNAL(name, args, ret_cref, lang, extDecl.annotation_, isSome(extDecl.funcName)) + SECTIONS_EXTERNAL(nameVar, args, ret_cref, lang, extDecl.annotation_, isSome(extDecl.funcName)) end end end @@ -2562,7 +2558,7 @@ end function instEEquations(scodeEql::List{<:SCode.EEquation}, scope::InstNode, origin::ORIGIN_Type) ::List{Equation} local instEql::List{Equation} - @assign instEql = List(instEEquation(eq, scope, origin) for eq in scodeEql) + @assign instEql = list(instEEquation(eq, scope, origin) for eq in scodeEql) instEql end @@ -2611,7 +2607,7 @@ function instEEquation(scodeEq::SCode.EEquation, scope::InstNode, origin::ORIGIN SCode.EQ_IF(info = info) => begin #= Instantiate the conditions. =# - @assign expl = List(instExp(c, scope, info) for c in scodeEq.condition) + @assign expl = list(instExp(c, scope, info) for c in scodeEq.condition) #= Instantiate each branch and pair it up with a condition. =# @assign next_origin = setFlag(origin, ORIGIN_IF) @@ -2627,7 +2623,7 @@ function instEEquation(scodeEq::SCode.EEquation, scope::InstNode, origin::ORIGIN =# if ! listEmpty(scodeEq.elseBranch) @assign eql = instEEquations(scodeEq.elseBranch, scope, next_origin) - @assign branches = _cons(Equation.makeBranch(P_Expression.Expression.BOOLEAN(true), eql), branches) + @assign branches = _cons(Equation.makeBranch(P_Expression.BOOLEAN_EXPRESSION(true), eql), branches) end Equation.IF(listReverse(branches), makeSource(scodeEq.comment, info)) end diff --git a/src/NewFrontend/NFInstNode.jl b/src/NewFrontend/NFInstNode.jl index b3e6dfa..e25b29d 100644 --- a/src/NewFrontend/NFInstNode.jl +++ b/src/NewFrontend/NFInstNode.jl @@ -77,9 +77,7 @@ Value = InstNode include("../Util/baseAvlTreeCode.jl") include("../Util/baseAvlSetCode.jl") - keyCompare = (inKey1::String, inKey2::String) -> begin - @debug "Calling key compare node tree" res = stringCompare(inKey1, inKey2) return res end @@ -108,8 +106,6 @@ end end end -P_CachedData = CachedData - const NUMBER_OF_CACHES = 3::Integer function setInnerOuterCache(in_caches::Array{<:CachedData}, in_cache::CachedData) ::Array{CachedData} @@ -138,25 +134,28 @@ function getPackageCache(in_caches::Array{<:CachedData}) ::CachedData end function setFuncCache(in_caches::Array{<:CachedData}, in_cache::CachedData) + #@info "Setting func cache with $in_caches and $in_cache" arrayUpdate(in_caches, 1, in_cache) end function getFuncCache(in_caches::Array{<:CachedData}) ::CachedData +# @info in_caches local out_cache::CachedData = arrayGet(in_caches, 1) out_cache end function addFunc(fn::M_Function, specialBuiltin::Bool, caches::Array{<:CachedData}) + @error "ADD FUNC CALLED" local func_cache::CachedData @assign func_cache = getFuncCache(caches) @assign func_cache = begin @match func_cache begin C_NO_CACHE(__) => begin - FUNCTION(list(fn), false, specialBuiltin) + C_FUNCTION(list(fn), false, specialBuiltin) end - FUNCTION(__) => begin - FUNCTION(listAppend(func_cache.funcs, list(fn)), false, func_cache.specialBuiltin || specialBuiltin) + C_FUNCTION(__) => begin + C_FUNCTION(listAppend(func_cache.funcs, list(fn)), false, func_cache.specialBuiltin || specialBuiltin) end _ => begin @@ -172,14 +171,13 @@ end function initFunc(caches::Array{<:CachedData}) local func_cache::CachedData - @assign func_cache = getFuncCache(caches) @assign func_cache = begin @match func_cache begin C_NO_CACHE(__) => begin - FUNCTION(nil, false, false) + C_FUNCTION(nil, false, false) end - FUNCTION(__) => begin + C_FUNCTION(__) => begin func_cache end end @@ -225,26 +223,22 @@ function isModel(node::InstNode) ::Bool isModel end -function isRecord(node::InstNode) ::Bool +function isRecord(@nospecialize(node::InstNode)) ::Bool local isRec::Bool - @assign isRec = begin @match node begin CLASS_NODE(__) => begin - P_Restriction.Restriction.isRecord(restriction(P_Pointer.access(node.cls))) + isRecord(restriction(P_Pointer.access(node.cls))) end - COMPONENT_NODE(__) => begin - isRecord(P_Component.classInstance(P_Pointer.access(node.component))) + isRecord(classInstance(P_Pointer.access(node.component))) end end end isRec end -function copyInstancePtr(srcNode::InstNode, dstNode::InstNode) ::InstNode - - +function copyInstancePtr(@nospecialize(srcNode::InstNode), @nospecialize(dstNode::InstNode)) ::InstNode @assign () = begin @match (srcNode, dstNode) begin (COMPONENT_NODE(__), COMPONENT_NODE(__)) => begin @@ -364,15 +358,12 @@ function toFullDAEType(clsNode::InstNode) ::DAE.Type end function stripDAETypeVars(ty::DAE.Type) ::DAE.Type - - @assign () = begin @match ty begin DAE.Type.T_COMPLEX(__) => begin @assign ty.varLst = nil () end - _ => begin () end @@ -867,17 +858,15 @@ function getPackageCache(inNode::InstNode) ::CachedData end function setFuncCache(node::InstNode, in_func_cache::CachedData) ::InstNode - - @assign () = begin @match node begin CLASS_NODE(__) => begin - P_CachedData.setFuncCache(node.caches, in_func_cache) + setFuncCache(node.caches, in_func_cache) () end - _ => begin - Error.assertion(false, getInstanceName() + " got node without cache", sourceInfo()) + #Error.assertion(false, getInstanceName() + " got node without cache", sourceInfo()) + @error "Error in set func cache" fail() end end @@ -887,13 +876,11 @@ end function getFuncCache(inNode::InstNode) ::CachedData local func_cache::CachedData - @assign func_cache = begin @match inNode begin CLASS_NODE(__) => begin getFuncCache(inNode.caches) end - _ => begin Error.assertion(false, getInstanceName() + " got node without cache", sourceInfo()) fail() @@ -904,15 +891,12 @@ function getFuncCache(inNode::InstNode) ::CachedData end function cacheAddFunc(node::InstNode, fn::M_Function, specialBuiltin::Bool) ::InstNode - - @assign () = begin @match node begin CLASS_NODE(__) => begin - P_CachedData.addFunc(fn, specialBuiltin, node.caches) + addFunc(fn, specialBuiltin, node.caches) () end - _ => begin Error.assertion(false, getInstanceName() + " got node without cache", sourceInfo()) fail() @@ -923,12 +907,10 @@ function cacheAddFunc(node::InstNode, fn::M_Function, specialBuiltin::Bool) ::In end function cacheInitFunc(node::InstNode) ::InstNode - - @assign () = begin @match node begin CLASS_NODE(__) => begin - P_CachedData.initFunc(node.caches) + initFunc(node.caches) () end @@ -1303,11 +1285,11 @@ function componentApply(node::InstNode, func::FuncType, arg::ArgT) where {ArgT} node end -function classApply(node::InstNode, func::FuncType, arg::ArgT) where {ArgT} +function classApply(@nospecialize(node::InstNode), @nospecialize(func::FuncType), arg::ArgT) where {ArgT} @assign () = begin @match node begin CLASS_NODE(__) => begin - P_Pointer.update(node.cls, func(arg, P_P_Pointer.access(node.cls))) + P_Pointer.update(node.cls, func(arg, P_Pointer.access(node.cls))) () end end @@ -1315,17 +1297,16 @@ function classApply(node::InstNode, func::FuncType, arg::ArgT) where {ArgT} node end -function getType(node::InstNode) ::M_Type +function getType(@nospecialize(node::InstNode))::NFType local ty::M_Type - @assign ty = begin @match node begin CLASS_NODE(__) => begin - getType(P_P_Pointer.access(node.cls), node) + getType(P_Pointer.access(node.cls), node) end COMPONENT_NODE(__) => begin - P_Component.getType(P_Pointer.access(node.component)) + getType(P_Pointer.access(node.component)) end end end @@ -1819,47 +1800,39 @@ function className(node::InstNode) ::String name end -function name(node::InstNode) ::String - local name::String - @assign name = begin +function name(@nospecialize(node::InstNode))::String + local nameVar::String + @assign nameVar = begin @match node begin CLASS_NODE(__) => begin node.name end - COMPONENT_NODE(__) => begin node.name end - INNER_OUTER_NODE(__) => begin name(node.innerNode) end - REF_NODE(__) => begin "REF[" + String(node.index) + "]" end - NAME_NODE(__) => begin node.name end - IMPLICIT_SCOPE(__) => begin "IMPLICIT" end - EXP_NODE(__) => begin "EXP(" + toString(node.exp) + ")" end - EMPTY_NODE(__) => begin "EMPTY" end end end - #= For bug catching, these names should never be used. - =# - name + #= For bug catching, these names should never be used. =# + nameVar end function isOperator(node::InstNode) ::Bool @@ -1872,7 +1845,6 @@ function isOperator(node::InstNode) ::Bool INNER_OUTER_NODE(__) => begin isOperator(node.innerNode) end - _ => begin false end diff --git a/src/NewFrontend/NFModifier.jl b/src/NewFrontend/NFModifier.jl index d556536..be547cf 100644 --- a/src/NewFrontend/NFModifier.jl +++ b/src/NewFrontend/NFModifier.jl @@ -100,7 +100,7 @@ function fromElement(element::SCode.Element)::ModifierScope SCode.Element.COMPONENT(__) => begin COMPONENT(element.name) end - SCode.Element.CLASS(__) => begin + SCode.CLASS(__) => begin CLASS(element.name) end SCode.Element.EXTENDS(__) => begin @@ -590,7 +590,7 @@ function stripSCodeMod(elem::SCode.Element)::Tuple{SCode.Element, SCode.Mod} @assign mod = begin local cdef::SCode.ClassDef @match elem begin - SCode.Element.CLASS(classDef = cdef && SCode.ClassDef.DERIVED(modifications = mod)) => begin + SCode.CLASS(classDef = cdef && SCode.ClassDef.DERIVED(modifications = mod)) => begin if !SCodeUtil.isEmptyMod(mod) @assign cdef.modifications = SCode.NOMOD() @assign elem.classDef = cdef diff --git a/src/NewFrontend/NFOCConnectionGraph.jl b/src/NewFrontend/NFOCConnectionGraph.jl index a58e387..59da284 100644 --- a/src/NewFrontend/NFOCConnectionGraph.jl +++ b/src/NewFrontend/NFOCConnectionGraph.jl @@ -64,7 +64,7 @@ P_Operator=P_NFOperator Operator=P_NFOperator.NFOperator import ..P_NFOperator.Op - import ..DAE.Connect + import DAE.Connect import ..P_NFExpression P_Expression=P_NFExpression Expression=P_NFExpression.NFExpression @@ -303,12 +303,12 @@ @assign ty2 = getComponentType(rhsArr) @assign fcref_rhs = P_Function.lookupFunctionSimple("equalityConstraint", classScope(node(lhs))) @assign (fcref_rhs, fn_node_rhs, _) = P_Function.instFunctionRef(fcref_rhs, ElementSource.getInfo(source)) - @assign expRHS = CALL_EXPRESSION(P_Call.UNTYPED_CALL(fcref_rhs, list(CREF_EXPRESSION(ty1, lhsArr), CREF_EXPRESSION(ty2, rhsArr)), nil, fn_node_rhs)) - @assign (expRHS, ty, var) = Typing.typeExp(expRHS, origin, ElementSource.getInfo(source)) + @assign expRHS = CALL_EXPRESSION(UNTYPED_CALL(fcref_rhs, list(CREF_EXPRESSION(ty1, lhsArr), CREF_EXPRESSION(ty2, rhsArr)), nil, fn_node_rhs)) + @assign (expRHS, ty, var) = typeExp(expRHS, origin, ElementSource.getInfo(source)) @assign fcref_lhs = P_Function.lookupFunctionSimple("fill", topScope(node(clhs))) @assign (fcref_lhs, fn_node_lhs, _) = P_Function.instFunctionRef(fcref_lhs, ElementSource.getInfo(source)) - @assign expLHS = CALL_EXPRESSION(P_Call.UNTYPED_CALL(fcref_lhs, _cons(P_Expression.REAL_EXPRESSION(0.0), ListUtil.map(arrayDims(ty), P_Dimension.Dimension.sizeExp)), nil, fn_node_lhs)) - @assign (expLHS, ty, var) = Typing.typeExp(expLHS, origin, ElementSource.getInfo(source)) + @assign expLHS = CALL_EXPRESSION(UNTYPED_CALL(fcref_lhs, _cons(P_Expression.REAL_EXPRESSION(0.0), ListUtil.map(arrayDims(ty), P_Dimension.Dimension.sizeExp)), nil, fn_node_lhs)) + @assign (expLHS, ty, var) = typeExp(expLHS, origin, ElementSource.getInfo(source)) @assign replaceEq = EQUATION_EQUALITY(expRHS, expLHS, ty, source) @assign eqsEqualityConstraint = list(replaceEq) return eqsEqualityConstraint @@ -1227,7 +1227,7 @@ if Flags.isSet(Flags.CGRAPH) print("- NFOCConnectionGraph.evalConnectionsOperatorsHelper: " + toString(exp) + " = false\\n") end - P_Expression.Expression.BOOLEAN(false) + P_Expression.BOOLEAN_EXPRESSION(false) end CREF_EXPRESSION(cref = cref) <| nil() => begin @@ -1260,7 +1260,7 @@ =# #= add an error message: =# - P_Expression.Expression.BOOLEAN(result) + P_Expression.BOOLEAN_EXPRESSION(result) end end end @@ -1276,7 +1276,7 @@ if Flags.isSet(Flags.CGRAPH) print("- NFOCConnectionGraph.evalConnectionsOperatorsHelper: " + toString(exp) + " = false\\n") end - P_Expression.Expression.BOOLEAN(false) + P_Expression.BOOLEAN_EXPRESSION(false) end CREF_EXPRESSION(cref = cref) <| nil() => begin @@ -1284,7 +1284,7 @@ if Flags.isSet(Flags.CGRAPH) print("- NFOCConnectionGraph.evalConnectionsOperatorsHelper: " + toString(exp) + " = " + boolString(result) + "\\n") end - P_Expression.Expression.BOOLEAN(result) + P_Expression.BOOLEAN_EXPRESSION(result) end end end diff --git a/src/NewFrontend/NFPackage.jl b/src/NewFrontend/NFPackage.jl index 4db1828..1591e45 100644 --- a/src/NewFrontend/NFPackage.jl +++ b/src/NewFrontend/NFPackage.jl @@ -87,14 +87,14 @@ function collectExpConstants(exp::Expression, constants::Constants)::Constants return constants end -function collectExpConstants_traverser(exp::Expression, constants::Constants)::Constants +function collectExpConstants_traverser(@nospecialize(exp::Expression), @nospecialize(constants::Constants))::Constants local cref::ComponentRef @assign () = begin @match exp begin CREF_EXPRESSION(cref = cref && CREF_EXPRESSION(__)) => begin if isPackageConstant(cref) - Typing.typeComponentBinding(cref.node, ExpOrigin.CLASS) + typeComponentBinding(cref.node, ORIGIN_CLASS) @assign constants = Constants.add( constants, stripSubscriptsAll(cref), diff --git a/src/NewFrontend/NFRangeIterator.jl b/src/NewFrontend/NFRangeIterator.jl index 5a274f3..6c982ee 100644 --- a/src/NewFrontend/NFRangeIterator.jl +++ b/src/NewFrontend/NFRangeIterator.jl @@ -165,8 +165,8 @@ function fromDim(dim::Dimension)::RangeIterator P_Dimension.Dimension.BOOLEAN(__) => begin ARRAY_RANGE(list( - P_Expression.Expression.BOOLEAN(false), - P_Expression.Expression.BOOLEAN(true), + P_Expression.BOOLEAN_EXPRESSION(false), + P_Expression.BOOLEAN_EXPRESSION(true), )) end diff --git a/src/NewFrontend/NFRecord.jl b/src/NewFrontend/NFRecord.jl index 50631e7..019d83d 100644 --- a/src/NewFrontend/NFRecord.jl +++ b/src/NewFrontend/NFRecord.jl @@ -79,8 +79,8 @@ function instDefaultConstructor( @assign out_comp = P_Component.UNTYPED_COMPONENT( ctor_node, listArray(nil), - NFBinding.EMPTY_BINDING, - NFBinding.EMPTY_BINDING, + EMPTY_BINDING, + EMPTY_BINDING, NFComponent.OUTPUT_ATTR, NONE(), false, diff --git a/src/NewFrontend/NFSimplifyExp.jl b/src/NewFrontend/NFSimplifyExp.jl index aa2653a..8eefcd4 100644 --- a/src/NewFrontend/NFSimplifyExp.jl +++ b/src/NewFrontend/NFSimplifyExp.jl @@ -150,7 +150,7 @@ function simplifyCall(callExp::Expression)::Expression @match CALL_EXPRESSION(call = call) = callExp @assign callExp = begin @match call begin - P_Call.TYPED_CALL(arguments = args) where {(!P_Call.isExternal(call))} => begin + TYPED_CALL(arguments = args) where {(!isExternal(call))} => begin if Flags.isSet(Flags.NF_EXPAND_FUNC_ARGS) @assign args = list(if P_Expression.Expression.hasArrayCall(arg) arg @@ -163,7 +163,7 @@ function simplifyCall(callExp::Expression)::Expression if Flags.isSet(Flags.NF_API) && !Flags.isSet(Flags.NF_API_DYNAMIC_SELECT) if stringEq( "DynamicSelect", - AbsynUtil.pathString(P_Function.nameConsiderBuiltin(call.fn)), + AbsynUtil.pathString(nameConsiderBuiltin(call.fn)), ) @assign callExp = simplify(listHead(args)) return @@ -185,7 +185,7 @@ function simplifyCall(callExp::Expression)::Expression else if Flags.isSet(Flags.NF_SCALARIZE) @assign callExp = - simplifyBuiltinCall(P_Function.nameConsiderBuiltin(call.fn), args, call) + simplifynameConsiderBuiltin(call.fn, args, call) end end elseif Flags.isSet(Flags.NF_EVAL_CONST_ARG_FUNCS) && @@ -202,11 +202,11 @@ function simplifyCall(callExp::Expression)::Expression callExp end - P_Call.TYPED_ARRAY_CONSTRUCTOR(__) => begin + TYPED_ARRAY_CONSTRUCTOR(__) => begin simplifyArrayConstructor(call) end - P_Call.TYPED_REDUCTION(__) => begin + TYPED_REDUCTION(__) => begin @assign call.exp = simplify(call.exp) @assign call.iters = list((Util.tuple21(i), simplify(Util.tuple22(i))) for i in call.iters) @@ -233,7 +233,7 @@ function simplifyCall2(call::Call)::Expression if Flags.isSet(Flags.FAILTRACE) ErrorExt.delCheckpoint(getInstanceName()) Debug.traceln( - "- " + getInstanceName() + " failed to evaluate " + P_Call.toString(call) + "\\n", + "- " + getInstanceName() + " failed to evaluate " + toString(call) + "\\n", ) else ErrorExt.rollBack(getInstanceName()) @@ -243,7 +243,7 @@ function simplifyCall2(call::Call)::Expression return outExp end -function simplifyBuiltinCall( +function simplify( name::Absyn.Path, args::List{<:Expression}, call::Call, @@ -351,7 +351,7 @@ function simplifyArrayConstructor(call::Call)::Expression local dim_size::Integer local expanded::Bool - @match P_Call.TYPED_ARRAY_CONSTRUCTOR(ty, var, exp, iters) = call + @match TYPED_ARRAY_CONSTRUCTOR(ty, var, exp, iters) = call @assign iters = list((Util.tuple21(i), simplify(Util.tuple22(i))) for i in iters) @assign outExp = begin @matchcontinue iters begin @@ -378,7 +378,7 @@ function simplifyArrayConstructor(call::Call)::Expression _ => begin @assign exp = simplify(exp) - CALL_EXPRESSION(P_Call.TYPED_ARRAY_CONSTRUCTOR(ty, var, exp, iters)) + CALL_EXPRESSION(TYPED_ARRAY_CONSTRUCTOR(ty, var, exp, iters)) end end end @@ -677,19 +677,19 @@ function simplifyLogicBinaryAnd( #= false and e => false =# @match (exp1, exp2) begin - (P_Expression.Expression.BOOLEAN(false), _) => begin + (P_Expression.BOOLEAN_EXPRESSION(false), _) => begin exp1 end - (_, P_Expression.Expression.BOOLEAN(false)) => begin + (_, P_Expression.BOOLEAN_EXPRESSION(false)) => begin exp2 end - (P_Expression.Expression.BOOLEAN(true), _) => begin + (P_Expression.BOOLEAN_EXPRESSION(true), _) => begin exp2 end - (_, P_Expression.Expression.BOOLEAN(true)) => begin + (_, P_Expression.BOOLEAN_EXPRESSION(true)) => begin exp1 end @@ -726,19 +726,19 @@ function simplifyLogicBinaryOr(exp1::Expression, op::Operator, exp2::Expression) #= true or e => true =# @match (exp1, exp2) begin - (P_Expression.Expression.BOOLEAN(true), _) => begin + (P_Expression.BOOLEAN_EXPRESSION(true), _) => begin exp1 end - (_, P_Expression.Expression.BOOLEAN(true)) => begin + (_, P_Expression.BOOLEAN_EXPRESSION(true)) => begin exp2 end - (P_Expression.Expression.BOOLEAN(false), _) => begin + (P_Expression.BOOLEAN_EXPRESSION(false), _) => begin exp2 end - (_, P_Expression.Expression.BOOLEAN(false)) => begin + (_, P_Expression.BOOLEAN_EXPRESSION(false)) => begin exp1 end @@ -813,7 +813,7 @@ function simplifyIf(ifExp::Expression)::Expression @assign cond = simplify(cond) @assign ifExp = begin @match cond begin - P_Expression.Expression.BOOLEAN(__) => begin + P_Expression.BOOLEAN_EXPRESSION(__) => begin simplify(if cond.value tb else diff --git a/src/NewFrontend/NFSimplifyModel.jl b/src/NewFrontend/NFSimplifyModel.jl index 5a36601..5d62e02 100644 --- a/src/NewFrontend/NFSimplifyModel.jl +++ b/src/NewFrontend/NFSimplifyModel.jl @@ -385,21 +385,18 @@ function removeEmptyTupleElements(exp::Expression)::Expression return exp end -function removeEmptyFunctionArguments(exp::Expression, isArg::Bool = false)::Expression +function removeEmptyFunctionArguments(@nospecialize(exp::Expression), isArg::Bool = false)::Expression local outExp::Expression - local is_arg::Bool - if isArg @assign () = begin @match exp begin - CREF_EXPRESSION(__) where {(Type.isEmptyArray(exp.ty))} => begin + CREF_EXPRESSION(__) where {(isEmptyArray(exp.ty))} => begin @assign outExp = - P_Expression.Expression.fillType(exp.ty, INTEGER_EXPRESSION(0)) + fillType(exp.ty, INTEGER_EXPRESSION(0)) return () end - _ => begin () end diff --git a/src/NewFrontend/NFStatement.jl b/src/NewFrontend/NFStatement.jl index 0b44e00..edee783 100644 --- a/src/NewFrontend/NFStatement.jl +++ b/src/NewFrontend/NFStatement.jl @@ -62,7 +62,7 @@ @Record ALG_ASSIGNMENT begin lhs::Expression #= The asignee =# rhs::Expression #= The expression =# - ty::M_Type + ty::NFType source::DAE.ElementSource end end @@ -803,7 +803,7 @@ function instStatement(scodeStmt::SCode.Statement, scope::InstNode, origin::ORIG end if ! listEmpty(scodeStmt.elseBranch) @assign stmtl = instStatements(scodeStmt.elseBranch, scope, next_origin) - @assign branches = _cons((P_Expression.Expression.BOOLEAN(true), stmtl), branches) + @assign branches = _cons((P_Expression.BOOLEAN_EXPRESSION(true), stmtl), branches) end ALG_IF(listReverse(branches), makeSource(scodeStmt.comment, info)) end diff --git a/src/NewFrontend/NFSubscript.jl b/src/NewFrontend/NFSubscript.jl index b3d2d91..f51dbba 100644 --- a/src/NewFrontend/NFSubscript.jl +++ b/src/NewFrontend/NFSubscript.jl @@ -64,7 +64,7 @@ function fromExp(exp::Expression)::Subscript INDEX(exp) end - P_Expression.Expression.BOOLEAN(__) => begin + P_Expression.BOOLEAN_EXPRESSION(__) => begin INDEX(exp) end @@ -81,7 +81,7 @@ function fromExp(exp::Expression)::Subscript end function isValidIndexType(ty::M_Type)::Bool - local b::Bool = Type.isInteger(ty) || Type.isBoolean(ty) || Type.isEnumeration(ty) + local b::Bool = isInteger(ty) || Type.isBoolean(ty) || Type.isEnumeration(ty) return b end @@ -95,7 +95,7 @@ function first(dim::Dimension)::Subscript end P_Dimension.Dimension.BOOLEAN(__) => begin - INDEX(P_Expression.Expression.BOOLEAN(false)) + INDEX(P_Expression.BOOLEAN_EXPRESSION(false)) end P_Dimension.Dimension.ENUM(__) => begin diff --git a/src/NewFrontend/NFType.jl b/src/NewFrontend/NFType.jl index 2c70f3f..4e64881 100644 --- a/src/NewFrontend/NFType.jl +++ b/src/NewFrontend/NFType.jl @@ -299,7 +299,7 @@ function isEqual(ty1::M_Type, ty2::M_Type)::Bool isEqual(ty1.elementType, ty2.elementType) && ListUtil.isEqualOnTrue( ty1.dimensions, ty2.dimensions, - P_Dimension.Dimension.isEqualKnown, + isEqualKnown, ) end @@ -778,23 +778,19 @@ function dimensionDiff(ty1::M_Type, ty2::M_Type)::Integer return diff end -function dimensionCount(ty::M_Type)::Integer +function dimensionCount(@nospecialize(ty::NFType))::Integer local dimCount::Integer - @assign dimCount = begin @match ty begin - ARRAY(__) => begin + TYPE_ARRAY(__) => begin listLength(ty.dimensions) end - TYPE_FUNCTION(__) => begin - dimensionCount(P_Function.returnType(ty.fn)) + dimensionCount(returnType(ty.fn)) end - TYPE_METABOXED(__) => begin dimensionCount(ty.ty) end - _ => begin 0 end @@ -1020,10 +1016,9 @@ function isTuple(ty::M_Type)::Bool @assign isTuple = begin @match ty begin - TUPLE(__) => begin + TYPE_TUPLE(__) => begin true end - _ => begin false end @@ -1316,7 +1311,7 @@ function isSquareMatrix(ty::M_Type)::Bool local d2::Dimension @match ty begin TYPE_ARRAY(dimensions = d1 <| d2 <| nil()) => begin - P_Dimension.Dimension.isEqualKnown(d1, d2) + isEqualKnown(d1, d2) end _ => begin diff --git a/src/NewFrontend/NFTypeCheck.jl b/src/NewFrontend/NFTypeCheck.jl index bf67148..e411f26 100644 --- a/src/NewFrontend/NFTypeCheck.jl +++ b/src/NewFrontend/NFTypeCheck.jl @@ -570,7 +570,7 @@ function checkOverloadedBinaryArrayMul( (dim11 <| dim12 <| nil(), dim21 <| nil()) => begin #= matrix[n, m] * vector[m] = vector[n] =# - @assign valid = P_Dimension.Dimension.isEqual(dim12, dim21) + @assign valid = isEqual(dim12, dim21) #= TODO: Implement me! =# @assign outExp = BINARY_EXPRESSION(exp1, op, exp2) @@ -581,7 +581,7 @@ function checkOverloadedBinaryArrayMul( (dim11 <| dim12 <| nil(), dim21 <| dim22 <| nil()) => begin #= matrix[n, m] * matrix[m, p] = vector[n, p] =# - @assign valid = P_Dimension.Dimension.isEqual(dim12, dim21) + @assign valid = isEqual(dim12, dim21) #= TODO: Implement me! =# @assign outExp = BINARY_EXPRESSION(exp1, op, exp2) @@ -1565,28 +1565,28 @@ function checkBinaryOperationMul( =# #= vector[n] * vector[n] = scalar =# - @assign valid = P_Dimension.Dimension.isEqual(dim11, dim21) + @assign valid = isEqual(dim11, dim21) (resultType, Op.SCALAR_PRODUCT) end (dim11 <| nil(), dim21 <| dim22 <| nil()) => begin #= vector[n] * matrix[n, m] = vector[m] =# - @assign valid = P_Dimension.Dimension.isEqual(dim11, dim21) + @assign valid = isEqual(dim11, dim21) (ARRAY_TYPE(resultType, list(dim22)), Op.MUL_VECTOR_MATRIX) end (dim11 <| dim12 <| nil(), dim21 <| nil()) => begin #= matrix[n, m] * vector[m] = vector[n] =# - @assign valid = P_Dimension.Dimension.isEqual(dim12, dim21) + @assign valid = isEqual(dim12, dim21) (ARRAY_TYPE(resultType, list(dim11)), Op.MUL_MATRIX_VECTOR) end (dim11 <| dim12 <| nil(), dim21 <| dim22 <| nil()) => begin #= matrix[n, m] * matrix[m, p] = vector[n, p] =# - @assign valid = P_Dimension.Dimension.isEqual(dim12, dim21) + @assign valid = isEqual(dim12, dim21) (ARRAY_TYPE(resultType, list(dim11, dim22)), Op.MATRIX_PRODUCT) end @@ -1699,7 +1699,7 @@ function checkBinaryOperationPow( @assign valid = isCompatibleMatch(mk) if isArray(resultType) @assign valid = valid && Type.isSquareMatrix(resultType) - @assign valid = valid && Type.isInteger(type2) + @assign valid = valid && isInteger(type2) @assign op = OPERATOR(resultType, Op.POW_MATRIX) @assign e2 = exp2 else @@ -2083,7 +2083,7 @@ function checkRelationOperation( #= Print a warning for == or <> with Real operands in a model. =# @assign o = operator.op - if ExpOrigin.flagNotSet(origin, ExpOrigin.FUNCTION) && + if ExpOrigin.flagNotSet(origin, ORIGIN_FUNCTION) && (o == Op.EQUAL || o == Op.NEQUAL) Error.addStrictMessage( Error.WARNING_RELATION_ON_REAL, @@ -3398,7 +3398,7 @@ function matchExpressions_cast( =# #= tuple is used. exp1 should never be a tuple here, since any tuple expression =# - #= not alone on the rhs of an equation is \"tuple subscripted\" by Typing.typeExp. + #= not alone on the rhs of an equation is \"tuple subscripted\" by typeExp. =# @assign exp2 = P_Expression.Expression.tupleElement(exp2, compatibleType, 1) @assign (exp2, compatibleType, matchKind) = @@ -3850,7 +3850,7 @@ function matchDimensions( local compatible::Bool local compatibleDim::Dimension - if P_Dimension.Dimension.isEqual(dim1, dim2) + if isEqual(dim1, dim2) @assign compatibleDim = dim1 @assign compatible = true else @@ -4310,7 +4310,7 @@ function getRangeTypeBool(startExp::Expression, stopExp::Expression)::Dimension local dim_exp::Expression local var::VariabilityType @match (startExp, stopExp) begin - (P_Expression.Expression.BOOLEAN(__), P_Expression.Expression.BOOLEAN(__)) => begin + (P_Expression.BOOLEAN_EXPRESSION(__), P_Expression.BOOLEAN_EXPRESSION(__)) => begin @assign sz = if startExp.value == stopExp.value 1 elseif (startExp.value < stopExp.value) @@ -4529,7 +4529,7 @@ end """ #= Checks that an expression used as a dimension has a valid type for a dimension, otherwise prints an error and fails. =#""" function checkDimensionType(exp::Expression, ty::NFType, info::SourceInfo) - return if !Type.isInteger(ty) + return if !isInteger(ty) @assign () = begin @match exp begin P_Expression.Expression.TYPENAME(ty = ARRAY_TYPE(elementType = TYPE_BOOLEAN(__))) => begin diff --git a/src/NewFrontend/NFTyping.jl b/src/NewFrontend/NFTyping.jl index 98c81b7..02ad716 100644 --- a/src/NewFrontend/NFTyping.jl +++ b/src/NewFrontend/NFTyping.jl @@ -40,6 +40,8 @@ Subscript = NFSubscript ComplexType = NFComplexType Restriction = NFRestriction +@nospecialize + @UniontypeDecl TypingError function isError(error::TypingError)::Bool local isError::Bool @@ -163,10 +165,10 @@ function flagNotSet(origin::M_Type, flag::M_Type)::Bool return notSet end -function typeClass(cls::InstNode, name::String) +function typeClass(@nospecialize(cls::InstNode), name::String) typeClassType(cls, EMPTY_BINDING, ORIGIN_CLASS, cls) typeComponents(cls, ORIGIN_CLASS) -# execStat("NFTyping.typeComponents(" + name + ")") +# execStat("NFtypeComponents(" + name + ")") typeBindings(cls, cls, ORIGIN_CLASS) # execStat("NFTyping.typeBindings(" + name + ")") typeClassSections(cls, ORIGIN_CLASS) @@ -174,7 +176,7 @@ function typeClass(cls::InstNode, name::String) return end -function typeComponents(cls::InstNode, origin::ORIGIN_Type) +function typeComponents(@nospecialize(cls::InstNode), origin::ORIGIN_Type) local c::Class = getClass(cls) local c2::Class local cls_tree::ClassTree @@ -521,7 +523,7 @@ function checkComponentStreamAttribute( return if isFlowOrStream(cty) @assign ety = arrayElementType(ty) - if !(Type.isReal(ety) || isComplex(ety)) + if !(isReal(ety) || isComplex(ety)) Error.addSourceMessageAndFail( Error.NON_REAL_FLOW_OR_STREAM, list(ConnectorType.toString(cty), name(component)), @@ -1339,16 +1341,23 @@ function typeTypeAttribute( return attribute end +function typeExp( + @nospecialize(exp::Expression), + @nospecialize(origin::ORIGIN_Type), + @nospecialize(info::SourceInfo), +)::Tuple{Expression, NFType, VariabilityType} + typeExp2(exp, origin, info) +end + """ #= Types an untyped expression, returning the typed expression itself along with its type and variability. =#""" -function typeExp( - exp::Expression, - origin::ORIGIN_Type, - info::SourceInfo, +function typeExp2( + @nospecialize(exp::Expression), + @nospecialize(origin::ORIGIN_Type), + @nospecialize(info::SourceInfo), )::Tuple{Expression, NFType, VariabilityType} local variability::VariabilityType local ty::NFType - @assign (exp, ty, variability) = begin local e1::Expression local e2::Expression @@ -1363,30 +1372,12 @@ function typeExp( local cref::ComponentRef local next_origin::ORIGIN_Type @match exp begin - INTEGER_EXPRESSION(__) => begin - (exp, TYPE_INTEGER(), Variability.CONSTANT) - end - - REAL_EXPRESSION(__) => begin - (exp, TYPE_REAL(), Variability.CONSTANT) - end - - STRING_EXPRESSION(__) => begin - (exp, TYPE_STRING(), Variability.CONSTANT) - end - - BOOLEAN_EXPRESSION(__) => begin - (exp, TYPE_BOOLEAN(), Variability.CONSTANT) - end - - ENUM_LITERAL_EXPRESSION(__) => begin - (exp, exp.ty, Variability.CONSTANT) - end - - CREF_EXPRESSION(__) => begin - typeCrefExp(exp.cref, origin, info) - end - + INTEGER_EXPRESSION(__) => (exp, TYPE_INTEGER(), Variability.CONSTANT) + REAL_EXPRESSION(__) => (exp, TYPE_REAL(), Variability.CONSTANT) + STRING_EXPRESSION(__) => (exp, TYPE_STRING(), Variability.CONSTANT) + BOOLEAN_EXPRESSION(__) => (exp, TYPE_BOOLEAN(), Variability.CONSTANT) + ENUM_LITERAL_EXPRESSION(__) => (exp, exp.ty, Variability.CONSTANT) + CREF_EXPRESSION(__) => typeCrefExp(exp.cref, origin, info) TYPENAME_EXPRESSION(__) => begin if flagNotSet(origin, ORIGIN_VALID_TYPENAME_SCOPE) Error.addSourceMessage( @@ -1398,119 +1389,60 @@ function typeExp( end (exp, exp.ty, Variability.CONSTANT) end - - ARRAY_EXPRESSION(__) => begin - typeArray(exp.elements, origin, info) - end - - MATRIX_EXPRESSION(__) => begin - typeMatrix(exp.elements, origin, info) - end - - RANGE_EXPRESSION(__) => begin - typeRange(exp, origin, info) - end - - TUPLE_EXPRESSION(__) => begin - typeTuple(exp.elements, origin, info) - end - - SIZE_EXPRESSION(__) => begin - typeSize(exp, origin, info) - end - + ARRAY_EXPRESSION(__) => typeArray(exp.elements, origin, info) + MATRIX_EXPRESSION(__) => typeMatrix(exp.elements, origin, info) + RANGE_EXPRESSION(__) => typeRange(exp, origin, info) + TUPLE_EXPRESSION(__) => typeTuple(exp.elements, origin, info) + SIZE_EXPRESSION(__) => typeSize(exp, origin, info) END_EXPRESSION(__) => begin - #= end is replaced in subscripts before we get here, so any end still - =# - #= left should be outside a subscript and thus illegal. - =# Error.addSourceMessage(Error.END_ILLEGAL_USE_ERROR, nil, info) fail() end - - BINARY_EXPRESSION(__) => begin - @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) - @assign (e1, ty1, var1) = typeExp(exp.exp1, next_origin, info) - @assign (e2, ty2, var2) = typeExp(exp.exp2, next_origin, info) - @assign (exp, ty) = checkBinaryOperation( - e1, - ty1, - var1, - exp.operator, - e2, - ty2, - var2, - info, - ) - (exp, ty, variabilityMax(var1, var2)) - end - - UNARY_EXPRESSION(__) => begin - @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) - @assign (e1, ty1, var1) = typeExp(exp.exp, next_origin, info) - @assign (exp, ty) = - checkUnaryOperation(e1, ty1, var1, exp.operator, info) - (exp, ty, var1) - end - - LBINARY_EXPRESSION(__) => begin - @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) - @assign (e1, ty1, var1) = typeExp(exp.exp1, next_origin, info) - @assign (e2, ty2, var2) = typeExp(exp.exp2, next_origin, info) - @assign (exp, ty) = checkLogicalBinaryOperation( - e1, - ty1, - var1, - exp.operator, - e2, - ty2, - var2, - info, - ) - (exp, ty, variabilityMax(var1, var2)) - end - - LUNARY_EXPRESSION(__) => begin - @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) - @assign (e1, ty1, var1) = typeExp(exp.exp, next_origin, info) - @assign (exp, ty) = - checkLogicalUnaryOperation(e1, ty1, var1, exp.operator, info) - (exp, ty, var1) - end - - RELATION_EXPRESSION(__) => begin - @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) - @assign (e1, ty1, var1) = typeExp(exp.exp1, next_origin, info) - @assign (e2, ty2, var2) = typeExp(exp.exp2, next_origin, info) - @assign (exp, ty) = checkRelationOperation( - e1, - ty1, - var1, - exp.operator, - e2, - ty2, - var2, - origin, - info, - ) - @assign variability = variabilityMax(var1, var2) - #= A relation involving continuous expressions which is not inside - =# - #= noEvent is a discrete expression. - =# - if flagNotSet(origin, ORIGIN_NOEVENT) && - variability == Variability.CONTINUOUS - @assign variability = Variability.DISCRETE - end - (exp, ty, variability) - end - - IF_EXPRESSION(__) => begin - typeIfExpression(exp, origin, info) - end + BINARY_EXPRESSION(__) => typeBinaryExpression(exp, origin, info) + UNARY_EXPRESSION(__) => typeUnaryExpression(exp, origin, info) + LBINARY_EXPRESSION(__) => typeLBinaryExpression(exp, origin, info) + + # LUNARY_EXPRESSION(__) => begin + # @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) + # @assign (e1, ty1, var1) = typeExp(exp.exp, next_origin, info) + # @assign (exp, ty) = + # checkLogicalUnaryOperation(e1, ty1, var1, exp.operator, info) + # (exp, ty, var1) + # end + + # RELATION_EXPRESSION(__) => begin + # @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) + # @assign (e1, ty1, var1) = typeExp(exp.exp1, next_origin, info) + # @assign (e2, ty2, var2) = typeExp(exp.exp2, next_origin, info) + # @assign (exp, ty) = checkRelationOperation( + # e1, + # ty1, + # var1, + # exp.operator, + # e2, + # ty2, + # var2, + # origin, + # info, + # ) + # @assign variability = variabilityMax(var1, var2) + # #= A relation involving continuous expressions which is not inside + # =# + # #= noEvent is a discrete expression. + # =# + # if flagNotSet(origin, ORIGIN_NOEVENT) && + # variability == Variability.CONTINUOUS + # @assign variability = Variability.DISCRETE + # end + # (exp, ty, variability) + # end + + # IF_EXPRESSION(__) => begin + # typeIfExpression(exp, origin, info) + # end CALL_EXPRESSION(__) => begin - @assign (e1, ty, var1) = typeCall(exp, origin, info) + (e1, ty, var1) = typeCall(exp, origin, info) #= If the call has multiple outputs and isn't alone on either side of an =# #= equation/algorithm, select the first output. @@ -1527,34 +1459,26 @@ function typeExp( typeExp(exp.exp, next_origin, info) end - SUBSCRIPTED_EXP_EXPRESSION(__) => begin - (exp, exp.ty, variability(exp)) - end + # SUBSCRIPTED_EXP_EXPRESSION(__) => begin + # (exp, exp.ty, variability(exp)) + # end - MUTABLE_EXPRESSION(__) => begin - #= Subscripted expressions are assumed to already be typed. - =# - @assign e1 = P_Pointer.access(exp.exp) - @assign (e1, ty, variability) = typeExp(e1, origin, info) - @assign exp.exp = P_Pointer.create(e1) - (exp, ty, variability) - end + # MUTABLE_EXPRESSION(__) => begin + # #= Subscripted expressions are assumed to already be typed. + # =# + # @assign e1 = P_Pointer.access(exp.exp) + # @assign (e1, ty, variability) = typeExp(e1, origin, info) + # @assign exp.exp = P_Pointer.create(e1) + # (exp, ty, variability) + # end - PARTIAL_FUNCTION_APPLICATION_EXPRESSION(__) => begin - typePartialApplication(exp, origin, info) - end + # PARTIAL_FUNCTION_APPLICATION_EXPRESSION(__) => begin + # typePartialApplication(exp, origin, info) + # end - BINDING_EXP(__) => begin - typeBindingExp(exp, origin, info) - end - _ => begin - # Error.assertion( - # false, - # getInstanceName() + - # " got unknown expression: " + - # toString(exp), - # sourceInfo(), - # ) + BINDING_EXP(__) => typeBindingExp(exp, origin, info) +_ => begin + @info "Attempted to type" fail() end end @@ -1568,10 +1492,64 @@ function typeExp( return (exp, ty, variability) end +function typeBinaryExpression( + @nospecialize(exp::Expression), + @nospecialize(origin::ORIGIN_Type), + @nospecialize(info::SourceInfo),)::Tuple{Expression, NFType, VariabilityType} + @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) + @assign (e1, ty1, var1) = typeExp(exp.exp1, next_origin, info) + @assign (e2, ty2, var2) = typeExp(exp.exp2, next_origin, info) + @assign (exp, ty) = checkBinaryOperation( + e1, + ty1, + var1, + exp.operator, + e2, + ty2, + var2, + info, + ) + (exp, ty, variabilityMax(var1, var2)) +end + + +function typeLBinaryExpression( + @nospecialize(exp::Expression), + @nospecialize(origin::ORIGIN_Type), + @nospecialize(info::SourceInfo),)::Tuple{Expression, NFType, VariabilityType} + + @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) + @assign (e1, ty1, var1) = typeExp(exp.exp1, next_origin, info) + @assign (e2, ty2, var2) = typeExp(exp.exp2, next_origin, info) + @assign (exp, ty) = checkLogicalBinaryOperation( + e1, + ty1, + var1, + exp.operator, + e2, + ty2, + var2, + info, + ) + (exp, ty, variabilityMax(var1, var2)) +end + + +function typeUnaryExpression( + @nospecialize(exp::Expression), + @nospecialize(origin::ORIGIN_Type), + @nospecialize(info::SourceInfo),)::Tuple{Expression, NFType, VariabilityType} + @assign next_origin = setFlag(origin, ORIGIN_SUBEXPRESSION) + @assign (e1, ty1, var1) = typeExp(exp.exp, next_origin, info) + @assign (exp, ty) = + checkUnaryOperation(e1, ty1, var1, exp.operator, info) + (exp, ty, var1) +end + function typeExpl( - expl::List{<:Expression}, - origin::ORIGIN_Type, - info::SourceInfo, + @nospecialize(expl::List{<:Expression}), + @nospecialize(origin::ORIGIN_Type), + @nospecialize(info::SourceInfo), )::Tuple{List{Expression}, List{M_Type}, List{Variability}} local varl::List{Variability} = nil local tyl::List{M_Type} = nil @@ -1591,8 +1569,8 @@ function typeExpl( end function typeBindingExp( - exp::Expression, - origin::ORIGIN_Type, + @nospecialize(exp::Expression), + @nospecialize(origin::ORIGIN_Type), info::SourceInfo, )::Tuple{Expression, M_Type, VariabilityType} local variability::VariabilityType @@ -1610,7 +1588,7 @@ function typeBindingExp( @assign parent_dims = 0 if !is_each for p in listRest(parents) - @assign parent_dims = parent_dims + Type.dimensionCount(getType(p)) + @assign parent_dims = parent_dims + dimensionCount(getType(p)) end end if parent_dims == 0 @@ -1633,7 +1611,7 @@ end the given index doesn't refer to a valid dimension, in which case the returned dimension is undefined. =#""" function typeExpDim( - exp::Expression, + @nospecialize(exp::Expression), dimIndex::Integer, origin::ORIGIN_Type, info::SourceInfo, @@ -1872,7 +1850,7 @@ function nthDimensionBoundsChecked( end function typeCrefExp( - cref::ComponentRef, + @nospecialize(cref::ComponentRef), o::ORIGIN_Type, info::SourceInfo, )::Tuple{Expression, NFType, VariabilityType} @@ -1890,7 +1868,7 @@ function typeCrefExp( end function typeCref( - cref::ComponentRef, + @nospecialize(cref::ComponentRef), origin::ORIGIN_Type, info::SourceInfo )::Tuple{ComponentRef, NFType, VariabilityType, VariabilityType} @@ -2227,7 +2205,7 @@ function typeMatrix( @assign res = _cons(e, res) end @assign (arrayExp, arrayType) = - BuiltinCall.makeCatExp(1, res, resTys, variability, info) + makeCatExp(1, res, resTys, variability, info) else @assign (arrayExp, arrayType, variability) = typeMatrixComma(listHead(elements), next_origin, info) @@ -2316,7 +2294,7 @@ function typeMatrixComma( @assign res = _cons(e, res) @assign tys2 = _cons(ty3, tys2) end - @assign (arrayExp, arrayType) = BuiltinCall.makeCatExp(2, res, tys2, variability, info) + @assign (arrayExp, arrayType) = makeCatExp(2, res, tys2, variability, info) else @assign (arrayExp, arrayType, variability) = typeExp(listHead(elements), origin, info) end @@ -2539,28 +2517,6 @@ function typeSize( end @assign exp = SIZE_EXPRESSION(exp, SOME(index)) end - #= Evaluate the index if it's a constant. - =# - #= TODO: Print an error if the index couldn't be evaluated to an int. - =# - #= Get the iindex'd dimension of the expression. - =# - #= If the dimension size is known, return its size. - =# - #= If the dimension size is unknown (e.g. in a function) or - =# - #= evaluation is disabled, return a size expression instead. - =# - #= size is constant outside functions, or for known dimensions inside functions. - =# - #= size is discrete for : in functions. - =# - #= If the index is not a constant, type the whole expression. - =# - #= Check that it's an array. - =# - #= Since we don't know which dimension to take the size of, return a size expression. - =# (exp, TYPE_INTEGER(), variability) end @@ -2576,7 +2532,7 @@ end function checkSizeTypingError( typingError::TypingError, - exp::Expression, + @nospecialize(exp::Expression), index::Integer, info::SourceInfo, ) @@ -2612,7 +2568,7 @@ function checkSizeTypingError( end function evaluateEnd( - exp::Expression, + @nospecialize(exp::Expression), dim::Dimension, cref::ComponentRef, index::Integer, @@ -2759,7 +2715,7 @@ function evaluateCondition( end @assign condBool = begin @match cond_exp begin - P_Expression.Expression.BOOLEAN(__) => begin + BOOLEAN_EXPRESSION(__) => begin cond_exp.value end @@ -2874,9 +2830,8 @@ function typeFunctionSections(classNode::InstNode, origin::ORIGIN_Type) local sections::Sections local info::SourceInfo local alg::Algorithm - @assign cls = getClass(classNode) - return @assign _ = begin + begin @match cls begin INSTANCED_CLASS(sections = sections) => begin @assign sections = begin @@ -2907,7 +2862,7 @@ function typeFunctionSections(classNode::InstNode, origin::ORIGIN_Type) fail() end - EXTERNAL(explicit = true) => begin + SECTIONS_EXTERNAL(explicit = true) => begin @assign info = info(classNode) @assign sections.args = List(typeExternalArg(arg, info, classNode) for arg in sections.args) @@ -2915,10 +2870,13 @@ function typeFunctionSections(classNode::InstNode, origin::ORIGIN_Type) sections end - EXTERNAL(__) => begin - makeDefaultExternalCall(sections, classNode) + SECTIONS_EXTERNAL(__) => begin + r = makeDefaultExternalCall(sections, classNode) + if r == SECTIONS_EMPTY() + return + end + r end - _ => begin sections end @@ -3009,7 +2967,6 @@ end otherwise a call 'func(param1, param2, ...)' is generated from the function's formal parameters and local variables. =#""" function makeDefaultExternalCall(extDecl::Sections, fnNode::InstNode)::Sections - @assign extDecl = begin local args::List{Expression} local output_ref::ComponentRef @@ -3021,11 +2978,11 @@ function makeDefaultExternalCall(extDecl::Sections, fnNode::InstNode)::Sections local node::InstNode local exp::Expression @match extDecl begin - EXTERNAL(__) => begin + SECTIONS_EXTERNAL(__) => begin #= An explicit function call isn't needed for builtin calls. =# if extDecl.language == "builtin" - return + return SECTIONS_EMPTY() end #= Fetch the cached function. =# @@ -3392,7 +3349,7 @@ function checkConnectorForm(cref::ComponentRef, isConnector::Bool = true)::Bool return valid end -function checkLhsInWhen(exp::Expression)::Bool +function checkLhsInWhen(@nospecialize(exp::Expression))::Bool local isValid::Bool @assign isValid = begin @@ -3429,7 +3386,6 @@ function typeStatements(alg::List{<:Statement}, origin::ORIGIN_Type)::List{State end function typeStatement(st::Statement, origin::ORIGIN_Type)::Statement - @assign st = begin local cond::Expression local e1::Expression @@ -3776,7 +3732,7 @@ function typeIfEquation( return ifEq end -function isNonConstantIfCondition(exp::Expression)::Bool +function isNonConstantIfCondition(@nospecialize(exp::Expression))::Bool local isConstant::Bool @assign isConstant = begin @@ -3894,10 +3850,10 @@ function typeOperatorArg( end function typeReinit( - crefExp::Expression, - exp::Expression, - origin::ORIGIN_Type, - source::DAE.ElementSource, + @nospecialize(crefExp::Expression), + @nospecialize(exp::Expression), + @nospecialize(origin::ORIGIN_Type), + @nospecialize(source::DAE.ElementSource), )::Tuple{Expression, Expression} local var::VariabilityType diff --git a/src/NewFrontend/NFUnitCheck.jl b/src/NewFrontend/NFUnitCheck.jl index e7eb9a3..4933352 100644 --- a/src/NewFrontend/NFUnitCheck.jl +++ b/src/NewFrontend/NFUnitCheck.jl @@ -104,7 +104,7 @@ function updateVariable( local unit_idx::Integer = 0 local unit::Unit.Unit - if Type.isReal(var.ty) + if isReal(var.ty) for attr in var.typeAttributes @assign (name, binding) = attr @assign unit_idx = unit_idx + 1 @@ -263,7 +263,7 @@ function foldBindingExp( local binding_exp::Expression local eq::Equation - if Type.isReal(var.ty) && isBound(var.binding) + if isReal(var.ty) && isBound(var.binding) @assign binding_exp = getTypedExp(var.binding) @assign eq = P_Equation.Equation.makeEquality( P_Expression.Expression.fromCref(var.name), diff --git a/src/NewFrontend/NFVariable.jl b/src/NewFrontend/NFVariable.jl index 4959536..6c08e28 100644 --- a/src/NewFrontend/NFVariable.jl +++ b/src/NewFrontend/NFVariable.jl @@ -138,7 +138,7 @@ function lookupTypeAttribute(name::String, var::Variable)::Binding return binding end end - @assign binding = NFBinding.EMPTY_BINDING + @assign binding = EMPTY_BINDING return binding end @@ -188,7 +188,7 @@ function fromCref(cref::ComponentRef)::Variable @assign ty = getSubscriptedType(cref) @assign binding = P_Component.getBinding(comp) @assign vis = visibility(node) - @assign attr = P_Component.getAttributes(comp) + @assign attr = getAttributes(comp) @assign cmt = P_Component.comment(comp) @assign info = info(node) @assign variable = VARIABLE(cref, ty, binding, vis, attr, nil, cmt, info) diff --git a/src/example.mo b/src/example.mo index 1d73b21..1fb9748 100644 --- a/src/example.mo +++ b/src/example.mo @@ -1,6 +1,6 @@ model HelloWorld - Real x; + Real x( start = 1 ); parameter Real a = 1; equation - x = - a * der(x); + der(x) = - a * x; end HelloWorld; diff --git a/src/preCompileExpr.jl b/src/preCompileExpr.jl new file mode 100644 index 0000000..cb66a58 --- /dev/null +++ b/src/preCompileExpr.jl @@ -0,0 +1,4 @@ +using SnoopCompile +precompilestuff = @snoopi tmin=0.01 include("test.jl") +pc = SnoopCompile.parcel(precompilestuff) +SnoopCompile.write("./precompile", pc) diff --git a/src/precompile/precompile_Base.jl b/src/precompile/precompile_Base.jl new file mode 100644 index 0000000..8f1dea4 --- /dev/null +++ b/src/precompile/precompile_Base.jl @@ -0,0 +1,6 @@ +function _precompile_() + ccall(:jl_generating_output, Cint, ()) == 1 || return nothing + Base.precompile(Tuple{typeof(Base.require),Module,Symbol}) + Base.precompile(Tuple{typeof(get!),Type{Array{Function,1}},Dict{Base.PkgId,Array{Function,1}},Base.PkgId}) + Base.precompile(Tuple{typeof(joinpath),String,String,Vararg{String,N} where N}) +end diff --git a/src/precompile/precompile_HybridDAEParser.jl b/src/precompile/precompile_HybridDAEParser.jl new file mode 100644 index 0000000..ceeb8ea --- /dev/null +++ b/src/precompile/precompile_HybridDAEParser.jl @@ -0,0 +1,5 @@ +function _precompile_() + ccall(:jl_generating_output, Cint, ()) == 1 || return nothing + Base.precompile(Tuple{typeof(HybridDAEParser.runModel),String,String}) + Base.precompile(Tuple{typeof(HybridDAEParser.translateToSCode),Absyn.PROGRAM}) +end diff --git a/src/precompile/precompile_Random.jl b/src/precompile/precompile_Random.jl new file mode 100644 index 0000000..ef29140 --- /dev/null +++ b/src/precompile/precompile_Random.jl @@ -0,0 +1,4 @@ +function _precompile_() + ccall(:jl_generating_output, Cint, ()) == 1 || return nothing + Base.precompile(Tuple{typeof(Random.shuffle!),Random.MersenneTwister,Array{Symbol,1}}) +end diff --git a/src/precompile/precompile_SCode.jl b/src/precompile/precompile_SCode.jl new file mode 100644 index 0000000..18f7cb2 --- /dev/null +++ b/src/precompile/precompile_SCode.jl @@ -0,0 +1,4 @@ +function _precompile_() + ccall(:jl_generating_output, Cint, ()) == 1 || return nothing + Base.precompile(Tuple{typeof(Base.push_widen),Array{SCode.ALG_ASSIGN,1},SCode.ALG_IF}) +end