]> gerrit.simantics Code Review - simantics/platform.git/blob
17cf6e58edb59a23b6601f087595dd8d1df8b725
[simantics/platform.git] /
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.THashSet;
21 import gnu.trove.set.hash.TIntHashSet;
22
23 public class EIntegerLiteral extends SimplifiableExpression {
24     public String value;
25     EVariable constraint;
26
27     public EIntegerLiteral(String value) {
28         this.value = value;
29     }
30
31     @Override
32     public void collectRefs(TObjectIntHashMap<Object> allRefs,
33             TIntHashSet refs) {
34     }
35
36     @Override
37     public void collectVars(TObjectIntHashMap<Variable> allVars,
38             TIntHashSet vars) {
39     }
40     
41     public String getValue() {
42         return value;
43     }
44     
45     private Expression tryToConvertToPrimitive(Type requiredType) {
46         if(requiredType.equals(Types.INTEGER))
47             return new ELiteral(new IntegerConstant(Integer.parseInt(value)));
48         else if(requiredType.equals(Types.DOUBLE))
49             return new ELiteral(new DoubleConstant(Double.parseDouble(value)));
50         else if(requiredType.equals(Types.FLOAT))
51             return new ELiteral(new FloatConstant(Float.parseFloat(value)));
52         else if(requiredType.equals(Types.LONG))
53             return new ELiteral(new LongConstant(Long.parseLong(value)));
54         else
55             return null;
56     }
57     
58     @Override
59     public Expression checkBasicType(TypingContext context, Type requiredType) {
60         requiredType = Types.canonical(requiredType);
61         
62         try {
63             Expression primitive = tryToConvertToPrimitive(requiredType);
64             if(primitive != null)
65                 return primitive;
66         } catch(NumberFormatException e) {
67             context.getErrorLog().log(getLocation(), "Invalid number format.");
68         }
69         
70         setType(requiredType);
71         constraint = new EVariable(location, null);
72         constraint.setType(Types.pred(Types.RING, requiredType));
73         context.addConstraintDemand(constraint);
74         return this;        
75     }
76     
77     @Override
78     protected void updateType() throws MatchException {
79         throw new InternalCompilerError();
80     }
81
82     @Override
83     public void collectFreeVariables(THashSet<Variable> vars) {
84     }
85
86     @Override
87     public Expression simplify(SimplificationContext context) {
88         try {
89             Expression primitive = tryToConvertToPrimitive(Types.canonical(getType()));
90             if(primitive != null)
91                 return primitive;
92             return context.apply(
93                     context.getConstant(Names.Prelude_fromInteger, getType()),
94                     constraint.simplify(context),
95                     context.literal(new IntegerConstant(Integer.parseInt(value)))
96                     );
97         } catch(NumberFormatException e) {
98             context.getErrorLog().log(getLocation(), "Invalid number format (maybe too long for the expected number type).");
99             return this;
100         }
101     }
102
103     @Override
104     public Expression resolve(TranslationContext context) {
105         return this;
106     }
107     
108     @Override
109     public Expression resolveAsPattern(TranslationContext context) {
110         return this;
111     }
112     
113     @Override
114     public Expression replace(ReplaceContext context) {
115         EIntegerLiteral copy = new EIntegerLiteral(value);
116         copy.setType(getType().replace(context.tvarMap));
117         copy.constraint = (EVariable)constraint.replace(context);
118         return copy;
119     }
120     
121     @Override
122     public boolean isEffectful() {
123         return false;
124     }
125
126     @Override
127     public void collectEffects(THashSet<Type> effects) {
128     }
129     
130     @Override
131     public void setLocationDeep(long loc) {
132         if(location == Locations.NO_LOCATION) {
133             location = loc;
134             if(constraint != null)
135                 constraint.setLocationDeep(loc);
136         }
137     }
138     
139     @Override
140     public void accept(ExpressionVisitor visitor) {
141         visitor.visit(this);
142     }
143
144     @Override
145     public void forVariables(VariableProcedure procedure) {
146         if(constraint != null)
147             constraint.forVariables(procedure);
148     }
149     
150     @Override
151     public boolean isPattern(int arity) {
152         return arity == 0;
153     }
154     
155     @Override
156     public Expression accept(ExpressionTransformer transformer) {
157         return transformer.transform(this);
158     }
159
160 }