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