Skip to content

Commit

Permalink
Added support for for-statements in the interactive environment.
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@2478 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
David Broman committed Aug 23, 2006
1 parent e40c62c commit b93a43f
Show file tree
Hide file tree
Showing 6 changed files with 258 additions and 15 deletions.
4 changes: 2 additions & 2 deletions Compiler/Absyn.mo
Expand Up @@ -649,10 +649,10 @@ uniontype Exp "The `Exp\' datatype is the container of a Modelica expression.
end ARRAY;

record MATRIX
list<list<Exp>> matrix "matrix Range expressions, e.g. 1:10 or 1:0.5:10" ;
list<list<Exp>> matrix "matrix Range expressions, " ;
end MATRIX;

record RANGE
record RANGE "e.g. 1:10 or 1:0.5:10"
Exp start "start" ;
Option<Exp> step "step" ;
Exp stop "stop Tuples used in function calls returning several values" ;
Expand Down
8 changes: 6 additions & 2 deletions Compiler/Error.mo
Expand Up @@ -272,7 +272,9 @@ public constant ErrorID DUPLICATE_ELEMENTS_NOT_IDENTICAL=89;

public constant ErrorID PACKAGE_VARIABLE_NOT_CONSTANT=90;

public constant ErrorID RECURSIVE_DEFINITION= 91;
public constant ErrorID RECURSIVE_DEFINITION= 91;

public constant ErrorID NOT_ARRAY_TYPE_IN_FOR_STATEMENT= 92;

public constant ErrorID UNBOUND_PARAMETER_WARNING=500;

Expand Down Expand Up @@ -452,6 +454,8 @@ protected constant list<tuple<Integer, MessageType, Severity, String>> errorTabl
"Type mismatch in modifier, expected type %s, got modifier %s of type %s"),
(ERROR_FLATTENING,TRANSLATION(),ERROR(),
"Error occured while flattening model %s"),
(NOT_ARRAY_TYPE_IN_FOR_STATEMENT, TRANSLATION(), ERROR(),
"Expression %s in for-statement must be an array type"),
(DUPLICATE_ELEMENTS_NOT_IDENTICAL,TRANSLATION(),ERROR(),
"Error duplicate elements (due to inherited elements) not identical, first element is: %s, second element is: %s"),
(PACKAGE_VARIABLE_NOT_CONSTANT, TRANSLATION(),ERROR(),"Variable %s in package %s is not constant"),
Expand All @@ -466,7 +470,7 @@ protected constant list<tuple<Integer, MessageType, Severity, String>> errorTabl
protected import OpenModelica.Compiler.ErrorExt "Errors
WARNING
Notification" ;

protected import OpenModelica.Compiler.Util;

protected import OpenModelica.Compiler.Print;
Expand Down
212 changes: 205 additions & 7 deletions Compiler/Interactive.mo
Expand Up @@ -13,7 +13,7 @@ http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

