summaryrefslogtreecommitdiff
path: root/chapter18/src/main
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2024-12-22 10:28:32 -0800
committerCliff Click <cliffc@acm.org>2025-01-15 15:07:30 -0800
commitfcd6dcf5265b4b23fd69af761316c064b8f9f7ce (patch)
tree038146e9f3b5f58ff770a5d4e51f6ed0d6d4e2bd /chapter18/src/main
parente58920741c38043f3f257ef088ca330893b7c84c (diff)
downloadSimple-fcd6dcf5265b4b23fd69af761316c064b8f9f7ce.tar.gz
Simple-fcd6dcf5265b4b23fd69af761316c064b8f9f7ce.zip
Intercept first function definition
Diffstat (limited to 'chapter18/src/main')
-rw-r--r--chapter18/src/main/java/com/seaofnodes/simple/Parser.java37
-rw-r--r--chapter18/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java14
2 files changed, 48 insertions, 3 deletions
diff --git a/chapter18/src/main/java/com/seaofnodes/simple/Parser.java b/chapter18/src/main/java/com/seaofnodes/simple/Parser.java
index 1105c2b7..7301f63b 100644
--- a/chapter18/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter18/src/main/java/com/seaofnodes/simple/Parser.java
@@ -955,8 +955,9 @@ public class Parser {
if( matchx("true" ) ) return con(1);
if( matchx("false") ) return ZERO;
if( matchx("null" ) ) return NIL;
- if( match("(") ) return require(parseAsgn(), ")");
+ if( match ("(" ) ) return require(parseAsgn(), ")");
if( matchx("new" ) ) return alloc();
+ if( match ("{" ) ) return func();
// Expect an identifier now
ScopeMinNode.Var n = requireLookupId("an identifier or expression");
Node rvalue = _scope.in(n);
@@ -1091,8 +1092,8 @@ public class Parser {
public static String memName(int alias) { return ("$"+alias).intern(); }
/**
- * Parse postfix expression. For now this is just a field
- * expression, but in future could be array index too.
+ * Parse postfix expression; this can be a field expression, an array
+ * lookup or a postfix operator like '#'
*
* <pre>
* expr ('.' IDENTIFIER)* [ = expr ]
@@ -1202,6 +1203,36 @@ public class Parser {
return peep(new SarNode(peep(new ShlNode(val,shf.keep())),shf.unkeep()));
}
+ /**
+ * Parse a function; the leading '{' is already parsed.
+ *
+ * <pre>
+ * { [type arg,]* -> expr }
+ * { expr } // The no-argument function
+ * </pre>
+ */
+ private Node func() {
+ int old = pos(); // Record lexer position
+ Ary<Type> ts = new Ary<>(Type.class);
+ Ary<String> ids = new Ary<>(String.class);
+ ts .push(Type.BOTTOM); // Return type, unknown yet
+ ids.push(null); // Not an argument
+ while( true ) {
+ Type t = type(); // Arg type
+ if( t==null ) break;
+ String id = requireId();
+ ts .push(t ); // Push type/arg pairs
+ ids.push(id);
+ match(",");
+ }
+ require("->");
+ // Make a concrete function type, with a fidx
+ TypeFunPtr tfp = TypeFunPtr.makeFun(TypeTuple.make(ts.asAry()));
+ //FunNode fun = (FunNode)peep(new FunNode());
+
+ throw Utils.TODO();
+ }
+
/**
* Parse integer literal
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 0c66c20c..f1a16de4 100644
--- a/chapter18/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java
+++ b/chapter18/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java
@@ -3,6 +3,7 @@ package com.seaofnodes.simple.type;
import com.seaofnodes.simple.SB;
import com.seaofnodes.simple.Utils;
import java.util.ArrayList;
+import java.util.HashMap;
/**
* Represents a Pointer to a function.
@@ -35,6 +36,19 @@ public class TypeFunPtr extends TypeNil {
public static TypeFunPtr make( boolean nil, TypeTuple sig ) { return make((byte)(nil ? 3 : 2),sig,-1); }
@Override TypeFunPtr makeFrom( byte nil ) { return nil==_nil ? this : make(nil,_sig,_fidxs); }
+ // Compute "function indices": FIDX
+ private static final HashMap<TypeTuple,Integer> FIDXS = new HashMap<>();
+ private static int nextFIDX(TypeTuple sig) {
+ Integer i = FIDXS.get(sig);
+ int fidx = i==null ? 0 : i;
+ FIDXS.put(sig,fidx+1); // Track count per sig
+ assert fidx<64; // TODO: need a larger FIDX space
+ return fidx; // Return
+ }
+ public static TypeFunPtr makeFun( TypeTuple sig ) {
+ return make((byte)2,sig,1L<<nextFIDX(sig));
+ }
+
public static TypeFunPtr BOT = make((byte)3,TypeTuple.SIGBOT,-1);
public static TypeFunPtr TEST = make((byte)2,TypeTuple.SIGTEST,1);
public static TypeFunPtr TEST0 = make((byte)3,TypeTuple.SIGTEST,3);