From efc81d5afc9983258db267894ce3f141962793a5 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Thu, 7 Nov 2024 16:30:43 -0800 Subject: var/val --- .../src/main/java/com/seaofnodes/simple/Parser.java | 16 ++++++++++++++-- .../main/java/com/seaofnodes/simple/node/MinusNode.java | 5 ++++- 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'chapter17/src/main/java') diff --git a/chapter17/src/main/java/com/seaofnodes/simple/Parser.java b/chapter17/src/main/java/com/seaofnodes/simple/Parser.java index abd70f89..fac012a4 100644 --- a/chapter17/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter17/src/main/java/com/seaofnodes/simple/Parser.java @@ -141,6 +141,8 @@ public class Parser { put("u16" ,TypeInteger.U16); put("u32" ,TypeInteger.U32); put("u8" ,TypeInteger.U8 ); + put("val" ,Type.TOP); // Marker type, indicates type inference + put("var" ,Type.BOTTOM); // Marker type, indicates type inference }}; } @@ -422,6 +424,8 @@ public class Parser { ? Type.TOP // Else takes the default : t.makeInit(); + // "var" and "val" require an expression to infer + if( init == null ) throw errorSyntax("expression"); expr = con(init); } else if( !match("=") ) { // Something else @@ -453,6 +457,9 @@ public class Parser { Type e = expr._type; if( e instanceof TypeMemPtr tmp && tmp._obj._fields==null ) e = TYPES.get(tmp._obj._name); + // "var" and "val" use TOP and BOTTOM - but just take the expression type. + if( t==Type.TOP || t==Type.BOTTOM ) + t = expr._type.glb(); // Type is sane if( !e.isa(t) ) throw error("Type " + e.str() + " is not of declared type " + t.str()); @@ -468,7 +475,9 @@ public class Parser { /** Parse final: [!]asgn */ private Node parseFinal(Type t) { - boolean xfinal = t!=null && match("!"); + // TOP is a "val" marker - uses type inference for a "value", i.e. a final. + // BOT is a "var" marker - uses type inference for a "variable", i.e. not final + boolean xfinal = t==Type.TOP || (t!=null && match("!")); return parseAsgn(t,xfinal); } @@ -761,8 +770,11 @@ public class Parser { // Expect an identifier now ScopeMinNode.Var n = requireLookupId("an identifier or expression"); Node rvalue = _scope.in(n).keep(); - if( matchx("++") || matchx("--") ) + if( matchx("++") || matchx("--") ) { + if( n._final ) + throw error("Cannot reassign final '"+n._name+"'"); _scope.update(n,new AddNode(rvalue,con( _lexer.peek(-1)=='+' ? 1 : -1)).peephole()); + } return rvalue.unkeep(); } diff --git a/chapter17/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter17/src/main/java/com/seaofnodes/simple/node/MinusNode.java index 8a2c9406..760a4274 100644 --- a/chapter17/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter17/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -2,6 +2,7 @@ package com.seaofnodes.simple.node; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeInteger; +import com.seaofnodes.simple.Utils; import java.util.BitSet; @@ -22,7 +23,9 @@ public class MinusNode extends Node { public Type compute() { if( in(1)._type instanceof TypeInteger i0 ) { if( i0.isHigh() ) return TypeInteger.TOP; - return i0==TypeInteger.BOT ? TypeInteger.BOT : TypeInteger.make(-i0._max,-i0._min); + if( i0==TypeInteger.BOT || i0._min == Long.MIN_VALUE || i0._max == Long.MIN_VALUE ) + return TypeInteger.BOT; + return TypeInteger.make(-i0._max,-i0._min); } return TypeInteger.TOP.meet(in(1)._type); } -- cgit v1.2.3