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.EAmbiguous;
12 import org.simantics.scl.compiler.elaboration.expressions.EApply;
13 import org.simantics.scl.compiler.elaboration.expressions.EApplyType;
14 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
15 import org.simantics.scl.compiler.elaboration.expressions.EBinary;
16 import org.simantics.scl.compiler.elaboration.expressions.EBind;
17 import org.simantics.scl.compiler.elaboration.expressions.EBlock;
18 import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset;
19 import org.simantics.scl.compiler.elaboration.expressions.ECHRRulesetConstructor;
20 import org.simantics.scl.compiler.elaboration.expressions.ECHRSelect;
21 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
22 import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
23 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
24 import org.simantics.scl.compiler.elaboration.expressions.EEquations;
25 import org.simantics.scl.compiler.elaboration.expressions.EError;
26 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
27 import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
28 import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint;
29 import org.simantics.scl.compiler.elaboration.expressions.EIf;
30 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
31 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
32 import org.simantics.scl.compiler.elaboration.expressions.ELambdaType;
33 import org.simantics.scl.compiler.elaboration.expressions.ELet;
34 import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
35 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
36 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
37 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
38 import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
39 import org.simantics.scl.compiler.elaboration.expressions.EPreLet;
40 import org.simantics.scl.compiler.elaboration.expressions.ERange;
41 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
42 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
43 import org.simantics.scl.compiler.elaboration.expressions.ERuleset;
44 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
45 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
46 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
47 import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
48 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
49 import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
50 import org.simantics.scl.compiler.elaboration.expressions.EVar;
51 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
52 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
53 import org.simantics.scl.compiler.elaboration.expressions.EWhen;
54 import org.simantics.scl.compiler.elaboration.expressions.Expression;
55 import org.simantics.scl.compiler.elaboration.expressions.ExpressionVisitor;
56 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
57 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
58 import org.simantics.scl.compiler.elaboration.expressions.Variable;
59 import org.simantics.scl.compiler.elaboration.java.EqRelation;
60 import org.simantics.scl.compiler.elaboration.java.MemberRelation;
61 import org.simantics.scl.compiler.elaboration.query.QAlternative;
62 import org.simantics.scl.compiler.elaboration.query.QAtom;
63 import org.simantics.scl.compiler.elaboration.query.QConjunction;
64 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
65 import org.simantics.scl.compiler.elaboration.query.QExists;
66 import org.simantics.scl.compiler.elaboration.query.QIf;
67 import org.simantics.scl.compiler.elaboration.query.QMapping;
68 import org.simantics.scl.compiler.elaboration.query.QNegation;
69 import org.simantics.scl.compiler.elaboration.query.Query;
70 import org.simantics.scl.compiler.elaboration.query.QueryVisitor;
71 import org.simantics.scl.compiler.elaboration.rules.SectionName;
72 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
74 public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisitor {
76 public static final boolean SHOW_EFFECTS = false;
78 StringBuilder b = new StringBuilder();
81 public ExpressionToStringVisitor(StringBuilder b) {
85 public void show(Variable variable) {
87 b.append("NULL_VARIABLE");
89 b.append(variable.getName());
92 private void newLine() {
94 for(int i=0;i<indentation;++i)
98 public void showPar(Expression expression) {
99 boolean needsPar = false;
101 if(expression instanceof EPlaceholder)
102 expression = ((EPlaceholder)expression).expression;
103 else if(expression instanceof ETypeAnnotation)
104 expression = ((ETypeAnnotation)expression).getValue();
105 else if(expression instanceof EApplyType)
106 expression = ((EApplyType)expression).getExpression();
107 else if(expression instanceof ELambdaType)
108 expression = ((ELambdaType)expression).value;
109 else if(expression instanceof ECoveringBranchPoint)
110 expression = ((ECoveringBranchPoint)expression).expression;
114 if(expression instanceof EApply ||
115 expression instanceof EIf ||
116 expression instanceof ESimpleLambda ||
117 expression instanceof ESimpleLet)
121 expression.accept(this);
127 public void visit(EApply expression) {
128 showPar(expression.getFunction());
130 b.append(" {" + expression.effect + "}");
131 for(Expression parameter : expression.getParameters()) {
138 public void visit(EApplyType expression) {
139 expression.getExpression().accept(this);
143 public void visit(EAsPattern expression) {
144 show(expression.getVariable());
146 showPar(expression.getPattern());
150 public void visit(EBind expression) {
155 public void visit(EConstant expression) {
156 String name = expression.getValue().getName().name;
157 if(Character.isJavaIdentifierStart(name.charAt(0)))
160 b.append('(').append(name).append(')');
164 public void visit(EEnforce expression) {
165 b.append("enforce ");
166 expression.getQuery().accept(this);
170 public void visit(EError expression) {
175 public void visit(EExternalConstant expression) {
176 b.append(expression.getValue());
180 public void visit(EFieldAccess expression) {
181 b.append("EFieldAccess");
185 public void visit(EGetConstraint expression) {
186 b.append("EGetConstraint");
190 public void visit(EIf expression) {
192 expression.condition.accept(this);
196 expression.then_.accept(this);
197 if(expression.else_ != null) {
200 expression.else_.accept(this);
206 public void visit(QIf query) {
208 query.condition.accept(this);
212 query.thenQuery.accept(this);
215 query.elseQuery.accept(this);
220 public void visit(EIntegerLiteral expression) {
221 b.append(expression.getValue());
225 public void visit(ELambda expression) {
228 for(Case case_ : expression.getCases()) {
230 for(Expression pat : case_.patterns) {
235 b.append("{" + expression.effect + "} ");
238 case_.value.accept(this);
245 public void visit(EViewPattern expression) {
247 expression.expression.accept(this);
249 expression.pattern.accept(this);
254 public void visit(ELambdaType expression) {
255 expression.value.accept(this);
259 public void visit(ELet expression) {
262 printAsDo(expression);
267 public void visit(EListComprehension expression) {
268 b.append("EListComprehension");
272 public void visit(EListLiteral expression) {
274 boolean first = true;
275 for(Expression component : expression.getComponents()) {
280 component.accept(this);
286 public void visit(ELiteral expression) {
287 b.append(expression.getValue().toString());
291 public void visit(EMatch expression) {
293 for(Expression s : expression.getScrutinee()) {
299 for(Case case_ : expression.getCases()) {
301 for(Expression pat : case_.patterns) {
307 case_.value.accept(this);
314 public void visit(EPlaceholder expression) {
315 expression.expression.accept(this);
319 public void visit(ERealLiteral expression) {
320 b.append(expression.getValue());
324 public void visit(ERuleset expression) {
327 for(ERuleset.DatalogRule rule : expression.getRules()) {
333 expression.getIn().accept(this);
337 public void visit(ESelect expression) {
342 public void visit(ECHRSelect expression) {
343 b.append("ECHRSelect");
347 public void visit(ESimpleLambda expression) {
349 show(expression.getParameter());
350 while(expression.getValue() instanceof ESimpleLambda) {
351 expression = (ESimpleLambda)expression.getValue();
353 show(expression.getParameter());
356 b.append(" {" + expression.effect + "}");
358 expression.getValue().accept(this);
362 public void visit(ESimpleLet expression) {
365 printAsDo(expression);
369 private void printAsDo(Expression expression) {
370 if(expression instanceof ESimpleLet) {
371 ESimpleLet let = (ESimpleLet)expression;
372 Variable variable = let.getVariable();
373 Expression value = let.getValue();
374 if(variable == null || "_".equals(variable.getName()))
382 printAsDo(let.getIn());
384 else if(expression instanceof ELet) {
385 ELet let = (ELet)expression;
386 for(Assignment assignment : let.assignments) {
388 assignment.pattern.accept(this);
390 assignment.value.accept(this);
396 expression.accept(this);
401 public void visit(ETransformation expression) {
402 b.append("<transformation>");
406 public void visit(ETypeAnnotation expression) {
407 expression.getValue().accept(this);
411 public void visit(EVar expression) {
412 b.append(expression.name);
416 public void visit(EVariable expression) {
417 show(expression.getVariable());
421 public void visit(EWhen expression) {
423 expression.getQuery().accept(this);
425 expression.getAction().accept(this);
429 public void visit(GuardedExpressionGroup expression) {
430 boolean first = true;
431 for(GuardedExpression gexp : expression.expressions) {
437 for(int i=0;i<gexp.guards.length;++i) {
440 gexp.guards[i].accept(this);
443 gexp.value.accept(this);
448 public void visit(QAlternative query) {
449 b.append("QAlternative");
453 public void visit(QAtom query) {
454 if(query.relation == EqRelation.INSTANCE) {
455 query.parameters[0].accept(this);
457 query.parameters[1].accept(this);
459 else if(query.relation == MemberRelation.INSTANCE) {
460 query.parameters[0].accept(this);
462 query.parameters[1].accept(this);
465 b.append(query.relation);
466 for(Expression parameter : query.parameters) {
474 public void visit(QConjunction query) {
475 boolean first = true;
476 for(Query q : query.queries) {
486 public void visit(QDisjunction query) {
487 b.append("QDisjunction");
491 public void visit(QExists query) {
496 public void visit(QNegation query) {
497 b.append("QNegation");
501 public void visit(QMapping query) {
502 b.append(query.mappingRelation.name.name);
503 for(Expression parameter : query.parameters) {
505 parameter.accept(this);
509 public void visit(ERuleset.DatalogRule rule) {
510 b.append(rule.headRelation.getName());
511 for(Expression parameter : rule.headParameters) {
517 rule.body.accept(this);
521 public void visit(TransformationRule rule) {
522 b.append("rule ").append(rule.name.name).append(" where");
523 for(Entry<SectionName, Query[]> section : rule.sections.entrySet()) {
524 b.append("\n@").append(section.getKey().name());
525 for(Query query : section.getValue()) {
534 public void visit(ECoveringBranchPoint expression) {
535 expression.expression.accept(this);
539 public void visit(EEquations expression) {
544 public void visit(ECHRRuleset expression) {
545 b.append("ECHRRuleset");
549 public void visit(ECHRRulesetConstructor expression) {
550 b.append("ECHRRulesetConstructor");
553 public void visit(CHRRule rule) {
559 public void visit(CHRQuery query) {
560 boolean first = true;
561 for(CHRLiteral literal : query.literals) {
570 public void visit(CHRLiteral literal) {
571 if(literal.passive && literal.relation instanceof CHRConstraint)
572 b.append("@passive ");
573 if(literal.killAfterMatch)
575 b.append(literal.relation);
576 for(Expression parameter : literal.parameters) {
583 public void visit(EBinary expression) {
584 b.append("<EBinary>");
588 public void visit(EBlock expression) {
589 b.append("<EBlock>");
593 public void visit(EPreLet expression) {
594 b.append("<EPreLet>");
598 public void visit(ERange expression) {
600 expression.from.accept(this);
602 expression.to.accept(this);
607 public void visit(ERecord expression) {
608 b.append("<ERecord>");
612 public void visit(EStringLiteral expression) {
614 for(int i=0;i<expression.strings.length;++i) {
615 b.append(expression.strings[i]);
616 if(i < expression.expressions.length) {
618 expression.expressions[i].accept(this);
626 public void visit(EAmbiguous eAmbiguous) {
627 b.append("EAmbigious");