1 package org.simantics.scl.compiler.elaboration.expressions.printing;
3 import java.util.Map.Entry;
5 import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
6 import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
7 import org.simantics.scl.compiler.elaboration.chr.CHRRule;
8 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
9 import org.simantics.scl.compiler.elaboration.expressions.Assignment;
10 import org.simantics.scl.compiler.elaboration.expressions.Case;
11 import org.simantics.scl.compiler.elaboration.expressions.EApply;
12 import org.simantics.scl.compiler.elaboration.expressions.EApplyType;
13 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
14 import org.simantics.scl.compiler.elaboration.expressions.EBinary;
15 import org.simantics.scl.compiler.elaboration.expressions.EBind;
16 import org.simantics.scl.compiler.elaboration.expressions.EBlock;
17 import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset;
18 import org.simantics.scl.compiler.elaboration.expressions.ECHRRulesetConstructor;
19 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
20 import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
21 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
22 import org.simantics.scl.compiler.elaboration.expressions.EEquations;
23 import org.simantics.scl.compiler.elaboration.expressions.EError;
24 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
25 import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
26 import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint;
27 import org.simantics.scl.compiler.elaboration.expressions.EIf;
28 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
29 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
30 import org.simantics.scl.compiler.elaboration.expressions.ELambdaType;
31 import org.simantics.scl.compiler.elaboration.expressions.ELet;
32 import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
33 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
34 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
35 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
36 import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
37 import org.simantics.scl.compiler.elaboration.expressions.EPreLet;
38 import org.simantics.scl.compiler.elaboration.expressions.ERange;
39 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
40 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
41 import org.simantics.scl.compiler.elaboration.expressions.ERuleset;
42 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
43 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
44 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
45 import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
46 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
47 import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
48 import org.simantics.scl.compiler.elaboration.expressions.EVar;
49 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
50 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
51 import org.simantics.scl.compiler.elaboration.expressions.EWhen;
52 import org.simantics.scl.compiler.elaboration.expressions.Expression;
53 import org.simantics.scl.compiler.elaboration.expressions.ExpressionVisitor;
54 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
55 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
56 import org.simantics.scl.compiler.elaboration.expressions.Variable;
57 import org.simantics.scl.compiler.elaboration.java.EqRelation;
58 import org.simantics.scl.compiler.elaboration.java.MemberRelation;
59 import org.simantics.scl.compiler.elaboration.query.QAlternative;
60 import org.simantics.scl.compiler.elaboration.query.QAtom;
61 import org.simantics.scl.compiler.elaboration.query.QConjunction;
62 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
63 import org.simantics.scl.compiler.elaboration.query.QExists;
64 import org.simantics.scl.compiler.elaboration.query.QIf;
65 import org.simantics.scl.compiler.elaboration.query.QMapping;
66 import org.simantics.scl.compiler.elaboration.query.QNegation;
67 import org.simantics.scl.compiler.elaboration.query.Query;
68 import org.simantics.scl.compiler.elaboration.query.QueryVisitor;
69 import org.simantics.scl.compiler.elaboration.rules.SectionName;
70 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
72 public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisitor {
74 StringBuilder b = new StringBuilder();
77 public ExpressionToStringVisitor(StringBuilder b) {
81 public void show(Variable variable) {
83 b.append("NULL_VARIABLE");
85 b.append(variable.getName());
88 private void newLine() {
90 for(int i=0;i<indentation;++i)
94 public void showPar(Expression expression) {
95 boolean needsPar = false;
97 if(expression instanceof EPlaceholder)
98 expression = ((EPlaceholder)expression).expression;
99 else if(expression instanceof ETypeAnnotation)
100 expression = ((ETypeAnnotation)expression).getValue();
101 else if(expression instanceof EApplyType)
102 expression = ((EApplyType)expression).getExpression();
103 else if(expression instanceof ELambdaType)
104 expression = ((ELambdaType)expression).value;
105 else if(expression instanceof ECoveringBranchPoint)
106 expression = ((ECoveringBranchPoint)expression).expression;
110 if(expression instanceof EApply ||
111 expression instanceof EIf ||
112 expression instanceof ESimpleLambda ||
113 expression instanceof ESimpleLet)
117 expression.accept(this);
123 public void visit(EApply expression) {
124 showPar(expression.getFunction());
125 for(Expression parameter : expression.getParameters()) {
132 public void visit(EApplyType expression) {
133 expression.getExpression().accept(this);
137 public void visit(EAsPattern expression) {
138 show(expression.getVariable());
140 showPar(expression.getPattern());
144 public void visit(EBind expression) {
149 public void visit(EConstant expression) {
150 String name = expression.getValue().getName().name;
151 if(Character.isJavaIdentifierStart(name.charAt(0)))
154 b.append('(').append(name).append(')');
158 public void visit(EEnforce expression) {
159 b.append("enforce ");
160 expression.getQuery().accept(this);
164 public void visit(EError expression) {
169 public void visit(EExternalConstant expression) {
170 b.append(expression.getValue());
174 public void visit(EFieldAccess expression) {
175 b.append("EFieldAccess");
179 public void visit(EGetConstraint expression) {
180 b.append("EGetConstraint");
184 public void visit(EIf expression) {
186 expression.condition.accept(this);
190 expression.then_.accept(this);
191 if(expression.else_ != null) {
194 expression.else_.accept(this);
200 public void visit(QIf query) {
202 query.condition.accept(this);
206 query.thenQuery.accept(this);
209 query.elseQuery.accept(this);
214 public void visit(EIntegerLiteral expression) {
215 b.append(expression.getValue());
219 public void visit(ELambda expression) {
222 for(Case case_ : expression.getCases()) {
224 for(Expression pat : case_.patterns) {
230 case_.value.accept(this);
237 public void visit(EViewPattern expression) {
239 expression.expression.accept(this);
241 expression.pattern.accept(this);
246 public void visit(ELambdaType expression) {
247 expression.value.accept(this);
251 public void visit(ELet expression) {
254 printAsDo(expression);
259 public void visit(EListComprehension expression) {
260 b.append("EListComprehension");
264 public void visit(EListLiteral expression) {
266 boolean first = true;
267 for(Expression component : expression.getComponents()) {
272 component.accept(this);
278 public void visit(ELiteral expression) {
279 b.append(expression.getValue().toString());
283 public void visit(EMatch expression) {
285 for(Expression s : expression.getScrutinee()) {
291 for(Case case_ : expression.getCases()) {
293 for(Expression pat : case_.patterns) {
299 case_.value.accept(this);
306 public void visit(EPlaceholder expression) {
307 expression.expression.accept(this);
311 public void visit(ERealLiteral expression) {
312 b.append(expression.getValue());
316 public void visit(ERuleset expression) {
319 for(ERuleset.DatalogRule rule : expression.getRules()) {
325 expression.getIn().accept(this);
329 public void visit(ESelect expression) {
334 public void visit(ESimpleLambda expression) {
336 show(expression.getParameter());
337 while(expression.getValue() instanceof ESimpleLambda) {
338 expression = (ESimpleLambda)expression.getValue();
340 show(expression.getParameter());
343 expression.getValue().accept(this);
347 public void visit(ESimpleLet expression) {
350 printAsDo(expression);
354 private void printAsDo(Expression expression) {
355 if(expression instanceof ESimpleLet) {
356 ESimpleLet let = (ESimpleLet)expression;
357 Variable variable = let.getVariable();
358 Expression value = let.getValue();
359 if(variable == null || "_".equals(variable.getName()))
367 printAsDo(let.getIn());
369 else if(expression instanceof ELet) {
370 ELet let = (ELet)expression;
371 for(Assignment assignment : let.assignments) {
373 assignment.pattern.accept(this);
375 assignment.value.accept(this);
381 expression.accept(this);
386 public void visit(ETransformation expression) {
387 b.append("<transformation>");
391 public void visit(ETypeAnnotation expression) {
392 expression.getValue().accept(this);
396 public void visit(EVar expression) {
397 b.append(expression.name);
401 public void visit(EVariable expression) {
402 show(expression.getVariable());
406 public void visit(EWhen expression) {
408 expression.getQuery().accept(this);
410 expression.getAction().accept(this);
414 public void visit(GuardedExpressionGroup expression) {
415 boolean first = true;
416 for(GuardedExpression gexp : expression.expressions) {
422 for(int i=0;i<gexp.guards.length;++i) {
425 gexp.guards[i].accept(this);
428 gexp.value.accept(this);
433 public void visit(QAlternative query) {
434 b.append("QAlternative");
438 public void visit(QAtom query) {
439 if(query.relation == EqRelation.INSTANCE) {
440 query.parameters[0].accept(this);
442 query.parameters[1].accept(this);
444 else if(query.relation == MemberRelation.INSTANCE) {
445 query.parameters[0].accept(this);
447 query.parameters[1].accept(this);
450 b.append(query.relation);
451 for(Expression parameter : query.parameters) {
459 public void visit(QConjunction query) {
460 boolean first = true;
461 for(Query q : query.queries) {
471 public void visit(QDisjunction query) {
472 b.append("QDisjunction");
476 public void visit(QExists query) {
481 public void visit(QNegation query) {
482 b.append("QNegation");
486 public void visit(QMapping query) {
487 b.append(query.mappingRelation.name.name);
488 for(Expression parameter : query.parameters) {
490 parameter.accept(this);
494 public void visit(ERuleset.DatalogRule rule) {
495 b.append(rule.headRelation.getName());
496 for(Expression parameter : rule.headParameters) {
502 rule.body.accept(this);
506 public void visit(TransformationRule rule) {
507 b.append("rule ").append(rule.name.name).append(" where");
508 for(Entry<SectionName, Query[]> section : rule.sections.entrySet()) {
509 b.append("\n@").append(section.getKey().name());
510 for(Query query : section.getValue()) {
519 public void visit(ECoveringBranchPoint expression) {
520 expression.expression.accept(this);
524 public void visit(EEquations expression) {
529 public void visit(ECHRRuleset expression) {
530 b.append("ECHRRuleset");
534 public void visit(ECHRRulesetConstructor expression) {
535 b.append("ECHRRulesetConstructor");
538 public void visit(CHRRule rule) {
544 public void visit(CHRQuery query) {
545 boolean first = true;
546 for(CHRLiteral literal : query.literals) {
555 public void visit(CHRLiteral literal) {
556 if(literal.passive && literal.relation instanceof CHRConstraint)
557 b.append("@passive ");
558 if(literal.killAfterMatch)
560 b.append(literal.relation);
561 for(Expression parameter : literal.parameters) {
568 public void visit(EBinary expression) {
569 b.append("<EBinary>");
573 public void visit(EBlock expression) {
574 b.append("<EBlock>");
578 public void visit(EPreLet expression) {
579 b.append("<EPreLet>");
583 public void visit(ERange expression) {
585 expression.from.accept(this);
587 expression.to.accept(this);
592 public void visit(ERecord expression) {
593 b.append("<ERecord>");
597 public void visit(EStringLiteral expression) {
599 for(int i=0;i<expression.strings.length;++i) {
600 b.append(expression.strings[i]);
601 if(i < expression.expressions.length) {
603 expression.expressions[i].accept(this);