diff options
| author | Cliff Click <cliffc@acm.org> | 2026-11-01 10:33:55 -0800 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-11-01 10:33:55 -0800 |
| commit | f4bd723d929e53475f7990374dca7b7dfcbbdc42 (patch) | |
| tree | 7bb080119e7b88ad4ac9b30af019fe6a5e4ba9dd /chapter29/src/test/smp | |
| parent | 0ac0c9e10287972ac3af5a4ee43d26f0d5b318fe (diff) | |
| download | Simple-main.tar.gz Simple-main.zip | |
Add Chapter 29 for tech debt cleanup with the parser splitmain
Keep Chapter 28b intact and carry the grammar-oriented parser package, Var move, IterPeeps move, and parser regression tests into Chapter 29. Defer privacy and exclude its experimental tests and fixture changes.
Register the chapter in the indexes, IntelliJ modules and run configurations, Maven reactor, roadmap, and linear-history publisher. Windows and Linux each pass 573 tests, release builds, 199 allocation replays, and 29 native checks.
Diffstat (limited to 'chapter29/src/test/smp')
| -rw-r--r-- | chapter29/src/test/smp/examples/A_helloWorld.smp | 2 | ||||
| -rw-r--r-- | chapter29/src/test/smp/examples/BubbleSort.smp | 36 | ||||
| -rw-r--r-- | chapter29/src/test/smp/examples/Capitalize.smp | 22 | ||||
| -rw-r--r-- | chapter29/src/test/smp/examples/Dijkstra.smp | 72 | ||||
| -rw-r--r-- | chapter29/src/test/smp/examples/FileIO.smp | 50 | ||||
| -rw-r--r-- | chapter29/src/test/smp/lazy/App.smp | 3 | ||||
| -rw-r--r-- | chapter29/src/test/smp/lazy/App/Main.smp | 1 | ||||
| -rw-r--r-- | chapter29/src/test/smp/lazy/App/Stats.smp | 1 | ||||
| -rw-r--r-- | chapter29/src/test/smp/lazy/App/Tables.smp | 4 | ||||
| -rw-r--r-- | chapter29/src/test/smp/separate/client/Main.smp | 6 | ||||
| -rw-r--r-- | chapter29/src/test/smp/separate/library/Counters.smp | 12 |
11 files changed, 209 insertions, 0 deletions
diff --git a/chapter29/src/test/smp/examples/A_helloWorld.smp b/chapter29/src/test/smp/examples/A_helloWorld.smp new file mode 100644 index 00000000..4ed6abdf --- /dev/null +++ b/chapter29/src/test/smp/examples/A_helloWorld.smp @@ -0,0 +1,2 @@ +sys.io.p("Hello, World!\n"); +return 0; diff --git a/chapter29/src/test/smp/examples/BubbleSort.smp b/chapter29/src/test/smp/examples/BubbleSort.smp new file mode 100644 index 00000000..ca6906b5 --- /dev/null +++ b/chapter29/src/test/smp/examples/BubbleSort.smp @@ -0,0 +1,36 @@ + +// An implementation of +// https://sampleprograms.io/projects/bubble-sort/ +// +// Bubble sort, with reading (parsing) and writing (formatting) the data. + +val sort = { !sys.aryi64 nums -> + sys.aryi64?! more = nums; + while( more ) { + more = null; + for( var i = 0; i < nums.len-1; i++ ) + if( nums.buf[i] > nums.buf[i+1] ) + more = nums.swap(i,i+1); + } +}; + +// Read one process argument of the form "[ 4, 3, 2, 1]" and print it sorted. +// args[0] is the executable name, as with native C argc/argv. +val main = { u8[~][] args -> + val usage = { -> + sys.io.p("Usage: please provide a list of at least two integers to sort in the format \"[1, 2, 3, 4, 5]\"\n"); + return 0; + }; + if( args# != 2 ) return usage(); + + var nums = sys.aryi64.parseAryI64(args[1]); + if( !nums ) return usage(); + if( nums.len < 2 ) return usage(); + + // Bubble sort array of integers + sort(nums); + + // Print the same bracketed array-list format accepted as input. + nums.str().add('\n').write(1); + return 0; +}; diff --git a/chapter29/src/test/smp/examples/Capitalize.smp b/chapter29/src/test/smp/examples/Capitalize.smp new file mode 100644 index 00000000..8e31c18f --- /dev/null +++ b/chapter29/src/test/smp/examples/Capitalize.smp @@ -0,0 +1,22 @@ + +// An implementation of +// https://sampleprograms.io/projects/capitalize/ + +val main = { u8[~][] args -> + if( args# > 2 ) { + sys.io.p("Use quotes around multiple strings.\n"); + return 0; + } + if( args# != 2 || args[1]# == 0 ) { + sys.io.p("Usage: please provide a string\n"); + return 0; + } + + u8[~] input = args[1]; + var output = new u8[input# + 1]; + sys.ary.copy(output,0,input,0,input#); + output[0] = sys.char.toupper(input[0]); + output[input#] = '\n'; + sys.io.p(output); + return 0; +}; diff --git a/chapter29/src/test/smp/examples/Dijkstra.smp b/chapter29/src/test/smp/examples/Dijkstra.smp new file mode 100644 index 00000000..fd595eb5 --- /dev/null +++ b/chapter29/src/test/smp/examples/Dijkstra.smp @@ -0,0 +1,72 @@ + +// An implementation of +// https://sampleprograms.io/projects/dijkstra/ + +val shortestPath = { !sys.aryi64 matrix, int nodes, int src, int dst -> + i64 infinity = (1 << 63)-1; + var dist = new i64[nodes]; + var visited = new sys.adt.bitset(); + // All nodes are infinitely far from each other + for( int i=0; i<nodes; i++ ) dist[i] = infinity; + // Starting point is zero far from starting point + dist[src] = 0; + + i64 result = -1; + int count = 0; + while( count < nodes && result < 0 ) { + int nearest = -1; + i64 best = infinity; + for( int node=0; node<nodes; node++ ) + if( !visited.get(node) && dist[node] < best ) { + nearest = node; + best = dist[node]; + } + if( nearest < 0 ) count = nodes; + else { + if( nearest == dst ) return best; + visited.set(nearest); + for( int node=0; node<nodes; node++ ) { + i64 weight = matrix.get(nearest*nodes + node); + if( weight > 0 && !visited.get(node) && best+weight < dist[node] ) + dist[node] = best+weight; + } + } + count++; + } + return result; +}; + +val usage = { -> + sys.io.p("Usage: please provide three inputs: a serialized matrix, a source node and a destination node\n"); + return 0; +}; + +val main = { u8[~][] args -> + // Exactly 3 args + if( args# != 4 ) return usage(); + // First is a serialized square matrix of positive numbers + var matrix = sys.aryi64.parseAryI64(args[1]); + if( !matrix ) return usage(); + if( !matrix.len ) return usage(); + // All numbers are positive + for( int i=0; i<matrix.len; i++ ) + if( matrix.get(i) < 0 ) return usage(); + // Matrix is square + int nodes = 0; + while( nodes*nodes < matrix.len ) nodes++; + if( nodes*nodes != matrix.len ) + return usage(); // Not a square matrix + + // src,dst are values within the matrix + i64 src = sys.aryu8.atoi(args[2]); + i64 dst = sys.aryu8.atoi(args[3]); + if( src < 0 || src >= nodes || dst < 0 || dst >= nodes ) + return usage(); // Source and destination land within the graph + + i64 cost = shortestPath(matrix,nodes,src,dst); + if( cost >= 0 ) { + new sys.aryu8().num(cost).add('\n').write(1); + return 0; + } + return usage(); +}; diff --git a/chapter29/src/test/smp/examples/FileIO.smp b/chapter29/src/test/smp/examples/FileIO.smp new file mode 100644 index 00000000..e48d435b --- /dev/null +++ b/chapter29/src/test/smp/examples/FileIO.smp @@ -0,0 +1,50 @@ + +// An implementation of +// https://sampleprograms.io/projects/file-input-output/ + +val FILE = "output.txt"; + +val main = { u8[~][] args -> + var str = new sys.aryu8(); + str.addAry("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n"); + str.addAry("Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n"); + str.addAry("Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n"); + str.addAry("Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n"); + + // Create + i32 fd = sys.io.create(FILE); + if( fd == -1 ) return _error(); + // Write + int wrote = sys.io.writeOff(fd,str.buf,0,str.len); + if( wrote == -1 ) return _error(); + if( wrote != str.len ) return _error2(-2); + // Close + if( sys.io.close(fd) != 0 ) return _error(); + + // Open + i32 fd2 = sys.io.open(FILE); + if( fd2 == -1 ) return _error(); + // Read + var got = sys.io.read(fd2); + if( got# != str.len ) return _error2(-3); + // Close + if( sys.io.close(fd2) != 0 ) return _error(); + + // Check contents are equal + if( sys.ary.cmp(got,0,str.buf,0,str.len) ) + return _error2(-4); + + // Remove + if( sys.io.remove(FILE) != 0 ) return _error(); + + sys.io.p("File I/O succeeded\n"); + return 0; +}; + +val _error2 = { i32 errno -> + sys.io.remove(FILE); + new sys.aryu8().addAry("Failed with error code ").num(errno).add('\n').write(sys.libc.STDERR); + sys.libc._exit(errno); +}; + +val _error = { -> _error2(sys.libc.errno()); }; diff --git a/chapter29/src/test/smp/lazy/App.smp b/chapter29/src/test/smp/lazy/App.smp new file mode 100644 index 00000000..caf7b0c1 --- /dev/null +++ b/chapter29/src/test/smp/lazy/App.smp @@ -0,0 +1,3 @@ +val Main=Main; +val Tables=Tables; +val Stats=Stats; diff --git a/chapter29/src/test/smp/lazy/App/Main.smp b/chapter29/src/test/smp/lazy/App/Main.smp new file mode 100644 index 00000000..2444f21b --- /dev/null +++ b/chapter29/src/test/smp/lazy/App/Main.smp @@ -0,0 +1 @@ +return arg ? Tables.square(3)+Tables.square(4)+100*Stats.builds : Stats.builds; diff --git a/chapter29/src/test/smp/lazy/App/Stats.smp b/chapter29/src/test/smp/lazy/App/Stats.smp new file mode 100644 index 00000000..e2d9e02e --- /dev/null +++ b/chapter29/src/test/smp/lazy/App/Stats.smp @@ -0,0 +1 @@ +int builds=0; diff --git a/chapter29/src/test/smp/lazy/App/Tables.smp b/chapter29/src/test/smp/lazy/App/Tables.smp new file mode 100644 index 00000000..0f32a118 --- /dev/null +++ b/chapter29/src/test/smp/lazy/App/Tables.smp @@ -0,0 +1,4 @@ +Stats.builds++; +int[] _squares=new int[256]; +for(int i=0; i<256; i++) _squares[i]=i*i; +val square={u8 n -> _squares[n];}; diff --git a/chapter29/src/test/smp/separate/client/Main.smp b/chapter29/src/test/smp/separate/client/Main.smp new file mode 100644 index 00000000..077f6575 --- /dev/null +++ b/chapter29/src/test/smp/separate/client/Main.smp @@ -0,0 +1,6 @@ +val run={int n -> + if(!n) return 0; + val c=new Counters.Counter(n); + return c.get()+100*Counters.next_noInline(); +}; +return run(arg); diff --git a/chapter29/src/test/smp/separate/library/Counters.smp b/chapter29/src/test/smp/separate/library/Counters.smp new file mode 100644 index 00000000..a3e36562 --- /dev/null +++ b/chapter29/src/test/smp/separate/library/Counters.smp @@ -0,0 +1,12 @@ +// A library can keep shared state and publish instance constructors. +int calls=0; +val next_noInline={ -> calls++; return calls; }; + +struct Counter { + val value=1; + new Counter={int n -> + value=0; + for(int i=0; i<n; i++) value=value*2+1; + }; + val get={ -> value; }; +}; |
