Object element = element(index);\r
// Last position should not be array\r
if(position == subscripts.length-1) {\r
- if(element instanceof Array) throw new IllegalStateException();\r
+ if(element instanceof Array) throw new ExecutionException("Array size does not match subscripts.");\r
if(element instanceof IExpression) {\r
IExpression exp = (IExpression)element;\r
return exp.evaluate(environment);\r
*******************************************************************************/\r
package fi.semantum.sysdyn.solver;\r
\r
-\r
public class Assignment {\r
- \r
+\r
+ private static final boolean VALIDATE = true; \r
+\r
+ public IFrame model;\r
public Variable target;\r
public IExpression[] subscripts;\r
public IExpression expression;\r
public boolean assigned = false;\r
public boolean isConstant = false;\r
\r
- public Assignment(Variable target, IExpression[] subscripts, IExpression expression) {\r
+ public Assignment(IFrame model, Variable target, IExpression[] subscripts, IExpression expression) {\r
+ this.model = model;\r
this.target = target;\r
this.subscripts = subscripts;\r
this.expression = expression;\r
IExpression[] subscripts2 = new IExpression[subscripts.length];\r
for(int i=0;i<subscripts.length;i++)\r
subscripts2[i] = subscripts[i].withBase(frame, prefix);\r
- return new Assignment(target.withBase(frame, prefix), subscripts2, expression.withBase(frame, prefix));\r
+ return new Assignment(frame, target.withBase(frame, prefix), subscripts2, expression.withBase(frame, prefix));\r
} else {\r
- return new Assignment(target.withBase(frame, prefix), null, expression.withBase(frame, prefix));\r
+ return new Assignment(frame, target.withBase(frame, prefix), null, expression.withBase(frame, prefix));\r
+ }\r
+ }\r
+ \r
+ public void assign(IEnvironment env) {\r
+ try {\r
+ Object value = expression.evaluate(env);\r
+ if(value != null) {\r
+ validate(target, value);\r
+ target.assign(env, subscripts, value);\r
+ assigned = true;\r
+ }\r
+ } catch (ExecutionException e) {\r
+ if(model instanceof Model) {\r
+ throw new ExecutionException("Line " + (target.line-((Model)model).line) + ": while evaluating " + target.base.name + ": " + e.getMessage());\r
+ } else {\r
+ throw new ExecutionException("While evaluating " + target.base.name + ": " + e.getMessage());\r
+ }\r
}\r
}\r
\r
+ \r
+ private void validate(Variable var, Object value) {\r
+ if(VALIDATE) {\r
+ if(value instanceof Double) {\r
+ if(Double.isNaN((Double)value)) {\r
+ System.err.println("value is invalid (NaN): " + var.base.name);\r
+ throw new IllegalStateException("value is invalid (NaN)");\r
+ }\r
+ if(Double.isInfinite((Double)value)) {\r
+ System.err.println("value is invalid (Infinite): " + var.base.name);\r
+ throw new IllegalStateException("value is invalid (Infinite)");\r
+ }\r
+ }\r
+ if(value instanceof Array) {\r
+ for(Object o : ((Array)value).elements()) validate(var, o);\r
+ }\r
+ }\r
+ }\r
+ \r
}\r
--- /dev/null
+package fi.semantum.sysdyn.solver;\r
+\r
+public class ExecutionException extends RuntimeException {\r
+\r
+ private static final long serialVersionUID = 8394963990462508948L;\r
+ \r
+ public int line = -1;\r
+ \r
+ public ExecutionException(String message) {\r
+ super(message);\r
+ }\r
+\r
+ public ExecutionException(String message, int line) {\r
+ super(message);\r
+ this.line = line;\r
+ }\r
+\r
+}\r
public Variable[] parameters;\r
\r
public ArrayList<ForIndex> indices = new ArrayList<ForIndex>();\r
+ \r
+ public int line;\r
\r
- public Function(String name, IStatement statement) {\r
+ public Function(String name, IStatement statement, int line) {\r
this.name = name;\r
this.statement = statement;\r
+ this.line = line;\r
}\r
\r
public Object evaluate(IEnvironment environment, int argc) {\r
\r
public final Globals globals;\r
\r
+ public int line = -1;\r
public String name;\r
public boolean isEnumClass;\r
\r
return base;\r
}\r
\r
+ private void reportException(Fn fn, ExecutionException e) throws ExecutionException {\r
+ \r
+ if(fn instanceof Function) {\r
+ throw new ExecutionException("function " + name + ": " + (e.line - ((Function)fn).line) + ": " + e.getMessage());\r
+ } else {\r
+ throw new ExecutionException("function " + name + ": " + (e.line - ((Function)fn).line) + ": " + e.getMessage());\r
+ }\r
+ \r
+ }\r
+ \r
public Object evaluateFunction(IEnvironment environment, String name, ArgumentList args) {\r
Fn fn = getFunction(name);\r
if(fn == null) {\r
\r
fn.setLocals(frame);\r
\r
- return fn.evaluate(frame, args.args.length+1);\r
+ try {\r
+ \r
+ return fn.evaluate(frame, args.args.length+1);\r
+ \r
+ } catch (ExecutionException e) {\r
+ \r
+ reportException(fn, e);\r
+ \r
+ }\r
\r
} else {\r
\r
}\r
\r
fn.setLocals(frame);\r
- Object value = fn.evaluate(frame, args.args.length); \r
- return value;\r
+ \r
+ try {\r
+\r
+ return fn.evaluate(frame, args.args.length); \r
+\r
+ } catch (ExecutionException e) {\r
+\r
+ reportException(fn, e);\r
+\r
+ }\r
\r
}\r
\r
}\r
\r
+ // This cannot happen - reportException always throws\r
+ throw new IllegalStateException();\r
+ \r
}\r
\r
private Array arrayEvaluate(Frame frame, Fn fn, Variable[] parameters, Object[] ps, boolean[] vector, List<Array> arrs) {\r
IExpression exp = (IExpression)walk((SimpleNode)n.jjtGetChild(1), indent+2, frame);\r
if(v instanceof Derivative) {\r
Derivative der = (Derivative)v;\r
- Assignment eq = new Assignment(der.variable, der.variable.subscripts, new Derivate(der.variable, der.variable.subscripts, exp));\r
+ Assignment eq = new Assignment(model, der.variable, der.variable.subscripts, new Derivate(der.variable, der.variable.subscripts, exp));\r
model.derivatives.add(eq);\r
return eq;\r
} else {\r
Variable var = (Variable)v;\r
- Assignment eq = new Assignment(var, var.subscripts, exp);\r
+ Assignment eq = new Assignment(model, var, var.subscripts, exp);\r
if(model.initial)\r
model.initials.add(eq);\r
else\r
return subs;\r
case declaration:\r
if(n.jjtGetNumChildren() == 0) {\r
- return new Declaration(new Variable(frame, n.op, null), null);\r
+ return new Declaration(new Variable(frame, n.op, null, n.line), null);\r
} else if(n.jjtGetNumChildren() == 1) {\r
Object o = walk((SimpleNode)n.jjtGetChild(0), indent+2, frame);\r
if(o instanceof IExpression[]) {\r
- return new Declaration(new Variable(frame, n.op, (IExpression[])o), null);\r
+ return new Declaration(new Variable(frame, n.op, (IExpression[])o, n.line), null);\r
} else {\r
- return new Declaration(new Variable(frame, n.op, null), o);\r
+ return new Declaration(new Variable(frame, n.op, null, n.line), o);\r
}\r
} else if(n.jjtGetNumChildren() == 2) {\r
IExpression[] subscripts2 = (IExpression[])walk((SimpleNode)n.jjtGetChild(0), indent+2, frame);\r
Object modification = walk((SimpleNode)n.jjtGetChild(1), indent+2, frame);\r
- return new Declaration(new Variable(frame, n.op,subscripts2), modification);\r
+ return new Declaration(new Variable(frame, n.op,subscripts2, n.line), modification);\r
} else {\r
StringBuilder b = new StringBuilder();\r
b.append("declaration: ");\r
SimpleNode child = (SimpleNode)n.jjtGetChild(0);\r
String packagePath = getPackagePath(child);\r
String functionName = packagePath + child.op;\r
+ System.err.println("function " + functionName + " at line " + child.line);\r
ArrayList<IStatement> stms2 = new ArrayList<IStatement>();\r
- Function function = new Function(functionName, new StatementList(stms2));\r
+ Function function = new Function(functionName, new StatementList(stms2), child.line);\r
ArrayList<Object> composition = (ArrayList<Object>)walk(child, indent+2, function);\r
for(int i=1;i<composition.size();i++) {\r
Object comp = composition.get(i);\r
}\r
}\r
}\r
+ \r
model.functions.put(functionName, function);\r
return function;\r
\r
} else if("model".equals(n.op)) {\r
\r
+ model.line = n.line;\r
+ \r
if(n.jjtGetNumChildren() == 1) {\r
return walk((SimpleNode)n.jjtGetChild(0), indent+2, frame);\r
} else {\r
walk(specifier, indent+2, clazz);\r
\r
if(clazz.isEnumClass) {\r
- Variable sizeVariable = new Variable(clazz, "size", null);\r
- Variable elementsVariable = new Variable(clazz, "elements", new IExpression[] { new Constant(""+clazz.variables.size()) });\r
+ Variable sizeVariable = new Variable(clazz, "size", null, n.line);\r
+ Variable elementsVariable = new Variable(clazz, "elements", new IExpression[] { new Constant(""+clazz.variables.size()) }, n.line);\r
clazz.parameters.add(new ParameterDeclaration(sizeVariable, sizeVariable.getPossibleConstant()));\r
clazz.parameters.add(new ParameterDeclaration(elementsVariable, elementsVariable.getPossibleConstant()));\r
}\r
}\r
case component_reference:\r
if(n.jjtGetNumChildren() == 1) {\r
- return Variable.make(frame, n.op, (IExpression[])walk((SimpleNode)n.jjtGetChild(0), indent+2, frame));\r
+ return Variable.make(frame, n.op, (IExpression[])walk((SimpleNode)n.jjtGetChild(0), indent+2, frame), n.line);\r
} else {\r
if ("time".equals(n.op)) {\r
return new TimeVariable();\r
}\r
- return Variable.make(frame, n.op, null);\r
+ return Variable.make(frame, n.op, null, n.line);\r
}\r
case relation:\r
if(n.jjtGetNumChildren() == 3) {\r
\r
for(Assignment ass : assignments) {\r
try {\r
- if(!ass.assigned) {\r
- Object value = ass.expression.evaluate(env);\r
- if(value != null) {\r
- validate(ass.target, value);\r
- ass.target.assign(env, ass.subscripts, value);\r
- ass.assigned = true;\r
- }\r
- }\r
+ if(!ass.assigned)\r
+ ass.assign(env);\r
} catch (Exception e) {\r
String error = " -" + ass.target.toString() + ": " + e.getMessage();\r
if(errors != null) {\r
Assignment[] assignments = model.assignmentArray;\r
for(int i=0;i<assignments.length;i++) {\r
if(assignments[i].isConstant) continue;\r
- Object value = assignments[i].expression.evaluate(env);\r
- assignments[i].target.assign(env, assignments[i].subscripts, value);\r
+ assignments[i].assign(env);\r
+// Object value = assignments[i].expression.evaluate(env);\r
+// assignments[i].target.assign(env, assignments[i].subscripts, value);\r
}\r
for(Assignment ass : model.initials) {\r
if(ass.isConstant) continue;\r
- Object value = ass.expression.evaluate(env);\r
- ass.target.assign(env, ass.subscripts, value);\r
+ ass.assign(env);\r
+// Object value = ass.expression.evaluate(env);\r
+// ass.target.assign(env, ass.subscripts, value);\r
}\r
\r
for(VariableDeclaration vd : model.variables) {\r
// Next solve algebraic equations\r
for(int i=0;i<assignments.length;i++) {\r
if(assignments[i].isConstant) continue;\r
- Object value = assignments[i].expression.evaluate(env);\r
- assignments[i].target.assign(env, assignments[i].subscripts, value);\r
+ assignments[i].assign(env);\r
+// Object value = assignments[i].expression.evaluate(env);\r
+// assignments[i].target.assign(env, assignments[i].subscripts, value);\r
}\r
\r
}\r
\r
public VariableBase base;\r
public IExpression[] subscripts = null;\r
+ public int line = -1;\r
\r
- public Variable(IFrame frame, String name, IExpression[] subscripts) {\r
+ public Variable(IFrame frame, String name, IExpression[] subscripts, int line) {\r
base = frame.getBase(name);\r
this.subscripts = subscripts;\r
+ this.line = line;\r
}\r
\r
- public static Object make(IFrame frame, String name, IExpression[] subscripts) {\r
+ public static Object make(IFrame frame, String name, IExpression[] subscripts, int line) {\r
// Array enumElements = enumerationElements(frame, name);\r
// if(enumElements != null) return enumElements;\r
// Constant enumSize = enumerationSize(frame, name);\r
// if(enumSize != null) return enumSize;\r
- return new Variable(frame, name, subscripts);\r
+ return new Variable(frame, name, subscripts, line);\r
}\r
\r
public Variable(VariableBase base) {\r
@Override\r
public Object evaluate(IEnvironment environment) {\r
\r
- if(constantIndex == -2) constantIndex = base.getConstantIndex(environment, subscripts);\r
+ try {\r
\r
- return base.evaluate(environment, subscripts, constantIndex);\r
+ if(constantIndex == -2) constantIndex = base.getConstantIndex(environment, subscripts);\r
+ \r
+ return base.evaluate(environment, subscripts, constantIndex);\r
+ \r
+ } catch (ExecutionException e) {\r
+ \r
+ throw new ExecutionException(base.name + ": " + e.getMessage(), line);\r
+ \r
+ }\r
\r
}\r
\r
/*** Class Definition **********************************************/\r
final public void class_definition() throws ParseException {\r
/*@bgen(jjtree) class_definition */\r
- SimpleNode jjtn000 = new SimpleNode(JJTCLASS_DEFINITION);\r
- boolean jjtc000 = true;\r
- jjtree.openNodeScope(jjtn000);\r
+ SimpleNode jjtn000 = new SimpleNode(JJTCLASS_DEFINITION);\r
+ boolean jjtc000 = true;\r
+ jjtree.openNodeScope(jjtn000);Token t;\r
try {\r
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {\r
case 30:\r
jjtn000.op = "class";\r
break;\r
case 7:\r
- jj_consume_token(7);\r
- jjtn000.op = "model";\r
+ t = jj_consume_token(7);\r
+ jjtn000.op = "model"; jjtn000.line = t.beginLine;\r
break;\r
case 61:\r
jj_consume_token(61);\r
try {\r
if (jj_2_1(2)) {\r
t = jj_consume_token(IDENT);\r
- jjtn000.op = t.image;\r
+ jjtn000.op = t.image; jjtn000.line = t.beginLine;\r
string_comment();\r
composition();\r
jj_consume_token(35);\r
Parameter ret = new Parameter();\r
try {\r
jj_consume_token(IDENT);\r
- ret.name = new String(token.image); jjtn000.op = token.image;\r
+ ret.name = new String(token.image); jjtn000.op = token.image; jjtn000.line = token.beginLine;\r
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {\r
case 66:\r
array_subscripts();\r
;\r
}\r
t = jj_consume_token(IDENT);\r
- jjtn000.op = t.image;\r
+ jjtn000.op = t.image; jjtn000.line = t.beginLine;\r
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {\r
case 66:\r
array_subscripts();\r
return false;\r
}\r
\r
+ private boolean jj_3R_107() {\r
+ Token xsp;\r
+ xsp = jj_scanpos;\r
+ if (jj_scan_token(50)) jj_scanpos = xsp;\r
+ if (jj_scan_token(44)) return true;\r
+ return false;\r
+ }\r
+\r
private boolean jj_3R_66() {\r
if (jj_3R_80()) return true;\r
return false;\r
return false;\r
}\r
\r
- private boolean jj_3R_107() {\r
- Token xsp;\r
- xsp = jj_scanpos;\r
- if (jj_scan_token(50)) jj_scanpos = xsp;\r
- if (jj_scan_token(44)) return true;\r
- return false;\r
- }\r
-\r
private boolean jj_3R_84() {\r
Token xsp;\r
xsp = jj_scanpos;\r
return false;\r
}\r
\r
+ private boolean jj_3R_165() {\r
+ if (jj_scan_token(68)) return true;\r
+ if (jj_scan_token(IDENT)) return true;\r
+ return false;\r
+ }\r
+\r
private boolean jj_3R_58() {\r
if (jj_scan_token(IDENT)) return true;\r
if (jj_3R_74()) return true;\r
return false;\r
}\r
\r
- private boolean jj_3R_165() {\r
- if (jj_scan_token(68)) return true;\r
- if (jj_scan_token(IDENT)) return true;\r
+ private boolean jj_3R_164() {\r
+ if (jj_3R_170()) return true;\r
return false;\r
}\r
\r
return false;\r
}\r
\r
- private boolean jj_3R_164() {\r
- if (jj_3R_170()) return true;\r
- return false;\r
- }\r
-\r
private boolean jj_3R_48() {\r
Token xsp;\r
xsp = jj_scanpos;\r
/*** Class Definition **********************************************/\r
\r
void class_definition() : {/*@bgen(jjtree) class_definition */\r
- SimpleNode jjtn000 = new SimpleNode(JJTCLASS_DEFINITION);\r
- boolean jjtc000 = true;\r
- jjtree.openNodeScope(jjtn000);\r
-/*@egen*/\r
+ SimpleNode jjtn000 = new SimpleNode(JJTCLASS_DEFINITION);\r
+ boolean jjtc000 = true;\r
+ jjtree.openNodeScope(jjtn000);\r
+/*@egen*/ Token t;\r
} {/*@bgen(jjtree) class_definition */\r
try {\r
/*@egen*/\r
// class_specifier\r
( "encapsulated" )?\r
( "partial" )?\r
- ( "class" { jjtn000.op = "class"; } | "model" { jjtn000.op = "model"; } | "record" | "block" | ( "expandable" )? "connector" | "type" |\r
+ ( "class" { jjtn000.op = "class"; } | t = "model" { jjtn000.op = "model"; jjtn000.line = t.beginLine; } | "record" | "block" | ( "expandable" )? "connector" | "type" |\r
"package" { jjtn000.op = "package"; } | "function" { jjtn000.op = "function"; } | "operator" | "operator function" | "operator record" )\r
class_specifier()/*@bgen(jjtree)*/\r
} catch (Throwable jjte000) {\r
// | IDENT "=" der "(" name "," IDENT { "," IDENT } ")" comment\r
// | extends IDENT [ class_modification ] string_comment composition\r
// end IDENT \r
- LOOKAHEAD(2) t=<IDENT> { jjtn000.op = t.image; } string_comment() composition() "end" <IDENT>\r
+ LOOKAHEAD(2) t=<IDENT> { jjtn000.op = t.image; jjtn000.line = t.beginLine; } string_comment() composition() "end" <IDENT>\r
| LOOKAHEAD(2) <IDENT> "=" base_prefix() name() ( array_subscripts() )? ( class_modification() )? comment()\r
| LOOKAHEAD(3) <IDENT> "=" "der" "(" name() "," <IDENT> ( "," <IDENT> )* ")" comment()\r
| LOOKAHEAD(3) <IDENT> "=" "enumeration" "(" ( ( enum_list() )? | ":" ) ")" comment()/*@bgen(jjtree)*/\r
try {\r
/*@egen*/\r
// IDENT [ array_subscripts ] [ modification ]\r
- <IDENT> { ret.name = new String(token.image); jjtn000.op = token.image; }\r
+ <IDENT> { ret.name = new String(token.image); jjtn000.op = token.image; jjtn000.line = token.beginLine; }\r
( array_subscripts() )?\r
( ret.optional = modification() )?/*@bgen(jjtree)*/\r
{\r
try {\r
/*@egen*/\r
// [ "." ] IDENT [ array_subscripts ] { "." IDENT [ array_subscripts ] }\r
- ( "." )? t=<IDENT> { jjtn000.op = t.image; } ( array_subscripts() )? ( "." <IDENT> ( array_subscripts() )? )*/*@bgen(jjtree)*/\r
+ ( "." )? t=<IDENT> { jjtn000.op = t.image; jjtn000.line = t.beginLine; } ( array_subscripts() )? ( "." <IDENT> ( array_subscripts() )? )*/*@bgen(jjtree)*/\r
} catch (Throwable jjte000) {\r
if (jjtc000) {\r
jjtree.clearNodeScope(jjtn000);\r
\r
/*** Class Definition **********************************************/\r
\r
-void class_definition() : {\r
+void class_definition() : { Token t;\r
} {\r
// class_definition :\r
// [ encapsulated ]\r
// class_specifier\r
( "encapsulated" )?\r
( "partial" )?\r
- ( "class" { jjtThis.op = "class"; } | "model" { jjtThis.op = "model"; } | "record" | "block" | ( "expandable" )? "connector" | "type" |\r
+ ( "class" { jjtThis.op = "class"; } | t = "model" { jjtThis.op = "model"; jjtThis.line = t.beginLine; } | "record" | "block" | ( "expandable" )? "connector" | "type" |\r
"package" { jjtThis.op = "package"; } | "function" { jjtThis.op = "function"; } | "operator" | "operator function" | "operator record" )\r
class_specifier()\r
}\r
// | IDENT "=" der "(" name "," IDENT { "," IDENT } ")" comment\r
// | extends IDENT [ class_modification ] string_comment composition\r
// end IDENT \r
- LOOKAHEAD(2) t=<IDENT> { jjtThis.op = t.image; } string_comment() composition() "end" <IDENT>\r
+ LOOKAHEAD(2) t=<IDENT> { jjtThis.op = t.image; jjtThis.line = t.beginLine; } string_comment() composition() "end" <IDENT>\r
| LOOKAHEAD(2) <IDENT> "=" base_prefix() name() ( array_subscripts() )? ( class_modification() )? comment()\r
| LOOKAHEAD(3) <IDENT> "=" "der" "(" name() "," <IDENT> ( "," <IDENT> )* ")" comment()\r
| LOOKAHEAD(3) <IDENT> "=" "enumeration" "(" ( ( enum_list() )? | ":" ) ")" comment()\r
Parameter ret = new Parameter();\r
} {\r
// IDENT [ array_subscripts ] [ modification ]\r
- <IDENT> { ret.name = new String(token.image); jjtThis.op = token.image; }\r
+ <IDENT> { ret.name = new String(token.image); jjtThis.op = token.image; jjtThis.line = token.beginLine; }\r
( array_subscripts() )?\r
( ret.optional = modification() )?\r
{\r return ret;\r }\r
Token t;\r
} {\r
// [ "." ] IDENT [ array_subscripts ] { "." IDENT [ array_subscripts ] }\r
- ( "." )? t=<IDENT> { jjtThis.op = t.image; } ( array_subscripts() )? ( "." <IDENT> ( array_subscripts() )? )*\r
+ ( "." )? t=<IDENT> { jjtThis.op = t.image; jjtThis.line = t.beginLine; } ( array_subscripts() )? ( "." <IDENT> ( array_subscripts() )? )*\r
}\r
\r
void function_call_args() : {\r
protected Object value;\r
protected ModelParser parser;\r
\r
+ public int line = -1;\r
public String op;\r
\r
public SimpleNode(int i) {\r