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.EConstant;
19 import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
20 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
21 import org.simantics.scl.compiler.elaboration.expressions.EEquations;
22 import org.simantics.scl.compiler.elaboration.expressions.EError;
23 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
24 import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
25 import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint;
26 import org.simantics.scl.compiler.elaboration.expressions.EIf;
27 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
28 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
29 import org.simantics.scl.compiler.elaboration.expressions.ELambdaType;
30 import org.simantics.scl.compiler.elaboration.expressions.ELet;
31 import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
32 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
33 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
34 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
35 import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
36 import org.simantics.scl.compiler.elaboration.expressions.EPreLet;
37 import org.simantics.scl.compiler.elaboration.expressions.ERange;
38 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
39 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
40 import org.simantics.scl.compiler.elaboration.expressions.ERuleset;
41 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
42 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
43 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
44 import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
45 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
46 import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
47 import org.simantics.scl.compiler.elaboration.expressions.EVar;
48 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
49 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
50 import org.simantics.scl.compiler.elaboration.expressions.EWhen;
51 import org.simantics.scl.compiler.elaboration.expressions.Expression;
52 import org.simantics.scl.compiler.elaboration.expressions.ExpressionVisitor;
53 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
54 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
55 import org.simantics.scl.compiler.elaboration.expressions.Variable;
56 import org.simantics.scl.compiler.elaboration.java.EqRelation;
57 import org.simantics.scl.compiler.elaboration.java.MemberRelation;
58 import org.simantics.scl.compiler.elaboration.query.QAlternative;
59 import org.simantics.scl.compiler.elaboration.query.QAtom;
60 import org.simantics.scl.compiler.elaboration.query.QConjunction;
61 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
62 import org.simantics.scl.compiler.elaboration.query.QExists;
63 import org.simantics.scl.compiler.elaboration.query.QIf;
64 import org.simantics.scl.compiler.elaboration.query.QMapping;
65 import org.simantics.scl.compiler.elaboration.query.QNegation;
66 import org.simantics.scl.compiler.elaboration.query.Query;
67 import org.simantics.scl.compiler.elaboration.query.QueryVisitor;
68 import org.simantics.scl.compiler.elaboration.rules.SectionName;
69 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
71 public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisitor {
73 StringBuilder b = new StringBuilder();
76 public ExpressionToStringVisitor(StringBuilder b) {
80 public void show(Variable variable) {
82 b.append("NULL_VARIABLE");
84 b.append(variable.getName());
87 private void newLine() {
89 for(int i=0;i<indentation;++i)
93 public void showPar(Expression expression) {
94 boolean needsPar = false;
96 if(expression instanceof EPlaceholder)
97 expression = ((EPlaceholder)expression).expression;
98 else if(expression instanceof ETypeAnnotation)
99 expression = ((ETypeAnnotation)expression).getValue();
100 else if(expression instanceof EApplyType)
101 expression = ((EApplyType)expression).getExpression();
102 else if(expression instanceof ELambdaType)
103 expression = ((ELambdaType)expression).value;
104 else if(expression instanceof ECoveringBranchPoint)
105 expression = ((ECoveringBranchPoint)expression).expression;
109 if(expression instanceof EApply ||
110 expression instanceof EIf ||
111 expression instanceof ESimpleLambda ||
112 expression instanceof ESimpleLet)
116 expression.accept(this);
122 public void visit(EApply expression) {
123 showPar(expression.getFunction());
124 for(Expression parameter : expression.getParameters()) {
131 public void visit(EApplyType expression) {
132 expression.getExpression().accept(this);
136 public void visit(EAsPattern expression) {
137 show(expression.getVariable());
139 showPar(expression.getPattern());
143 public void visit(EBind expression) {
148 public void visit(EConstant expression) {
149 String name = expression.getValue().getName().name;
150 if(Character.isJavaIdentifierStart(name.charAt(0)))
153 b.append('(').append(name).append(')');
157 public void visit(EEnforce expression) {
158 b.append("enforce ");
159 expression.getQuery().accept(this);
163 public void visit(EError expression) {
168 public void visit(EExternalConstant expression) {
169 b.append(expression.getValue());
173 public void visit(EFieldAccess expression) {
174 b.append("EFieldAccess");
178 public void visit(EGetConstraint expression) {
179 b.append("EGetConstraint");
183 public void visit(EIf expression) {
185 expression.condition.accept(this);
189 expression.then_.accept(this);
190 if(expression.else_ != null) {
193 expression.else_.accept(this);
199 public void visit(QIf query) {
201 query.condition.accept(this);
205 query.thenQuery.accept(this);
208 query.elseQuery.accept(this);
213 public void visit(EIntegerLiteral expression) {
214 b.append(expression.getValue());
218 public void visit(ELambda expression) {
221 for(Case case_ : expression.getCases()) {
223 for(Expression pat : case_.patterns) {
229 case_.value.accept(this);
236 public void visit(EViewPattern expression) {
238 expression.expression.accept(this);
240 expression.pattern.accept(this);
245 public void visit(ELambdaType expression) {
246 expression.value.accept(this);
250 public void visit(ELet expression) {
253 printAsDo(expression);
258 public void visit(EListComprehension expression) {
259 b.append("EListComprehension");
263 public void visit(EListLiteral expression) {
265 boolean first = true;
266 for(Expression component : expression.getComponents()) {
271 component.accept(this);
277 public void visit(ELiteral expression) {
278 b.append(expression.getValue().toString());
282 public void visit(EMatch expression) {
284 for(Expression s : expression.getScrutinee()) {
290 for(Case case_ : expression.getCases()) {
292 for(Expression pat : case_.patterns) {
298 case_.value.accept(this);
305 public void visit(EPlaceholder expression) {
306 expression.expression.accept(this);
310 public void visit(ERealLiteral expression) {
311 b.append(expression.getValue());
315 public void visit(ERuleset expression) {
318 for(ERuleset.DatalogRule rule : expression.getRules()) {
324 expression.getIn().accept(this);
328 public void visit(ESelect expression) {
333 public void visit(ESimpleLambda expression) {
335 show(expression.getParameter());
336 while(expression.getValue() instanceof ESimpleLambda) {
337 expression = (ESimpleLambda)expression.getValue();
339 show(expression.getParameter());
342 expression.getValue().accept(this);
346 public void visit(ESimpleLet expression) {
349 printAsDo(expression);
353 private void printAsDo(Expression expression) {
354 if(expression instanceof ESimpleLet) {
355 ESimpleLet let = (ESimpleLet)expression;
356 Variable variable = let.getVariable();
357 Expression value = let.getValue();
358 if(variable == null || "_".equals(variable.getName()))
366 printAsDo(let.getIn());
368 else if(expression instanceof ELet) {
369 ELet let = (ELet)expression;
370 for(Assignment assignment : let.assignments) {
372 assignment.pattern.accept(this);
374 assignment.value.accept(this);
380 expression.accept(this);
385 public void visit(ETransformation expression) {
386 b.append("<transformation>");
390 public void visit(ETypeAnnotation expression) {
391 expression.getValue().accept(this);
395 public void visit(EVar expression) {
396 b.append(expression.name);
400 public void visit(EVariable expression) {
401 show(expression.getVariable());
405 public void visit(EWhen expression) {
407 expression.getQuery().accept(this);
409 expression.getAction().accept(this);
413 public void visit(GuardedExpressionGroup expression) {
414 boolean first = true;
415 for(GuardedExpression gexp : expression.expressions) {
421 for(int i=0;i<gexp.guards.length;++i) {
424 gexp.guards[i].accept(this);
427 gexp.value.accept(this);
432 public void visit(QAlternative query) {
433 b.append("QAlternative");
437 public void visit(QAtom query) {
438 if(query.relation == EqRelation.INSTANCE) {
439 query.parameters[0].accept(this);
441 query.parameters[1].accept(this);
443 else if(query.relation == MemberRelation.INSTANCE) {
444 query.parameters[0].accept(this);
446 query.parameters[1].accept(this);
449 b.append(query.relation);
450 for(Expression parameter : query.parameters) {
458 public void visit(QConjunction query) {
459 boolean first = true;
460 for(Query q : query.queries) {
470 public void visit(QDisjunction query) {
471 b.append("QDisjunction");
475 public void visit(QExists query) {
480 public void visit(QNegation query) {
481 b.append("QNegation");
485 public void visit(QMapping query) {
486 b.append(query.mappingRelation.name.name);
487 for(Expression parameter : query.parameters) {
489 parameter.accept(this);
493 public void visit(ERuleset.DatalogRule rule) {
494 b.append(rule.headRelation.getName());
495 for(Expression parameter : rule.headParameters) {
501 rule.body.accept(this);
505 public void visit(TransformationRule rule) {
506 b.append("rule ").append(rule.name.name).append(" where");
507 for(Entry<SectionName, Query[]> section : rule.sections.entrySet()) {
508 b.append("\n@").append(section.getKey().name());
509 for(Query query : section.getValue()) {
518 public void visit(ECoveringBranchPoint expression) {
519 expression.expression.accept(this);
523 public void visit(EEquations eEquations) {
528 public void visit(ECHRRuleset echrRuleset) {
529 b.append("CHRRuleset");
532 public void visit(CHRRule rule) {
538 public void visit(CHRQuery query) {
539 boolean first = true;
540 for(CHRLiteral literal : query.literals) {
549 public void visit(CHRLiteral literal) {
550 if(literal.passive && literal.relation instanceof CHRConstraint)
551 b.append("@passive ");
552 if(literal.killAfterMatch)
554 b.append(literal.relation);
555 for(Expression parameter : literal.parameters) {
562 public void visit(EBinary expression) {
563 b.append("<EBinary>");
567 public void visit(EBlock expression) {
568 b.append("<EBlock>");
572 public void visit(EPreLet expression) {
573 b.append("<EPreLet>");
577 public void visit(ERange expression) {
579 expression.from.accept(this);
581 expression.to.accept(this);
586 public void visit(ERecord expression) {
587 b.append("<ERecord>");
591 public void visit(EStringLiteral expression) {
593 for(int i=0;i<expression.strings.length;++i) {
594 b.append(expression.strings[i]);
595 if(i < expression.expressions.length) {
597 expression.expressions[i].accept(this);