diff options
| author | Cliff Click <cliffc@acm.org> | 2024-11-07 15:19:19 -0800 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2024-11-23 09:03:20 -0800 |
| commit | 6d96985f9d297f6dee9ee6f877b9986dec797d4c (patch) | |
| tree | 79db56ad23fb9ab16824d82a03d0821a897c5294 /chapter17/src/main/java | |
| parent | 2d6ee0da8228e0b53a7387c964d74b28aa58c8f3 (diff) | |
| download | Simple-6d96985f9d297f6dee9ee6f877b9986dec797d4c.tar.gz Simple-6d96985f9d297f6dee9ee6f877b9986dec797d4c.zip | |
Support post ++ on arrays and structs
Diffstat (limited to 'chapter17/src/main/java')
| -rw-r--r-- | chapter17/src/main/java/com/seaofnodes/simple/Parser.java | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/chapter17/src/main/java/com/seaofnodes/simple/Parser.java b/chapter17/src/main/java/com/seaofnodes/simple/Parser.java index 9710be30..abd70f89 100644 --- a/chapter17/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter17/src/main/java/com/seaofnodes/simple/Parser.java @@ -761,8 +761,8 @@ public class Parser { // Expect an identifier now ScopeMinNode.Var n = requireLookupId("an identifier or expression"); Node rvalue = _scope.in(n).keep(); - if( matchx("++") ) _scope.update(n,new AddNode(rvalue,con( 1)).peephole()); - if( matchx("--") ) _scope.update(n,new AddNode(rvalue,con(-1)).peephole()); + if( matchx("++") || matchx("--") ) + _scope.update(n,new AddNode(rvalue,con( _lexer.peek(-1)=='+' ? 1 : -1)).peephole()); return rvalue.unkeep(); } @@ -907,24 +907,24 @@ public class Parser { // Get field type and layout offset from base type and field index fidx Field f = base._fields[fidx]; // Field from field index - Node off = name.equals("[]") // If field is an array body + Node off = (name.equals("[]") // If field is an array body // Array index math ? new AddNode(con(base.aryBase()),new ShlNode(require(parseExpression(),"]"),con(base.aryScale())).peephole()).peephole() // Struct field offsets are hardwired - : con(base.offset(fidx)); + : con(base.offset(fidx))).keep(); // Disambiguate "obj.fld==x" boolean test from "obj.fld=x" field assignment if( matchOpx('=','=') ) { Node val = parseExpression(); // Auto-truncate when storing to narrow fields - val = zsMask(val,f._type); - Node st = new StoreNode(name, f._alias, f._type, memAlias(f._alias), expr, off, val, false); + val = zsMask(val,f._type).keep(); + Node st = new StoreNode(name, f._alias, f._type, memAlias(f._alias), expr, off.unkeep(), val, false); // Arrays include control, as a proxy for a safety range check. // Structs don't need this; they only need a NPE check which is // done via the type system. if( base.isAry() ) st.setDef(0,ctrl()); memAlias(f._alias, st.peephole()); - return val; // "obj.a = expr" returns the expression while updating memory + return val.unkeep(); // "obj.a = expr" returns the expression while updating memory } Node load = new LoadNode(name, f._alias, f._type.glb(), memAlias(f._alias), expr, off); @@ -932,7 +932,23 @@ public class Parser { // Structs don't need this; they only need a NPE check which is // done via the type system. if( base.isAry() ) load.setDef(0,ctrl()); - return parsePostfix(load.peephole()); + load = load.peephole(); + + // ary[idx]++ + if( matchx("++") || matchx("--") ) { + Node inc = new AddNode(load,con( _lexer.peek(-1)=='+' ? 1 : -1)).peephole(); + Node val = zsMask(inc,f._type); + Node st = new StoreNode(name, f._alias, f._type, memAlias(f._alias), expr, off, val, false); + // Arrays include control, as a proxy for a safety range check. + // Structs don't need this; they only need a NPE check which is + // done via the type system. + if( base.isAry() ) st.setDef(0,ctrl()); + memAlias(f._alias, st.peephole()); + // And use the original loaded value as the result + } + if( off.unkeep().isDead() ) off.kill(); + + return parsePostfix(load); } @@ -1044,6 +1060,8 @@ public class Parser { return isEOF() ? Character.MAX_VALUE // Special value that causes parsing to terminate : (char) _input[_position]; } + // Just crash if misused + public byte peek(int off) { return _input[_position+off]; } private char nextChar() { char ch = peek(); |
