summaryrefslogtreecommitdiff
path: root/chapter17/src/main/java
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-09-17 16:39:32 -0700
committerCliff Click <cliffc@acm.org>2026-09-17 16:39:32 -0700
commit200162345900136663027b6deae21d72cf30818c (patch)
treea9b26f38b5f920f61837327ab56f97c5f9a01016 /chapter17/src/main/java
parent42681f41318796afc58bc14ce04620b7c5c7eb18 (diff)
downloadSimple-200162345900136663027b6deae21d72cf30818c.tar.gz
Simple-200162345900136663027b6deae21d72cf30818c.zip
Backport string escapes and many op-assign
Diffstat (limited to 'chapter17/src/main/java')
-rw-r--r--chapter17/src/main/java/com/seaofnodes/simple/Parser.java26
-rw-r--r--chapter17/src/main/java/com/seaofnodes/simple/node/ShrNode.java5
2 files changed, 24 insertions, 7 deletions
diff --git a/chapter17/src/main/java/com/seaofnodes/simple/Parser.java b/chapter17/src/main/java/com/seaofnodes/simple/Parser.java
index adc47edc..789eea19 100644
--- a/chapter17/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter17/src/main/java/com/seaofnodes/simple/Parser.java
@@ -916,13 +916,19 @@ public class Parser {
if( n._final )
throw error("Cannot reassign final '"+n._name+"'");
Node op = switch(ch) {
- case '+' -> new AddNode(rvalue,null);
- case '-' -> new SubNode(rvalue,null);
- case '*' -> new MulNode(rvalue,null);
- case '/' -> new DivNode(rvalue,null);
- case 1 -> new AddNode(rvalue,con( 1));
- case (char)-1 -> new AddNode(rvalue,con(-1));
- default -> throw Utils.TODO();
+ case '+' -> new AddNode(rvalue,null);
+ case '-' -> new SubNode(rvalue,null);
+ case '*' -> new MulNode(rvalue,null);
+ case '/' -> new DivNode(rvalue,null);
+ case '&' -> new AndNode(rvalue,null);
+ case '|' -> new OrNode(rvalue,null);
+ case '^' -> new XorNode(rvalue,null);
+ case Lexer.SHL -> new ShlNode(rvalue,null);
+ case Lexer.SAR -> new SarNode(rvalue,null);
+ case Lexer.SHR -> new ShrNode(rvalue,null);
+ case 1 -> new AddNode(rvalue,con( 1));
+ case (char)-1 -> new AddNode(rvalue,con(-1));
+ default -> throw Utils.TODO();
};
// Return pre-value (x+=1) or post-value (x++)
boolean pre = op.in(2)==null;
@@ -1403,8 +1409,14 @@ public class Parser {
// Next oper= character, or 0.
// As a convenience, mark "++" as a char 1 and "--" as char -1 (65535)
// Disallow e.g. "arg--1" which should parse as "arg - -1"
+ // Distinct tags for the multi-character compound operators.
+ static final char SHL = 2, SAR = 3, SHR = 4;
+
public char matchOperAssign() {
skipWhiteSpace();
+ if( match("<<=" ) ) return SHL;
+ if( match(">>>=") ) return SHR;
+ if( match(">>=" ) ) return SAR;
if( _position+2 >= _input.length ) return 0;
char ch0 = (char)_input[_position];
if( "+-/*&|^".indexOf(ch0) == -1 ) return 0;
diff --git a/chapter17/src/main/java/com/seaofnodes/simple/node/ShrNode.java b/chapter17/src/main/java/com/seaofnodes/simple/node/ShrNode.java
index 22eb45a0..779193de 100644
--- a/chapter17/src/main/java/com/seaofnodes/simple/node/ShrNode.java
+++ b/chapter17/src/main/java/com/seaofnodes/simple/node/ShrNode.java
@@ -49,4 +49,9 @@ public class ShrNode extends Node {
return null;
}
@Override Node copy(Node lhs, Node rhs) { return new ShrNode(lhs,rhs); }
+ @Override String err() {
+ if( !(in(1)._type instanceof TypeInteger) ) return "Cannot '>>>' " + in(1)._type;
+ if( !(in(2)._type instanceof TypeInteger) ) return "Cannot '>>>' " + in(2)._type;
+ return null;
+ }
}