summaryrefslogtreecommitdiff
path: root/src/main/java/com/seaofnodes/simple/Parser.java
diff options
context:
space:
mode:
authorDibyendu Majumdar <mobile@majumdar.org.uk>2023-10-20 15:21:08 -0700
committerDibyendu Majumdar <mobile@majumdar.org.uk>2024-10-23 17:51:09 -0700
commit83fdf059150e37c335a86e3dd4547a76a1c588db (patch)
tree7df24a5366647c8f9cf083ead43ca106f1d23430 /src/main/java/com/seaofnodes/simple/Parser.java
parent0e8916e1a4ae550357401b37df6fdca683c221f7 (diff)
downloadSimple-linear-chapter04.tar.gz
Simple-linear-chapter04.zip
Chapter 4: External Argument and Comparisonslinear-chapter04
Co-authored-by: Cliff Click <cliffc@acm.org> Co-authored-by: Yichen Yan <oraluben@outlook.com> Co-authored-by: Thalia Archibald <thalia@archibald.dev> Co-authored-by: Tamas Hadhazy <helsgithub15@gmail.com> Co-authored-by: Hels15 <helsgithub15@gmail.com> Co-authored-by: XmiliaH <45106915+XmiliaH@users.noreply.github.com>
Diffstat (limited to 'src/main/java/com/seaofnodes/simple/Parser.java')
-rw-r--r--src/main/java/com/seaofnodes/simple/Parser.java57
1 files changed, 50 insertions, 7 deletions
diff --git a/src/main/java/com/seaofnodes/simple/Parser.java b/src/main/java/com/seaofnodes/simple/Parser.java
index fa1a852c..ff2c0504 100644
--- a/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/src/main/java/com/seaofnodes/simple/Parser.java
@@ -14,6 +14,7 @@ import java.util.*;
*/
public class Parser {
+
/**
* A Global Static, unique to each compilation. This is a public, so we
* can make constants everywhere without having to thread the StartNode
@@ -27,7 +28,7 @@ public class Parser {
private final Lexer _lexer;
/**
- * Stack of lexical scopes, each scope is a symbol table that binds
+ * A ScopeNode contains a stack of lexical scopes, each scope is a symbol table that binds
* variable names to Nodes. The top of this stack represents current scope.
*/
public ScopeNode _scope;
@@ -41,18 +42,38 @@ public class Parser {
}};
- public Parser(String source) {
- _lexer = new Lexer(source);
+ public Parser(String source, TypeInteger arg) {
Node.reset();
+ _lexer = new Lexer(source);
_scope = new ScopeNode();
- START = new StartNode();
+ START = new StartNode(new Type[]{ Type.CONTROL, arg });
+ START.peephole();
+ }
+
+ public Parser(String source) {
+ this(source, TypeInteger.BOT);
}
+ @Override
+ public String toString() { return _lexer.toString(); }
+
String src() { return new String( _lexer._input ); }
+ // Debugging utility to find a Node by index
+ public static Node find(int nid) { return START.find(nid); }
+
+ private Node ctrl() { return _scope.ctrl(); }
+
+ private Node ctrl(Node n) { return _scope.ctrl(n); }
+
public ReturnNode parse() { return parse(false); }
public ReturnNode parse(boolean show) {
+ // Enter a new scope for the initial control and arguments
+ _scope.push();
+ _scope.define(ScopeNode.CTRL, new ProjNode(START, 0, ScopeNode.CTRL).peephole());
+ _scope.define(ScopeNode.ARG0, new ProjNode(START, 1, ScopeNode.ARG0).peephole());
var ret = (ReturnNode) parseBlock();
+ _scope.pop();
if (!_lexer.isEOF()) throw error("Syntax error, unexpected " + _lexer.getAnyNextToken());
if( show ) showGraph();
return ret;
@@ -99,6 +120,7 @@ public class Parser {
/**
* Parses a return statement; "return" already parsed.
+ * The $ctrl edge is killed.
*
* <pre>
* 'return' expr ;
@@ -107,7 +129,9 @@ public class Parser {
*/
private Node parseReturn() {
var expr = require(parseExpression(), ";");
- return new ReturnNode(START, expr).peephole();
+ Node ret = new ReturnNode(ctrl(), expr).peephole();
+ ctrl(null); // Kill control
+ return ret;
}
/**
@@ -158,11 +182,30 @@ public class Parser {
* Parse an expression of the form:
*
* <pre>
- * expr : additiveExpr
+ * expr : compareExpr
* </pre>
* @return an expression {@link Node}, never {@code null}
*/
- private Node parseExpression() { return parseAddition(); }
+ private Node parseExpression() { return parseComparison(); }
+
+ /**
+ * Parse an expression of the form:
+ *
+ * <pre>
+ * expr : additiveExpr op additiveExpr
+ * </pre>
+ * @return an comparator expression {@link Node}, never {@code null}
+ */
+ private Node parseComparison() {
+ var lhs = parseAddition();
+ if (match("==")) return new BoolNode.EQ(lhs, parseComparison()).peephole();
+ if (match("!=")) return new NotNode(new BoolNode.EQ(lhs, parseComparison()).peephole()).peephole();
+ if (match("<=")) return new BoolNode.LE(lhs, parseComparison()).peephole();
+ if (match("<" )) return new BoolNode.LT(lhs, parseComparison()).peephole();
+ if (match(">=")) return new BoolNode.LE(parseComparison(), lhs).peephole();
+ if (match(">" )) return new BoolNode.LT(parseComparison(), lhs).peephole();
+ return lhs;
+ }
/**
* Parse an additive expression