(refs #7375) Replaced collectFreeVariables method by a visitor
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / EIntegerLiteral.java
1 package org.simantics.scl.compiler.elaboration.expressions;
2
3
4 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
5 import org.simantics.scl.compiler.common.names.Names;
6 import org.simantics.scl.compiler.constants.DoubleConstant;
7 import org.simantics.scl.compiler.constants.FloatConstant;
8 import org.simantics.scl.compiler.constants.IntegerConstant;
9 import org.simantics.scl.compiler.constants.LongConstant;
10 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
11 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
12 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
13 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
14 import org.simantics.scl.compiler.errors.Locations;
15 import org.simantics.scl.compiler.types.Type;
16 import org.simantics.scl.compiler.types.Types;
17 import org.simantics.scl.compiler.types.exceptions.MatchException;
18
19 import gnu.trove.map.hash.TObjectIntHashMap;
20 import gnu.trove.set.hash.TIntHashSet;
21
22 public class EIntegerLiteral extends SimplifiableExpression {
23     public String value;
24     public EVariable constraint;
25
26     public EIntegerLiteral(String value) {
27         this.value = value;
28     }
29
30     @Override
31     public void collectVars(TObjectIntHashMap<Variable> allVars,
32             TIntHashSet vars) {
33     }
34     
35     public String getValue() {
36         return value;
37     }
38     
39     private Expression tryToConvertToPrimitive(Type requiredType) {
40         if(requiredType.equals(Types.INTEGER))
41             return new ELiteral(new IntegerConstant(Integer.parseInt(value)));
42         else if(requiredType.equals(Types.DOUBLE))
43             return new ELiteral(new DoubleConstant(Double.parseDouble(value)));
44         else if(requiredType.equals(Types.FLOAT))
45             return new ELiteral(new FloatConstant(Float.parseFloat(value)));
46         else if(requiredType.equals(Types.LONG))
47             return new ELiteral(new LongConstant(Long.parseLong(value)));
48         else
49             return null;
50     }
51     
52     @Override
53     public Expression checkBasicType(TypingContext context, Type requiredType) {
54         requiredType = Types.canonical(requiredType);
55         
56         try {
57             Expression primitive = tryToConvertToPrimitive(requiredType);
58             if(primitive != null)
59                 return primitive;
60         } catch(NumberFormatException e) {
61             context.getErrorLog().log(getLocation(), "Invalid number format.");
62         }
63         
64         setType(requiredType);
65         constraint = new EVariable(location, null);
66         constraint.setType(Types.pred(Types.RING, requiredType));
67         context.addConstraintDemand(constraint);
68         return this;        
69     }
70     
71     @Override
72     protected void updateType() throws MatchException {
73         throw new InternalCompilerError();
74     }
75
76     @Override
77     public Expression simplify(SimplificationContext context) {
78         try {
79             Expression primitive = tryToConvertToPrimitive(Types.canonical(getType()));
80             if(primitive != null)
81                 return primitive;
82             return context.apply(
83                     context.getConstant(Names.Prelude_fromInteger, getType()),
84                     constraint.simplify(context),
85                     context.literal(new IntegerConstant(Integer.parseInt(value)))
86                     );
87         } catch(NumberFormatException e) {
88             context.getErrorLog().log(getLocation(), "Invalid number format (maybe too long for the expected number type).");
89             return this;
90         }
91     }
92
93     @Override
94     public Expression resolve(TranslationContext context) {
95         return this;
96     }
97     
98     @Override
99     public Expression resolveAsPattern(TranslationContext context) {
100         return this;
101     }
102     
103     @Override
104     public Expression replace(ReplaceContext context) {
105         EIntegerLiteral copy = new EIntegerLiteral(value);
106         copy.setType(getType().replace(context.tvarMap));
107         copy.constraint = (EVariable)constraint.replace(context);
108         return copy;
109     }
110     
111     @Override
112     public boolean isEffectful() {
113         return false;
114     }
115     
116     @Override
117     public void setLocationDeep(long loc) {
118         if(location == Locations.NO_LOCATION) {
119             location = loc;
120             if(constraint != null)
121                 constraint.setLocationDeep(loc);
122         }
123     }
124     
125     @Override
126     public void accept(ExpressionVisitor visitor) {
127         visitor.visit(this);
128     }
129     
130     @Override
131     public boolean isPattern(int arity) {
132         return arity == 0;
133     }
134     
135     @Override
136     public Expression accept(ExpressionTransformer transformer) {
137         return transformer.transform(this);
138     }
139
140 }