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.ECHRSelect;
20 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
21 import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
22 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
23 import org.simantics.scl.compiler.elaboration.expressions.EEquations;
24 import org.simantics.scl.compiler.elaboration.expressions.EError;
25 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
26 import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
27 import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint;
28 import org.simantics.scl.compiler.elaboration.expressions.EIf;
29 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
30 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
31 import org.simantics.scl.compiler.elaboration.expressions.ELambdaType;
32 import org.simantics.scl.compiler.elaboration.expressions.ELet;
33 import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
34 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
35 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
36 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
37 import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
38 import org.simantics.scl.compiler.elaboration.expressions.EPreLet;
39 import org.simantics.scl.compiler.elaboration.expressions.ERange;
40 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
41 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
42 import org.simantics.scl.compiler.elaboration.expressions.ERuleset;
43 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
44 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
45 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
46 import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
47 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
48 import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
49 import org.simantics.scl.compiler.elaboration.expressions.EVar;
50 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
51 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
52 import org.simantics.scl.compiler.elaboration.expressions.EWhen;
53 import org.simantics.scl.compiler.elaboration.expressions.Expression;
54 import org.simantics.scl.compiler.elaboration.expressions.ExpressionVisitor;
55 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
56 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
57 import org.simantics.scl.compiler.elaboration.expressions.Variable;
58 import org.simantics.scl.compiler.elaboration.java.EqRelation;
59 import org.simantics.scl.compiler.elaboration.java.MemberRelation;
60 import org.simantics.scl.compiler.elaboration.query.QAlternative;
61 import org.simantics.scl.compiler.elaboration.query.QAtom;
62 import org.simantics.scl.compiler.elaboration.query.QConjunction;
63 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
64 import org.simantics.scl.compiler.elaboration.query.QExists;
65 import org.simantics.scl.compiler.elaboration.query.QIf;
66 import org.simantics.scl.compiler.elaboration.query.QMapping;
67 import org.simantics.scl.compiler.elaboration.query.QNegation;
68 import org.simantics.scl.compiler.elaboration.query.Query;
69 import org.simantics.scl.compiler.elaboration.query.QueryVisitor;
70 import org.simantics.scl.compiler.elaboration.rules.SectionName;
71 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
73 public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisitor {
75 StringBuilder b = new StringBuilder();
78 public ExpressionToStringVisitor(StringBuilder b) {
82 public void show(Variable variable) {
84 b.append("NULL_VARIABLE");
86 b.append(variable.getName());
89 private void newLine() {
91 for(int i=0;i<indentation;++i)
95 public void showPar(Expression expression) {
96 boolean needsPar = false;
98 if(expression instanceof EPlaceholder)
99 expression = ((EPlaceholder)expression).expression;
100 else if(expression instanceof ETypeAnnotation)
101 expression = ((ETypeAnnotation)expression).getValue();
102 else if(expression instanceof EApplyType)
103 expression = ((EApplyType)expression).getExpression();
104 else if(expression instanceof ELambdaType)
105 expression = ((ELambdaType)expression).value;
106 else if(expression instanceof ECoveringBranchPoint)
107 expression = ((ECoveringBranchPoint)expression).expression;
111 if(expression instanceof EApply ||
112 expression instanceof EIf ||
113 expression instanceof ESimpleLambda ||
114 expression instanceof ESimpleLet)
118 expression.accept(this);
124 public void visit(EApply expression) {
125 showPar(expression.getFunction());
126 for(Expression parameter : expression.getParameters()) {
133 public void visit(EApplyType expression) {
134 expression.getExpression().accept(this);
138 public void visit(EAsPattern expression) {
139 show(expression.getVariable());
141 showPar(expression.getPattern());
145 public void visit(EBind expression) {
150 public void visit(EConstant expression) {
151 String name = expression.getValue().getName().name;
152 if(Character.isJavaIdentifierStart(name.charAt(0)))
155 b.append('(').append(name).append(')');
159 public void visit(EEnforce expression) {
160 b.append("enforce ");
161 expression.getQuery().accept(this);
165 public void visit(EError expression) {
170 public void visit(EExternalConstant expression) {
171 b.append(expression.getValue());
175 public void visit(EFieldAccess expression) {
176 b.append("EFieldAccess");
180 public void visit(EGetConstraint expression) {
181 b.append("EGetConstraint");
185 public void visit(EIf expression) {
187 expression.condition.accept(this);
191 expression.then_.accept(this);
192 if(expression.else_ != null) {
195 expression.else_.accept(this);
201 public void visit(QIf query) {
203 query.condition.accept(this);
207 query.thenQuery.accept(this);
210 query.elseQuery.accept(this);
215 public void visit(EIntegerLiteral expression) {
216 b.append(expression.getValue());
220 public void visit(ELambda expression) {
223 for(Case case_ : expression.getCases()) {
225 for(Expression pat : case_.patterns) {
231 case_.value.accept(this);
238 public void visit(EViewPattern expression) {
240 expression.expression.accept(this);
242 expression.pattern.accept(this);
247 public void visit(ELambdaType expression) {
248 expression.value.accept(this);
252 public void visit(ELet expression) {
255 printAsDo(expression);
260 public void visit(EListComprehension expression) {
261 b.append("EListComprehension");
265 public void visit(EListLiteral expression) {
267 boolean first = true;
268 for(Expression component : expression.getComponents()) {
273 component.accept(this);
279 public void visit(ELiteral expression) {
280 b.append(expression.getValue().toString());
284 public void visit(EMatch expression) {
286 for(Expression s : expression.getScrutinee()) {
292 for(Case case_ : expression.getCases()) {
294 for(Expression pat : case_.patterns) {
300 case_.value.accept(this);
307 public void visit(EPlaceholder expression) {
308 expression.expression.accept(this);
312 public void visit(ERealLiteral expression) {
313 b.append(expression.getValue());
317 public void visit(ERuleset expression) {
320 for(ERuleset.DatalogRule rule : expression.getRules()) {
326 expression.getIn().accept(this);
330 public void visit(ESelect expression) {
335 public void visit(ECHRSelect expression) {
336 b.append("ECHRSelect");
340 public void visit(ESimpleLambda expression) {
342 show(expression.getParameter());
343 while(expression.getValue() instanceof ESimpleLambda) {
344 expression = (ESimpleLambda)expression.getValue();
346 show(expression.getParameter());
349 expression.getValue().accept(this);
353 public void visit(ESimpleLet expression) {
356 printAsDo(expression);
360 private void printAsDo(Expression expression) {
361 if(expression instanceof ESimpleLet) {
362 ESimpleLet let = (ESimpleLet)expression;
363 Variable variable = let.getVariable();
364 Expression value = let.getValue();
365 if(variable == null || "_".equals(variable.getName()))
373 printAsDo(let.getIn());
375 else if(expression instanceof ELet) {
376 ELet let = (ELet)expression;
377 for(Assignment assignment : let.assignments) {
379 assignment.pattern.accept(this);
381 assignment.value.accept(this);
387 expression.accept(this);
392 public void visit(ETransformation expression) {
393 b.append("<transformation>");
397 public void visit(ETypeAnnotation expression) {
398 expression.getValue().accept(this);
402 public void visit(EVar expression) {
403 b.append(expression.name);
407 public void visit(EVariable expression) {
408 show(expression.getVariable());
412 public void visit(EWhen expression) {
414 expression.getQuery().accept(this);
416 expression.getAction().accept(this);
420 public void visit(GuardedExpressionGroup expression) {
421 boolean first = true;
422 for(GuardedExpression gexp : expression.expressions) {
428 for(int i=0;i<gexp.guards.length;++i) {
431 gexp.guards[i].accept(this);
434 gexp.value.accept(this);
439 public void visit(QAlternative query) {
440 b.append("QAlternative");
444 public void visit(QAtom query) {
445 if(query.relation == EqRelation.INSTANCE) {
446 query.parameters[0].accept(this);
448 query.parameters[1].accept(this);
450 else if(query.relation == MemberRelation.INSTANCE) {
451 query.parameters[0].accept(this);
453 query.parameters[1].accept(this);
456 b.append(query.relation);
457 for(Expression parameter : query.parameters) {
465 public void visit(QConjunction query) {
466 boolean first = true;
467 for(Query q : query.queries) {
477 public void visit(QDisjunction query) {
478 b.append("QDisjunction");
482 public void visit(QExists query) {
487 public void visit(QNegation query) {
488 b.append("QNegation");
492 public void visit(QMapping query) {
493 b.append(query.mappingRelation.name.name);
494 for(Expression parameter : query.parameters) {
496 parameter.accept(this);
500 public void visit(ERuleset.DatalogRule rule) {
501 b.append(rule.headRelation.getName());
502 for(Expression parameter : rule.headParameters) {
508 rule.body.accept(this);
512 public void visit(TransformationRule rule) {
513 b.append("rule ").append(rule.name.name).append(" where");
514 for(Entry<SectionName, Query[]> section : rule.sections.entrySet()) {
515 b.append("\n@").append(section.getKey().name());
516 for(Query query : section.getValue()) {
525 public void visit(ECoveringBranchPoint expression) {
526 expression.expression.accept(this);
530 public void visit(EEquations expression) {
535 public void visit(ECHRRuleset expression) {
536 b.append("ECHRRuleset");
540 public void visit(ECHRRulesetConstructor expression) {
541 b.append("ECHRRulesetConstructor");
544 public void visit(CHRRule rule) {
550 public void visit(CHRQuery query) {
551 boolean first = true;
552 for(CHRLiteral literal : query.literals) {
561 public void visit(CHRLiteral literal) {
562 if(literal.passive && literal.relation instanceof CHRConstraint)
563 b.append("@passive ");
564 if(literal.killAfterMatch)
566 b.append(literal.relation);
567 for(Expression parameter : literal.parameters) {
574 public void visit(EBinary expression) {
575 b.append("<EBinary>");
579 public void visit(EBlock expression) {
580 b.append("<EBlock>");
584 public void visit(EPreLet expression) {
585 b.append("<EPreLet>");
589 public void visit(ERange expression) {
591 expression.from.accept(this);
593 expression.to.accept(this);
598 public void visit(ERecord expression) {
599 b.append("<ERecord>");
603 public void visit(EStringLiteral expression) {
605 for(int i=0;i<expression.strings.length;++i) {
606 b.append(expression.strings[i]);
607 if(i < expression.expressions.length) {
609 expression.expressions[i].accept(this);