summaryrefslogtreecommitdiff
path: root/chapter18/src/main/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'chapter18/src/main/java/com')
-rw-r--r--chapter18/src/main/java/com/seaofnodes/simple/Parser.java22
-rw-r--r--chapter18/src/main/java/com/seaofnodes/simple/node/CastNode.java10
-rw-r--r--chapter18/src/main/java/com/seaofnodes/simple/node/FRefNode.java2
-rw-r--r--chapter18/src/main/java/com/seaofnodes/simple/node/StoreNode.java1
-rw-r--r--chapter18/src/main/java/com/seaofnodes/simple/node/ToFloatNode.java7
-rw-r--r--chapter18/src/main/java/com/seaofnodes/simple/type/TypeFloat.java1
-rw-r--r--chapter18/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java11
7 files changed, 39 insertions, 15 deletions
diff --git a/chapter18/src/main/java/com/seaofnodes/simple/Parser.java b/chapter18/src/main/java/com/seaofnodes/simple/Parser.java
index 2d98287d..d888f17e 100644
--- a/chapter18/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter18/src/main/java/com/seaofnodes/simple/Parser.java
@@ -651,7 +651,7 @@ public class Parser {
// Auto-narrow wide ints to narrow ints
expr = zsMask(expr,t);
// Type is sane
- if( !expr._type.isa(t) )
+ if( expr._type!=Type.BOTTOM && !expr._type.isa(t) )
throw error("Type " + expr._type.str() + " is not of declared type " + t.str());
return expr;
}
@@ -711,14 +711,16 @@ public class Parser {
if( inferType && !_scope.inCon() )
throw errorSyntax("=expression");
// Initial value for uninitialized struct fields.
- expr = t instanceof TypeMemPtr tn
+ expr = switch( t ) {
// Nullable pointers get a NIL; not-null get a TOP which
// signals that they *must* be initialized in the constructor.
- ? (tn.nullable() ? NIL : con(Type.TOP))
- // Bottom signals type inference: they must be initialized in
- // the constructor and that's when we'll discover the type.
- // Otherwise, its an Integer and use 0.
- : (t==Type.BOTTOM ? con(t) : (t instanceof TypeInteger ? ZERO : con(TypeFloat.FZERO)));
+ case TypeNil tn -> tn.nullable() ? NIL : con(Type.TOP);
+ case TypeInteger ti -> ZERO;
+ case TypeFloat tf -> con(TypeFloat.FZERO);
+ // Bottom signals type inference: they must be initialized in
+ // the constructor and that's when we'll discover the type.
+ case Type tt -> { assert tt==Type.BOTTOM; yield con(tt); }
+ };
}
// Lift expression, based on type
@@ -727,6 +729,10 @@ public class Parser {
if( xfinal && t instanceof TypeMemPtr tmp )
t = tmp.makeRO();
+ // Lift type to the declaration. This will report as an error later if
+ // we cannot lift the type.
+ if( !lift._type.isa(t) )
+ lift = peep(new CastNode(t,null,lift));
// Define a new name
if( !_scope.define(name,t,xfinal,lift, loc) )
throw error("Redefining name '" + name + "'", loc);
@@ -1356,7 +1362,7 @@ public class Parser {
private Node functionCall(Node expr) {
if( expr._type == Type.NIL )
throw error("Calling a null function pointer");
- if( !expr._type.isa(TypeFunPtr.BOT) )
+ if( !(expr instanceof FRefNode) && !expr._type.isa(TypeFunPtr.BOT) )
throw error("Expected a function but got "+expr._type.glb().str());
expr.keep(); // Keep while parsing args
diff --git a/chapter18/src/main/java/com/seaofnodes/simple/node/CastNode.java b/chapter18/src/main/java/com/seaofnodes/simple/node/CastNode.java
index 98d0ac71..d8a968c1 100644
--- a/chapter18/src/main/java/com/seaofnodes/simple/node/CastNode.java
+++ b/chapter18/src/main/java/com/seaofnodes/simple/node/CastNode.java
@@ -1,5 +1,7 @@
package com.seaofnodes.simple.node;
+import com.seaofnodes.simple.Parser;
+import com.seaofnodes.simple.Utils;
import com.seaofnodes.simple.type.Type;
import com.seaofnodes.simple.type.TypeInteger;
import java.util.BitSet;
@@ -45,4 +47,12 @@ public class CastNode extends Node {
@Override
int hash() { return _t.hashCode(); }
+
+ @Override
+ public Parser.ParseException err() {
+ // Has a condition to test, so OK
+ if( in(0) != null ) return null;
+ // No condition to test, so this must optimize away
+ throw Utils.TODO();
+ }
}
diff --git a/chapter18/src/main/java/com/seaofnodes/simple/node/FRefNode.java b/chapter18/src/main/java/com/seaofnodes/simple/node/FRefNode.java
index beb14870..f0c4045d 100644
--- a/chapter18/src/main/java/com/seaofnodes/simple/node/FRefNode.java
+++ b/chapter18/src/main/java/com/seaofnodes/simple/node/FRefNode.java
@@ -11,7 +11,7 @@ import java.util.BitSet;
* peepholes to the Def.
*/
public class FRefNode extends ConstantNode {
- public static final Type FREF_TYPE = Type.TOP;
+ public static final Type FREF_TYPE = Type.BOTTOM;
public final Var _n;
public FRefNode( Var n ) { super(FREF_TYPE); _n = n; }
diff --git a/chapter18/src/main/java/com/seaofnodes/simple/node/StoreNode.java b/chapter18/src/main/java/com/seaofnodes/simple/node/StoreNode.java
index 576f8d92..ccabadb4 100644
--- a/chapter18/src/main/java/com/seaofnodes/simple/node/StoreNode.java
+++ b/chapter18/src/main/java/com/seaofnodes/simple/node/StoreNode.java
@@ -43,6 +43,7 @@ public class StoreNode extends MemOpNode {
public Type compute() {
Type val = val()._type;
TypeMem mem = (TypeMem)mem()._type; // Invariant
+ if( mem == TypeMem.TOP ) return TypeMem.TOP;
Type t = Type.BOTTOM; // No idea on field contents
// Same alias, lift val to the declared type and then meet into other fields
if( mem._alias == _alias ) {
diff --git a/chapter18/src/main/java/com/seaofnodes/simple/node/ToFloatNode.java b/chapter18/src/main/java/com/seaofnodes/simple/node/ToFloatNode.java
index 0661ac2c..1f4d67e0 100644
--- a/chapter18/src/main/java/com/seaofnodes/simple/node/ToFloatNode.java
+++ b/chapter18/src/main/java/com/seaofnodes/simple/node/ToFloatNode.java
@@ -21,8 +21,11 @@ public class ToFloatNode extends Node {
@Override
public Type compute() {
if( in(1)._type == Type.NIL ) return TypeFloat.FZERO;
- if (in(1)._type instanceof TypeInteger i0 && i0.isConstant() )
- return TypeFloat.constant(i0.value());
+ if (in(1)._type instanceof TypeInteger i0 ) {
+ if( i0.isHigh() ) return TypeFloat.F64.dual();
+ if( i0.isConstant() )
+ return TypeFloat.constant(i0.value());
+ }
return TypeFloat.F64;
}
diff --git a/chapter18/src/main/java/com/seaofnodes/simple/type/TypeFloat.java b/chapter18/src/main/java/com/seaofnodes/simple/type/TypeFloat.java
index 258cda03..aa205149 100644
--- a/chapter18/src/main/java/com/seaofnodes/simple/type/TypeFloat.java
+++ b/chapter18/src/main/java/com/seaofnodes/simple/type/TypeFloat.java
@@ -47,6 +47,7 @@ public class TypeFloat extends Type {
}
private boolean isF32() { return ((float)_con)==_con; }
+ @Override public boolean isHigh () { return _sz< 0; }
@Override public boolean isConstant() { return _sz==0; }
@Override public int log_size() { return _sz==32 || _sz==-32 ? 2 : 3; }
diff --git a/chapter18/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java b/chapter18/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java
index 78a94dff..5799fea9 100644
--- a/chapter18/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java
+++ b/chapter18/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java
@@ -63,7 +63,7 @@ public class TypeFunPtr extends TypeNil {
@Override
Type xmeet(Type t) {
TypeFunPtr that = (TypeFunPtr) t;
- return TypeFunPtr.make(xmeet0(that),(TypeTuple)_sig.meet(that._sig), _ret.meet(that._ret),_fidxs | that._fidxs);
+ return TypeFunPtr.make(xmeet0(that),(TypeTuple)_sig.meet(that._sig), _ret.meet(that._ret), _fidxs | that._fidxs);
}
@Override
@@ -94,8 +94,9 @@ public class TypeFunPtr extends TypeNil {
public TypeFunPtr setName(String name) {
if( name==null ) return this;
- assert _name==null || _name.equals(name);
assert _fidxs > 0 && Long.bitCount(_fidxs) == 1;
+ // Name can be set to different things, just for debug
+ //assert _name==null || _name.equals(name);
_name = name;
return this;
}
@@ -109,9 +110,11 @@ public class TypeFunPtr extends TypeNil {
sb.p(x()).p("{ ");
if( n && _name!=null ) sb.p(_name);
else {
- for( Type t : _sig._types )
- _print(sb,g,t).p(" ");
+ if( _sig._types!=null )
+ for( Type t : _sig._types )
+ _print(sb,g,t).p(" ");
_print(sb.p(g ? "&rarr; " : "-> "),g,_ret).p(" #");
+ if( isHigh() ) sb.p("~");
long fidxs = isHigh() ? ~_fidxs : _fidxs;
String fidx = fidxs==0 ? ""
: Long.bitCount(fidxs) == 1 ? ""+Long.numberOfTrailingZeros(fidxs)