1 package org.simantics.scl.compiler.elaboration.expressions.printing;
\r
3 import java.util.Map.Entry;
\r
5 import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
\r
6 import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
\r
7 import org.simantics.scl.compiler.elaboration.chr.CHRRule;
\r
8 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
\r
9 import org.simantics.scl.compiler.elaboration.expressions.Assignment;
\r
10 import org.simantics.scl.compiler.elaboration.expressions.Case;
\r
11 import org.simantics.scl.compiler.elaboration.expressions.EApply;
\r
12 import org.simantics.scl.compiler.elaboration.expressions.EApplyType;
\r
13 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
\r
14 import org.simantics.scl.compiler.elaboration.expressions.EBind;
\r
15 import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset;
\r
16 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
\r
17 import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
\r
18 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
\r
19 import org.simantics.scl.compiler.elaboration.expressions.EEquations;
\r
20 import org.simantics.scl.compiler.elaboration.expressions.EError;
\r
21 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
\r
22 import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
\r
23 import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint;
\r
24 import org.simantics.scl.compiler.elaboration.expressions.EIf;
\r
25 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
\r
26 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
\r
27 import org.simantics.scl.compiler.elaboration.expressions.ELambdaType;
\r
28 import org.simantics.scl.compiler.elaboration.expressions.ELet;
\r
29 import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
\r
30 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
\r
31 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
\r
32 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
\r
33 import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
\r
34 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
\r
35 import org.simantics.scl.compiler.elaboration.expressions.ERuleset;
\r
36 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
\r
37 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
\r
38 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
\r
39 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
\r
40 import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
\r
41 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
\r
42 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
\r
43 import org.simantics.scl.compiler.elaboration.expressions.EWhen;
\r
44 import org.simantics.scl.compiler.elaboration.expressions.Expression;
\r
45 import org.simantics.scl.compiler.elaboration.expressions.ExpressionVisitor;
\r
46 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
\r
47 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
\r
48 import org.simantics.scl.compiler.elaboration.expressions.Variable;
\r
49 import org.simantics.scl.compiler.elaboration.java.EqRelation;
\r
50 import org.simantics.scl.compiler.elaboration.java.MemberRelation;
\r
51 import org.simantics.scl.compiler.elaboration.query.QAlternative;
\r
52 import org.simantics.scl.compiler.elaboration.query.QAtom;
\r
53 import org.simantics.scl.compiler.elaboration.query.QConjunction;
\r
54 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
\r
55 import org.simantics.scl.compiler.elaboration.query.QExists;
\r
56 import org.simantics.scl.compiler.elaboration.query.QIf;
\r
57 import org.simantics.scl.compiler.elaboration.query.QMapping;
\r
58 import org.simantics.scl.compiler.elaboration.query.QNegation;
\r
59 import org.simantics.scl.compiler.elaboration.query.Query;
\r
60 import org.simantics.scl.compiler.elaboration.query.QueryVisitor;
\r
61 import org.simantics.scl.compiler.elaboration.rules.SectionName;
\r
62 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
\r
64 public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisitor {
\r
66 StringBuilder b = new StringBuilder();
\r
69 public ExpressionToStringVisitor(StringBuilder b) {
\r
73 public void show(Variable variable) {
\r
74 if(variable == null)
\r
75 b.append("NULL_VARIABLE");
\r
77 b.append(variable.getName());
\r
80 private void newLine() {
\r
82 for(int i=0;i<indentation;++i)
\r
86 public void showPar(Expression expression) {
\r
87 boolean needsPar = false;
\r
89 if(expression instanceof EPlaceholder)
\r
90 expression = ((EPlaceholder)expression).expression;
\r
91 else if(expression instanceof ETypeAnnotation)
\r
92 expression = ((ETypeAnnotation)expression).getValue();
\r
93 else if(expression instanceof EApplyType)
\r
94 expression = ((EApplyType)expression).getExpression();
\r
95 else if(expression instanceof ELambdaType)
\r
96 expression = ((ELambdaType)expression).value;
\r
97 else if(expression instanceof ECoveringBranchPoint)
\r
98 expression = ((ECoveringBranchPoint)expression).expression;
\r
102 if(expression instanceof EApply ||
\r
103 expression instanceof EIf ||
\r
104 expression instanceof ESimpleLambda ||
\r
105 expression instanceof ESimpleLet)
\r
109 expression.accept(this);
\r
115 public void visit(EApply expression) {
\r
116 showPar(expression.getFunction());
\r
117 for(Expression parameter : expression.getParameters()) {
\r
119 showPar(parameter);
\r
124 public void visit(EApplyType expression) {
\r
125 expression.getExpression().accept(this);
\r
129 public void visit(EAsPattern expression) {
\r
130 show(expression.getVariable());
\r
132 showPar(expression.getPattern());
\r
136 public void visit(EBind expression) {
\r
141 public void visit(EConstant expression) {
\r
142 String name = expression.getValue().getName().name;
\r
143 if(Character.isJavaIdentifierStart(name.charAt(0)))
\r
146 b.append('(').append(name).append(')');
\r
150 public void visit(EEnforce expression) {
\r
151 b.append("enforce ");
\r
152 expression.getQuery().accept(this);
\r
156 public void visit(EError expression) {
\r
157 b.append("EError");
\r
161 public void visit(EExternalConstant expression) {
\r
162 b.append(expression.getValue());
\r
166 public void visit(EFieldAccess expression) {
\r
167 b.append("EFieldAccess");
\r
171 public void visit(EGetConstraint expression) {
\r
172 b.append("EGetConstraint");
\r
176 public void visit(EIf expression) {
\r
178 expression.condition.accept(this);
\r
182 expression.then_.accept(this);
\r
183 if(expression.else_ != null) {
\r
186 expression.else_.accept(this);
\r
192 public void visit(QIf query) {
\r
194 query.condition.accept(this);
\r
198 query.thenQuery.accept(this);
\r
201 query.elseQuery.accept(this);
\r
206 public void visit(EIntegerLiteral expression) {
\r
207 b.append(expression.getValue());
\r
211 public void visit(ELambda expression) {
\r
214 for(Case case_ : expression.getCases()) {
\r
216 for(Expression pat : case_.patterns) {
\r
222 case_.value.accept(this);
\r
229 public void visit(EViewPattern expression) {
\r
231 expression.expression.accept(this);
\r
233 expression.pattern.accept(this);
\r
238 public void visit(ELambdaType expression) {
\r
239 expression.value.accept(this);
\r
243 public void visit(ELet expression) {
\r
246 printAsDo(expression);
\r
251 public void visit(EListComprehension expression) {
\r
252 b.append("EListComprehension");
\r
256 public void visit(EListLiteral expression) {
\r
258 boolean first = true;
\r
259 for(Expression component : expression.getComponents()) {
\r
264 component.accept(this);
\r
270 public void visit(ELiteral expression) {
\r
271 b.append(expression.getValue().toString());
\r
275 public void visit(EMatch expression) {
\r
277 for(Expression s : expression.getScrutinee()) {
\r
283 for(Case case_ : expression.getCases()) {
\r
285 for(Expression pat : case_.patterns) {
\r
291 case_.value.accept(this);
\r
298 public void visit(EPlaceholder expression) {
\r
299 expression.expression.accept(this);
\r
303 public void visit(ERealLiteral expression) {
\r
304 b.append(expression.getValue());
\r
308 public void visit(ERuleset expression) {
\r
311 for(ERuleset.DatalogRule rule : expression.getRules()) {
\r
317 expression.getIn().accept(this);
\r
321 public void visit(ESelect expression) {
\r
322 b.append("ESelect");
\r
326 public void visit(ESimpleLambda expression) {
\r
328 show(expression.getParameter());
\r
329 while(expression.getValue() instanceof ESimpleLambda) {
\r
330 expression = (ESimpleLambda)expression.getValue();
\r
332 show(expression.getParameter());
\r
335 expression.getValue().accept(this);
\r
339 public void visit(ESimpleLet expression) {
\r
342 printAsDo(expression);
\r
346 private void printAsDo(Expression expression) {
\r
347 if(expression instanceof ESimpleLet) {
\r
348 ESimpleLet let = (ESimpleLet)expression;
\r
349 Variable variable = let.getVariable();
\r
350 Expression value = let.getValue();
\r
351 if(variable == null || "_".equals(variable.getName()))
\r
357 value.accept(this);
\r
359 printAsDo(let.getIn());
\r
361 else if(expression instanceof ELet) {
\r
362 ELet let = (ELet)expression;
\r
363 for(Assignment assignment : let.assignments) {
\r
365 assignment.pattern.accept(this);
\r
367 assignment.value.accept(this);
\r
373 expression.accept(this);
\r
378 public void visit(ETransformation expression) {
\r
379 b.append("<transformation>");
\r
383 public void visit(ETypeAnnotation expression) {
\r
384 expression.getValue().accept(this);
\r
388 public void visit(EVariable expression) {
\r
389 show(expression.getVariable());
\r
393 public void visit(EWhen expression) {
\r
395 expression.getQuery().accept(this);
\r
397 expression.getAction().accept(this);
\r
401 public void visit(GuardedExpressionGroup expression) {
\r
402 boolean first = true;
\r
403 for(GuardedExpression gexp : expression.expressions) {
\r
409 for(int i=0;i<gexp.guards.length;++i) {
\r
412 gexp.guards[i].accept(this);
\r
415 gexp.value.accept(this);
\r
420 public void visit(QAlternative query) {
\r
421 b.append("QAlternative");
\r
425 public void visit(QAtom query) {
\r
426 if(query.relation == EqRelation.INSTANCE) {
\r
427 query.parameters[0].accept(this);
\r
429 query.parameters[1].accept(this);
\r
431 else if(query.relation == MemberRelation.INSTANCE) {
\r
432 query.parameters[0].accept(this);
\r
434 query.parameters[1].accept(this);
\r
437 b.append(query.relation);
\r
438 for(Expression parameter : query.parameters) {
\r
440 showPar(parameter);
\r
446 public void visit(QConjunction query) {
\r
447 boolean first = true;
\r
448 for(Query q : query.queries) {
\r
458 public void visit(QDisjunction query) {
\r
459 b.append("QDisjunction");
\r
463 public void visit(QExists query) {
\r
464 b.append("QExists");
\r
468 public void visit(QNegation query) {
\r
469 b.append("QNegation");
\r
473 public void visit(QMapping query) {
\r
474 b.append(query.mappingRelation.name.name);
\r
475 for(Expression parameter : query.parameters) {
\r
477 parameter.accept(this);
\r
481 public void visit(ERuleset.DatalogRule rule) {
\r
482 b.append(rule.headRelation.getName());
\r
483 for(Expression parameter : rule.headParameters) {
\r
485 showPar(parameter);
\r
489 rule.body.accept(this);
\r
493 public void visit(TransformationRule rule) {
\r
494 b.append("rule ").append(rule.name.name).append(" where");
\r
495 for(Entry<SectionName, Query[]> section : rule.sections.entrySet()) {
\r
496 b.append("\n@").append(section.getKey().name());
\r
497 for(Query query : section.getValue()) {
\r
499 query.accept(this);
\r
506 public void visit(ECoveringBranchPoint expression) {
\r
507 expression.expression.accept(this);
\r
511 public void visit(EEquations eEquations) {
\r
516 public void visit(ECHRRuleset echrRuleset) {
\r
517 b.append("CHRRuleset");
\r
520 public void visit(CHRRule rule) {
\r
526 public void visit(CHRQuery query) {
\r
527 boolean first = true;
\r
528 for(CHRLiteral literal : query.literals) {
\r
537 public void visit(CHRLiteral literal) {
\r
538 if(literal.passive && literal.relation instanceof CHRConstraint)
\r
539 b.append("@passive ");
\r
540 if(literal.killAfterMatch)
\r
542 b.append(literal.relation);
\r
543 for(Expression parameter : literal.parameters) {
\r
545 showPar(parameter);
\r