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