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