summaryrefslogtreecommitdiff
path: root/chapter22
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-05-10 10:55:15 -0700
committerCliff Click <cliffc@acm.org>2025-05-10 10:55:15 -0700
commit288912d2a84d035730cad405e32a6afa5dd4f9c6 (patch)
tree30011f79d371d5f6f8ad8a3d869eccf22352b3e9 /chapter22
parentb4eb623979cc9566d2a22c718b4ba8ded3bca5a4 (diff)
downloadSimple-288912d2a84d035730cad405e32a6afa5dd4f9c6.tar.gz
Simple-288912d2a84d035730cad405e32a6afa5dd4f9c6.zip
Move sys.smp to smp directory
Diffstat (limited to 'chapter22')
-rw-r--r--chapter22/README.md2
-rw-r--r--chapter22/docs/examples/BubbleSort.smp3
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/Parser.java3
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/sys.java (renamed from chapter22/src/main/java/com/seaofnodes/simple/sys/sys.java)4
-rw-r--r--chapter22/src/main/smp/sys.smp57
5 files changed, 64 insertions, 5 deletions
diff --git a/chapter22/README.md b/chapter22/README.md
index 7482fc70..844129d2 100644
--- a/chapter22/README.md
+++ b/chapter22/README.md
@@ -15,7 +15,7 @@ Let's break it down.
- `sys`: is Just A Variable Name. Like other variables, it is looked up in the
current scope... which looks completely empty. Every Simple program now starts
with the `sys` variable in-scope. `sys` itself a normal `struct`
- and is defined in `src/main/java/com/seaofnodes/simple/sys/sys.smp`.
+ and is defined in `src/main/smp/sys.smp`.
- `sys.io.p`: lookup the `io` field in `sys` struct, which yields the `sys.io`
struct; then a lookup of `p` (short for "print") in the `sys.io` struct.
This returns a function.
diff --git a/chapter22/docs/examples/BubbleSort.smp b/chapter22/docs/examples/BubbleSort.smp
index a80d6bd8..aa9cbbb8 100644
--- a/chapter22/docs/examples/BubbleSort.smp
+++ b/chapter22/docs/examples/BubbleSort.smp
@@ -5,10 +5,12 @@
//
// Bubble sort, with reading (parsing) and writing (formatting) the data.
+
val _exit = { u8[~] msg ->
sys.io.p(msg);
sys.libc._exit(1);
};
+
val usage = { -> _exit("stdin must look like [4, 3, 2, 1]"); };
// Scanner
@@ -23,6 +25,7 @@ val skip = { Scan s ->
s.x++;
};
+
// Require specific syntax or usage
val require = { Scan s, u8 c ->
skip(s);
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java
index 9c22fc43..d0ef5d49 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java
@@ -141,7 +141,7 @@ public class Parser {
_scope.mem(new MemMergeNode(false));
// Parse the sys import
- _lexer = new Lexer(com.seaofnodes.simple.sys.sys.SYS);
+ _lexer = new Lexer(com.seaofnodes.simple.sys.SYS);
while( !_lexer.isEOF() ) {
parseStatement();
_lexer.skipWhiteSpace();
@@ -795,7 +795,6 @@ public class Parser {
while (!peek('}') && !_lexer.isEOF())
parseStatement().isKill();
-
// Grab the declarations and build fields and a Struct
int lexlen = _scope._lexSize.last();
int varlen = _scope._vars._len;
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/sys/sys.java b/chapter22/src/main/java/com/seaofnodes/simple/sys.java
index 399e7cb7..45106770 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/sys/sys.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/sys.java
@@ -1,4 +1,4 @@
-package com.seaofnodes.simple.sys;
+package com.seaofnodes.simple;
import java.io.IOException;
import java.nio.file.Files;
@@ -15,7 +15,7 @@ public abstract class sys {
static {
try {
- SYS = Files.readString(Path.of("src/main/java/com/seaofnodes/simple/sys/sys.smp"));
+ SYS = Files.readString(Path.of("src/main/smp/sys.smp"));
}
catch( Exception e ) {
throw new RuntimeException(e);
diff --git a/chapter22/src/main/smp/sys.smp b/chapter22/src/main/smp/sys.smp
new file mode 100644
index 00000000..ede08d63
--- /dev/null
+++ b/chapter22/src/main/smp/sys.smp
@@ -0,0 +1,57 @@
+// -*- mode: java; -*-
+
+// top-level default import
+struct sys {
+ // libc bindings
+ /** https://www.man7.org/linux/man-pages/man2/<libc call>.2.html */
+ struct libc {
+ i32 errno = "C";
+ // fd buf len -> len
+ { i32 i64 u32 -> u32 } write = "C";
+ // fd buf len -> len
+ { i32 i64 u32 -> u32 } read = "C";
+ // status
+ { i32 -> i32 } _exit = "C";
+ // addr len prot flags fd off -> void*
+ { i64 i64 i32 i32 i32 i32 -> i64 } mmap = "C";
+ // mmap flags
+ i32 PROT_EXEC = 4;
+ i32 PROT_READ = 1;
+ i32 PROT_WRITE= 2;
+ i32 PROT_NONE = 0;
+ i32 MAP_PRIVATE = 2;
+ i32 MAP_ANON = 32;
+ };
+ struct ary {
+ val copy = { u8[] dst, int doff, u8[~] src, int soff, int len ->
+ for( int i=0; i<len; i++ )
+ dst[i+doff] = src[i+soff];
+ return dst;
+ };
+ };
+ struct io {
+ // Print string to stdout
+ val p = { u8[~] str ->
+ i64 ptr = str; // cast array base to i64
+ return sys.libc.write(1,ptr,str#);
+ };
+
+ // Return stdin as a u8[]
+ val stdin = { ->
+ var buf = new u8[8*1024];
+ i64 ptr = buf;
+ int len = 0;
+ while( true ) {
+ int rez = sys.libc.read(0,ptr,buf#);
+ if( rez < 0 ) sys.libc._exit(sys.libc.errno);
+ len += rez;
+ if( rez < buf# )
+ break;
+ sys.libc._exit(-2); // Need to implement
+ }
+ // Compress
+ var dst = new u8[len];
+ return sys.ary.copy(dst,0,buf,0,len);
+ };
+ };
+};