Expand Down Expand Up @@ -417,7 +417,7 @@ algorithm
list<Env.Frame> env;
Exp.Exp econd,msg_1,sexp,srexp;
Types.Properties prop,rprop;
InteractiveSymbolTable st_1,st_2,st,newst;
InteractiveSymbolTable st_1,st_2,st_3,st_4,st,newst;
Absyn.Exp cond,msg,exp,rexp;
Absyn.Program p;
String str,ident;
Expand All @@ -430,6 +430,10 @@ algorithm
tuple<Absyn.Exp, list<Absyn.AlgorithmItem>> cond1;
list<tuple<Absyn.Exp, list<Absyn.AlgorithmItem>>> cond2,cond3,elseifexpitemlist;
list<Absyn.AlgorithmItem> algitemlist,elseitemlist;
String iter;
list<Absyn.AlgorithmItem> algItemList;
Values.Value startv, stepv, stopv;
Absyn.Exp starte, stepe, stope;
case (Absyn.ALGORITHMITEM(
algorithm_ = Absyn.ALG_NORETCALL(functionCall = Absyn.CREF_IDENT(name = "assert"),
functionArgs = Absyn.FUNCTIONARGS(args = {cond,msg}))),
Expand Down Expand Up @@ -474,14 +478,126 @@ algorithm
st_1 = evaluateIfStatementLst(cond3, st);
then
("",st_1);
case (Absyn.ALGORITHMITEM(algorithm_ = Absyn.ALG_WHILE(whileStmt = exp,whileBody = algitemlist)),st) /* WHILE-statement */
/* while-statement */
case (Absyn.ALGORITHMITEM(algorithm_ = Absyn.ALG_WHILE(whileStmt = exp,whileBody = algitemlist)),st)
equation
(value,st_1) = evaluateExpr(exp, st);
st_2 = evaluateWhileStmt(value, exp, algitemlist, st_1);
then
("",st_2);

/* for-statement, optimized case, e.g.: for i in 1:1000 loop */
case (Absyn.ALGORITHMITEM(algorithm_ =
Absyn.ALG_FOR(forVariable = iter, forStmt = Absyn.RANGE(start=starte,step=NONE, stop=stope),
forBody = algItemList)),st)
equation
(startv,st_1) = evaluateExpr(starte, st);
(stopv,st_2) = evaluateExpr(stope, st_1);
st_3 = evaluateForStmtRangeOpt(iter, startv, Values.INTEGER(1), stopv, algItemList, st_2);
then
("",st_3);

/* for-statement, optimized case, e.g.: for i in 7.3:0.4:1000.3 loop */
case (Absyn.ALGORITHMITEM(algorithm_ =
Absyn.ALG_FOR(forVariable = iter, forStmt = Absyn.RANGE(start=starte, step=SOME(stepe), stop=stope),
forBody = algItemList)),st)
equation
(startv,st_1) = evaluateExpr(starte, st);
(stepv,st_2) = evaluateExpr(stepe, st_1);
(stopv,st_3) = evaluateExpr(stope, st_2);
st_4 = evaluateForStmtRangeOpt(iter, startv, stepv, stopv, algItemList, st_3);
then
("",st_4);

/* for-statement, general case */ //DABR
case (Absyn.ALGORITHMITEM(algorithm_ =
Absyn.ALG_FOR(forVariable = iter, forStmt = exp,forBody = algItemList)),st)
local
input list<Values.Value> valList;
equation
(Values.ARRAY(valList),st_1) = evaluateExpr(exp, st);
st_2 = evaluateForStmt(iter, valList, algItemList, st_1);
then
("",st_2);
/* for-statement - not an array type */
case (Absyn.ALGORITHMITEM(algorithm_ = Absyn.ALG_FOR(forStmt = exp)),st)
local
String estr;
equation
estr = stringRepresOfExpr(exp, st);
Error.addMessage(Error.NOT_ARRAY_TYPE_IN_FOR_STATEMENT, {estr});
then
fail();
end matchcontinue;
end evaluateAlgStmt;
end evaluateAlgStmt;



protected function evaluateForStmt "evaluates a for-statement in an algorithm section"
input String iter "The iterator variable which will be assigned different values";
input list<Values.Value> valList "List of values that the iterator later will be assigned to";
input list<Absyn.AlgorithmItem> algItemList;
input InteractiveSymbolTable inInteractiveSymbolTable;
output InteractiveSymbolTable outInteractiveSymbolTable;
algorithm
outInteractiveSymbolTable:=
matchcontinue (forVar,valList,algItemList, inInteractiveSymbolTable)
local
Values.Value val;
list<Values.Value> vallst;
list<Absyn.AlgorithmItem> algItems;
InteractiveSymbolTable st1,st2,st3,st4,st5;
case (iter, val::vallst, algItems, st1)
equation
st2 = appendVarToSymboltable(iter, val, Types.typeOfValue(val), st1);
st3 = evaluateAlgStmtLst(algItems, st2);
st4 = deleteVarFromSymboltable(iter, st3);
st5 = evaluateForStmt(iter, vallst, algItems, st4);
then
st5;
case (_, {}, _, st1)
then
st1;
end matchcontinue;
end evaluateForStmt;


protected function evaluateForStmtRangeOpt
"Optimized version of for statement. In this case, we do not create a large array if
a range expression is given. E.g. for i in 1:10000 loop"
input String iter "The iterator variable which will be assigned different values";
input Values.Value startVal;
input Values.Value stepVal;
input Values.Value stopVal;
input list<Absyn.AlgorithmItem> algItemList;
input InteractiveSymbolTable inInteractiveSymbolTable;
output InteractiveSymbolTable outInteractiveSymbolTable;
algorithm
outInteractiveSymbolTable:=
matchcontinue (forVar, startVal, stepVal, stopVal, algItemList, inInteractiveSymbolTable)
local
Values.Value startv, stepv, stopv, nextv;
list<Values.Value> vallst;
list<Absyn.AlgorithmItem> algItems;
InteractiveSymbolTable st1,st2,st3,st4,st5;
Boolean startIsLess;
case (iter, startv, stepv, stopv, algItems, st1)
equation
startIsLess = Values.safeLessEq(startv, stopv);
equality(startIsLess = true);
st2 = appendVarToSymboltable(iter, startv, Types.typeOfValue(startv), st1);
st3 = evaluateAlgStmtLst(algItems, st2);
st4 = deleteVarFromSymboltable(iter, st3);
nextv = Values.safeIntRealOp(startv, stepv, Values.ADDOP);
st5 = evaluateForStmtRangeOpt(iter, nextv, stepv, stopv, algItems, st4);
then
st5;
case (_,_,_,_,_,st1)
then
st1;
end matchcontinue;
end evaluateForStmtRangeOpt;


protected function evaluateWhileStmt "function: evaluateWhileStmt

Expand Down Expand Up @@ -866,9 +982,91 @@ algorithm
end matchcontinue;
end addVarToSymboltable;

protected function addVarToVarlist "function: addVarToVarlist

Helper function to add_var_to_symboltable
public function appendVarToSymboltable "
Appends a variable to the interactive symbol table. Compared to addVarToSymboltable, this
function does not search for the identifier, it adds the variable to the beginning of the list.
Used in for example iterators in for statements.
"
input Absyn.Ident inIdent;
input Values.Value inValue;
input Types.Type inType;
input InteractiveSymbolTable inInteractiveSymbolTable;
output InteractiveSymbolTable outInteractiveSymbolTable;
algorithm
outInteractiveSymbolTable:=
matchcontinue (inIdent,inValue,inType,inInteractiveSymbolTable)
local
list<InteractiveVariable> vars_1,vars;
String ident;
Values.Value v;
tuple<Types.TType, Option<Absyn.Path>> t;
Absyn.Program p;
list<SCode.Class> sp;
list<InstantiatedClass> id;
list<tuple<Absyn.Path, tuple<Types.TType, Option<Absyn.Path>>>> cf;
case (ident,v,t,SYMBOLTABLE(ast = p,explodedAst = sp,instClsLst = id,lstVarVal = vars,compiledFunctions = cf))
equation
vars_1 = (IVAR(ident,v,t))::vars;
then
SYMBOLTABLE(p,sp,id,vars_1,cf);
end matchcontinue;
end appendVarToSymboltable;



public function deleteVarFromSymboltable
input Absyn.Ident inIdent;
input InteractiveSymbolTable inInteractiveSymbolTable;
output InteractiveSymbolTable outInteractiveSymbolTable;
algorithm
outInteractiveSymbolTable:=
matchcontinue (inIdent,inInteractiveSymbolTable)
local
list<InteractiveVariable> vars_1,vars;
String ident;
Absyn.Program p;
list<SCode.Class> sp;
list<InstantiatedClass> id;
list<tuple<Absyn.Path, tuple<Types.TType, Option<Absyn.Path>>>> cf;
case (ident,SYMBOLTABLE(ast = p,explodedAst = sp,instClsLst = id,lstVarVal = vars,compiledFunctions = cf))
equation
vars_1 = deleteVarFromVarlist(ident, vars);
then
SYMBOLTABLE(p,sp,id,vars_1,cf);
end matchcontinue;
end deleteVarFromSymboltable;



protected function deleteVarFromVarlist "deletes the first variable found"
input Absyn.Ident inIdent;
input list<InteractiveVariable> inInteractiveVariableLst;
output list<InteractiveVariable> outInteractiveVariableLst;
algorithm
outInteractiveVariableLst:=
matchcontinue (inIdent,inInteractiveVariableLst)
local
String ident,id2;
Values.Value v,val2;
list<InteractiveVariable> rest, rest2;
InteractiveVariable var;
case (ident,(IVAR(varIdent = id2) :: rest))
equation
equality(ident = id2);
then
rest;
case (ident,var::rest)
equation
rest2 = deleteVarFromVarlist(ident, rest);
then
var::rest2;
case (ident,{})
then {};
end matchcontinue;
end deleteVarFromVarlist;

protected function addVarToVarlist "
Assignes a value to a variable with a specific identifier.
"
input Absyn.Ident inIdent;
input Values.Value inValue;
Expand Down
4 changes: 2 additions & 2 deletions Compiler/Main.mo
Expand Up @@ -8,8 +8,8 @@ All rights reserved.

(The new BSD license, see also
http://www.opensource.org/licenses/bsd-license.php)


Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
Expand Down
2 changes: 1 addition & 1 deletion Compiler/Static.mo
Expand Up @@ -454,7 +454,7 @@ algorithm
(start_2,NONE,stop_2,rt) = deoverloadRange((start_1,start_t), NONE, (stop_1,stop_t));
const = Types.constAnd(c_start, c_stop);
(cache,t) = elabRangeType(cache,env, start_2, NONE, stop_2, const, rt, impl);
then
then
(cache,Exp.RANGE(rt,start_1,NONE,stop_1),Types.PROP(t,const),st_2);
case (cache,env,Absyn.RANGE(start = start,step = SOME(step),stop = stop),impl,st)
equation
Expand Down
43 changes: 42 additions & 1 deletion Compiler/Values.mo
Expand Up @@ -3,7 +3,7 @@ This file is part of OpenModelica.
§
Copyright (c) 1998-2005, Linköpings universitet, Department of
Computer and Information Science, PELAB

All rights reserved.

(The new BSD license, see also
Expand Down Expand Up @@ -278,6 +278,7 @@ public uniontype IntRealOp
record ADDOP end ADDOP;
record SUBOP end SUBOP;
record POWOP end POWOP;
record LESSEQOP end LESSEQOP;
end IntRealOp;

public function safeIntRealOp
Expand Down Expand Up @@ -432,6 +433,44 @@ algorithm
end safeIntRealOp;


public function safeLessEq
"Checks if val1 is less or equal to val2. Val1 or val2 can
be integers or reals.
"
input Value val1;
input Value val2;
output Boolean outv;
algorithm
outv :=
matchcontinue(val1, val2)
local
Real rv1,rv2;
Integer iv1,iv2;
case (INTEGER(iv1),INTEGER(iv2))
equation
outv = (iv1 <= iv2);
then
outv;
case (REAL(rv1),INTEGER(iv2))
equation
rv2 = intReal(iv2);
outv = (rv1 <=. rv2);
then
outv;
case (INTEGER(iv1), REAL(rv2))
equation
rv1 = intReal(iv1);
outv = (rv1 <=. rv2);
then
outv;
case (REAL(rv1), REAL(rv2))
equation
outv = (rv1 <=. rv2);
then
outv;
end matchcontinue;
end safeLessEq;

protected function unparseDescription "function: unparseDescription
Helper function to unparse_values. Creates a description string
Expand Down Expand Up @@ -1186,6 +1225,8 @@ algorithm
end matchcontinue;
end valString;



protected function valRecordString "function: valRecordString
This function returns a textual representation of a record,
Expand Down

0 comments on commit b93a43f

Please sign in to comment.