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