-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.expressions.ERuleset.DatalogRule;\r
-import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;\r
-import org.simantics.scl.compiler.elaboration.relations.LocalRelation;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-\r
-public class EPreRuleset extends ASTExpression {\r
-\r
- RuleStatement[] statements;\r
- Expression in;\r
- \r
- public EPreRuleset(RuleStatement[] statements, Expression in) {\r
- this.statements = statements;\r
- this.in = in;\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- THashMap<String, LocalRelation> relations = new THashMap<String, LocalRelation>(); \r
- DatalogRule[] rules = new DatalogRule[statements.length];\r
- context.pushRelationFrame();\r
- try {\r
- for(int i=0;i<statements.length;++i) {\r
- RuleStatement statement = statements[i];\r
- Expression head = statement.head;\r
- if(!(head instanceof EApply)) {\r
- context.getErrorLog().log(head.location, "Invalid rule head.");\r
- return new EError();\r
- }\r
- EApply apply = (EApply)head;\r
- if(!(apply.function instanceof EVar)) {\r
- context.getErrorLog().log(head.location, "Invalid relation in rule head.");\r
- return new EError();\r
- }\r
- String relationName = ((EVar)apply.function).name;\r
- LocalRelation relation = relations.get(relationName);\r
- if(relation == null) {\r
- relation = new LocalRelation(relationName, apply.parameters.length);\r
- relations.put(relationName, relation);\r
- context.newRelation(relationName, relation);\r
- }\r
- else if(apply.parameters.length != relation.getArity()) {\r
- context.getErrorLog().log(apply.location, "Different rules have different relation arity.");\r
- return new EError();\r
- }\r
- rules[i] = new DatalogRule(relation, apply.parameters, statement.body);\r
- }\r
- for(DatalogRule rule : rules) {\r
- context.pushExistentialFrame();\r
- for(int i=0;i<rule.headParameters.length;++i)\r
- rule.headParameters[i] = rule.headParameters[i].resolve(context);\r
- rule.body = rule.body.resolve(context);\r
- rule.variables = context.popExistentialFrame();\r
- }\r
- return new ERuleset(\r
- relations.values().toArray(new LocalRelation[relations.size()]),\r
- rules,\r
- in.resolve(context));\r
- } finally {\r
- context.popRelationFrame();\r
- }\r
- }\r
-\r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- for(RuleStatement statement : statements)\r
- statement.setLocationDeep(loc);\r
- in.setLocationDeep(loc);\r
- }\r
- }\r
- \r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.expressions.ERuleset.DatalogRule;
+import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
+import org.simantics.scl.compiler.elaboration.relations.LocalRelation;
+import org.simantics.scl.compiler.errors.Locations;
+
+import gnu.trove.map.hash.THashMap;
+
+public class EPreRuleset extends ASTExpression {
+
+ public RuleStatement[] statements;
+ public Expression in;
+
+ public EPreRuleset(RuleStatement[] statements, Expression in) {
+ this.statements = statements;
+ this.in = in;
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ THashMap<String, LocalRelation> relations = new THashMap<String, LocalRelation>();
+ DatalogRule[] rules = new DatalogRule[statements.length];
+ context.pushRelationFrame();
+ try {
+ for(int i=0;i<statements.length;++i) {
+ RuleStatement statement = statements[i];
+ Expression head = statement.head;
+ if(!(head instanceof EApply)) {
+ context.getErrorLog().log(head.location, "Invalid rule head.");
+ return new EError();
+ }
+ EApply apply = (EApply)head;
+ if(!(apply.function instanceof EVar)) {
+ context.getErrorLog().log(head.location, "Invalid relation in rule head.");
+ return new EError();
+ }
+ String relationName = ((EVar)apply.function).name;
+ LocalRelation relation = relations.get(relationName);
+ if(relation == null) {
+ relation = new LocalRelation(relationName, apply.parameters.length);
+ relations.put(relationName, relation);
+ context.newRelation(relationName, relation);
+ }
+ else if(apply.parameters.length != relation.getArity()) {
+ context.getErrorLog().log(apply.location, "Different rules have different relation arity.");
+ return new EError();
+ }
+ rules[i] = new DatalogRule(relation, apply.parameters, statement.body);
+ }
+ for(DatalogRule rule : rules) {
+ context.pushExistentialFrame();
+ for(int i=0;i<rule.headParameters.length;++i)
+ rule.headParameters[i] = rule.headParameters[i].resolve(context);
+ rule.body = rule.body.resolve(context);
+ rule.variables = context.popExistentialFrame();
+ }
+ return new ERuleset(
+ relations.values().toArray(new LocalRelation[relations.size()]),
+ rules,
+ in.resolve(context));
+ } finally {
+ context.popRelationFrame();
+ }
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ for(RuleStatement statement : statements)
+ statement.setLocationDeep(loc);
+ in.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+ @Override
+ public int getSyntacticFunctionArity() {
+ return in.getSyntacticFunctionArity();
+ }
+
+}