Merge branch 'master' into desugar

This commit is contained in:
Kartik Agaram 2019-08-25 15:04:26 -07:00
commit 0d3b3ef04a
25 changed files with 416 additions and 4839 deletions

View File

@ -5,7 +5,8 @@
:(before "End Main")
assert(argc > 1);
if (is_equal(argv[1], "run")) {
START_TRACING_UNTIL_END_OF_SCOPE;
// Outside of tests, traces must be explicitly requested.
if (Trace_file.is_open()) Trace_stream = new trace_stream;
trace(2, "run") << "=== Starting to run" << end();
assert(argc > 2);
reset();

View File

@ -18,7 +18,8 @@
:(before "End Main")
if (is_equal(argv[1], "translate")) {
START_TRACING_UNTIL_END_OF_SCOPE;
// Outside of tests, traces must be explicitly requested.
if (Trace_file.is_open()) Trace_stream = new trace_stream;
reset();
// Begin subx translate
program p;

View File

@ -1,9 +1,10 @@
# Mu: a human-scale computer
* Not designed to operate in large clusters providing services for millions of
people.
* Designed for _you_, to run one computer. (Or a few.) Running the code you
want to run, and nothing else.
Not designed to operate in large clusters providing services for millions of
people.
Designed for _you_, to run one computer. (Or a few.) Running the code you want
to run, and nothing else.
```sh
$ git clone https://github.com/akkartik/mu
@ -12,7 +13,7 @@
$ ./gen_iso examples/ex6.subx
# try it out
$ qemu-system-x86_64 -m 256M -cdrom mu.iso -boot d
# print the message followed by kernel panic
# print the message
```
[![Build Status](https://api.travis-ci.org/akkartik/mu.svg?branch=master)](https://travis-ci.org/akkartik/mu)
@ -328,19 +329,18 @@ distinguish between code and data. Correspondingly, SubX programs consist of a
series of segments, each starting with a header line: `==` followed by a name
and approximate starting address.
All code must lie in a segment called 'code'. Execution begins at the start of
the `code` segment by default.
All code must lie in a segment called 'code'.
You can reuse segment names:
Segments can be added to.
```
== code
```sh
== code 0x09000000 # first mention requires starting address
...A...
== data
== data 0x0a000000
...B...
== code
== code # no address necessary when adding
...C...
```
@ -841,9 +841,11 @@ Mu builds on many ideas that have come before, especially:
markup can be clean;
- BDD for challenging us all to write tests at a higher level;
- JavaScript and CSS for demonstrating the power of a DOM for complex
structured documents.
- Rust for demonstrating that a system-programming language can be safe.
- Forth for demonstrating that ergonomics don't require grammar.
structured documents;
- Rust for demonstrating that a system-programming language can be safe;
- Forth for demonstrating that ergonomics don't require grammar; and
- [Minimal Linux Live](http://minimal.linux-bg.org) for teaching how to create
a bootable disk image.
## Coda

BIN
apps/random Executable file

Binary file not shown.

62
apps/random.subx Normal file
View File

@ -0,0 +1,62 @@
# Repeatedly read 32-bit numbers from /dev/random, print them to stdout.
#
# To run:
# $ ./subx translate 0*.subx apps/random.subx -o apps/random
# $ ./subx run apps/random
== code 0x09000000
# instruction effective address register displacement immediate
# . op subop mod rm32 base index scale r32
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
Entry:
# stream/ESI = syscall(open, "/dev/null", O_RDONLY, 0) # we can't use 'fd' because it looks like a hex byte
bb/copy-to-EBX Filename/imm32
b9/copy-to-ECX 0/imm32/rdonly
ba/copy-to-EDX 0x180/imm32/fixed-perms
b8/copy-to-EAX 5/imm32/open
cd/syscall 0x80/imm8
# . stream = EAX
89/copy 3/mod/direct 6/rm32/ESI . . . 0/r32/EAX . . # copy EAX to ESI
$loop:
# syscall(read, Stream, N, 4)
89/copy 3/mod/direct 3/rm32/EBX . . . 6/r32/ESI . . # copy ESI to EBX
b9/copy-to-ECX N/imm32
ba/copy-to-EDX 4/imm32/size
b8/copy-to-EAX 3/imm32/read
cd/syscall 0x80/imm8
# print-int32-buffered(Stdout, *N)
# . . push args
ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . N/disp32 # push *N
68/push Stdout/imm32
# . . call
e8/call print-int32-buffered/disp32
# write-buffered(Stdout, Newline)
# . . push args
68/push Newline/imm32
68/push Stdout/imm32
# . . call
e8/call write-buffered/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
eb/jump $loop/disp8
# syscall(exit, 0)
bb/copy-to-EBX 0/imm32
b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8
== data 0x0a000000
N:
0/imm32
Filename:
2f 64 65 76 2f 72 61 6e 64 6f 6d 00
# / d e v / r a n d o m null
# . . vim:nowrap:textwidth=0

3
build
View File

@ -106,6 +106,9 @@ older_than subx_bin subx.cc *_list && {
$CXX $CFLAGS subx.cc -o subx_bin
}
# We ought to always rebuild all apps if any .subx layers are updated.
# But during development it's too slow to update _all_ apps when we're
# repeatedly running a single one.
if [ ! $ONLY_CPP ]
then

View File

@ -1,7 +1,7 @@
# First program: same as https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
# Just return 42.
#
# To run (from the subx directory):
# To run:
# $ ./subx translate examples/ex1.2.subx -o examples/ex1
# $ ./subx run examples/ex1
# Expected result:

View File

@ -1,6 +1,6 @@
# String comparison: return 1 iff the two args passed in at the commandline are equal.
#
# To run (from the subx directory):
# To run:
# $ ./subx translate examples/ex10.subx -o examples/ex10
# $ ./subx run examples/ex10 abc abd
# Expected result:

View File

@ -5,7 +5,7 @@
# kernel in a few places. This layer implements a function for comparing
# a null-terminated 'kernel string' with a length-prefixed 'SubX string'.
#
# To run (from the subx directory):
# To run:
# $ ./subx translate examples/ex11.subx -o examples/ex11
# $ ./subx run examples/ex11 # runs a series of tests
# ...... # all tests pass

View File

@ -1,7 +1,7 @@
# Example showing mmap syscall.
# Create a new segment using mmap, save the address, write to it.
#
# To run (from the subx directory):
# To run:
# $ ./subx translate examples/ex12.subx -o examples/ex12
# $ ./subx run examples/ex12
# You shouldn't get a segmentation fault.

View File

@ -1,6 +1,6 @@
# Add 1 and 1, and return the result in the exit code.
#
# To run (from the subx directory):
# To run:
# $ ./subx translate examples/ex2.subx -o examples/ex2
# $ ./subx run examples/ex2
# Expected result:

View File

@ -1,6 +1,6 @@
# Add the first 10 numbers, and return the result in the exit code.
#
# To run (from the subx directory):
# To run:
# $ ./subx translate examples/ex3.subx -o examples/ex3
# $ ./subx run examples/ex3
# Expected result:

View File

@ -1,6 +1,6 @@
# Read a character from stdin, save it to a global, write it to stdout.
#
# To run (from the subx directory):
# To run:
# $ ./subx translate examples/ex4.subx -o examples/ex4
# $ ./subx run examples/ex4

View File

@ -1,6 +1,6 @@
# Read a character from stdin, save it to a local on the stack, write it to stdout.
#
# To run (from the subx directory):
# To run:
# $ ./subx translate examples/ex5.subx -o examples/ex5
# $ ./subx run examples/ex5

View File

@ -1,6 +1,6 @@
# Print out a (global variable) string to stdout.
#
# To run (from the subx directory):
# To run:
# $ ./subx translate examples/ex6.subx -o examples/ex6
# $ ./subx run examples/ex6
# Hello, world!

View File

@ -4,7 +4,7 @@
# it for reading, read a character from it, close it, delete it, and return
# the character read.
#
# To run (from the subx directory):
# To run:
# $ ./subx translate examples/ex7.subx -o examples/ex7
# $ ./subx run examples/ex7
# Expected result:

View File

@ -1,6 +1,6 @@
# Example reading commandline arguments: compute length of first arg.
#
# To run (from the subx directory):
# To run:
# $ ./subx translate examples/ex8.subx -o examples/ex8
# $ ./subx run examples/ex8 abc de fghi
# Expected result:

View File

@ -3,7 +3,7 @@
# Show difference between ascii codes of first letter of first arg and first
# letter of second arg.
#
# To run (from the subx directory):
# To run:
# $ ./subx translate examples/ex9.subx -o examples/ex9
# $ ./subx run examples/ex9 z x
# Expected result:

View File

@ -32,7 +32,6 @@ then
fi
echo "=== building kernel"
cp kernel.config kernel/.config
( cd kernel
make bzImage -j $(grep ^processor /proc/cpuinfo | wc -l)
)

124
html/apps/random.subx.html Normal file
View File

@ -0,0 +1,124 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - apps/random.subx</title>
<meta name="Generator" content="Vim/8.1">
<meta name="plugin-version" content="vim8.1_v1">
<meta name="syntax" content="none">
<meta name="settings" content="number_lines,use_css,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="minimal-light">
<style type="text/css">
<!--
pre { font-family: monospace; color: #000000; background-color: #c6c6c6; }
body { font-size:12pt; font-family: monospace; color: #000000; background-color: #c6c6c6; }
a { color:inherit; }
* { font-size:12pt; font-size: 1em; }
.subxComment { color: #005faf; }
.subxS2Comment { color: #8a8a8a; }
.LineNr { }
.subxS1Comment { color: #0000af; }
.SpecialChar { color: #d70000; }
.Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; }
.Constant { color: #008787; }
-->
</style>
<script type='text/javascript'>
<!--
/* function to open any folds containing a jumped-to line before jumping to it */
function JumpToLine()
{
var lineNum;
lineNum = window.location.hash;
lineNum = lineNum.substr(1); /* strip off '#' */
if (lineNum.indexOf('L') == -1) {
lineNum = 'L'+lineNum;
}
var lineElem = document.getElementById(lineNum);
/* Always jump to new location even if the line was hidden inside a fold, or
* we corrected the raw number to a line ID.
*/
if (lineElem) {
lineElem.scrollIntoView(true);
}
return true;
}
if ('onhashchange' in window) {
window.onhashchange = JumpToLine;
}
-->
</script>
</head>
<body onload='JumpToLine();'>
<a href='https://github.com/akkartik/mu/blob/master/apps/random.subx'>https://github.com/akkartik/mu/blob/master/apps/random.subx</a>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr"> 1 </span><span class="subxComment"># Repeatedly read 32-bit numbers from /dev/random, print them to stdout.</span>
<span id="L2" class="LineNr"> 2 </span><span class="subxComment">#</span>
<span id="L3" class="LineNr"> 3 </span><span class="subxComment"># To run:</span>
<span id="L4" class="LineNr"> 4 </span><span class="subxComment"># $ ./subx translate 0*.subx apps/random.subx -o apps/random</span>
<span id="L5" class="LineNr"> 5 </span><span class="subxComment"># $ ./subx run apps/random</span>
<span id="L6" class="LineNr"> 6 </span>
<span id="L7" class="LineNr"> 7 </span>== code 0x09000000
<span id="L8" class="LineNr"> 8 </span><span class="subxComment"># instruction effective address register displacement immediate</span>
<span id="L9" class="LineNr"> 9 </span><span class="subxS1Comment"># . op subop mod rm32 base index scale r32</span>
<span id="L10" class="LineNr">10 </span><span class="subxS1Comment"># . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes</span>
<span id="L11" class="LineNr">11 </span>
<span id="L12" class="LineNr">12 </span><span class="SpecialChar">Entry</span>:
<span id="L13" class="LineNr">13 </span> <span class="subxComment"># stream/ESI = syscall(open, &quot;/dev/null&quot;, O_RDONLY, 0) # we can't use 'fd' because it looks like a hex byte</span>
<span id="L14" class="LineNr">14 </span> bb/copy-to-EBX <span class="SpecialChar"><a href='random.subx.html#L58'>Filename</a></span>/imm32
<span id="L15" class="LineNr">15 </span> b9/copy-to-ECX 0/imm32/rdonly
<span id="L16" class="LineNr">16 </span> ba/copy-to-EDX 0x180/imm32/fixed-perms
<span id="L17" class="LineNr">17 </span> b8/copy-to-EAX 5/imm32/open
<span id="L18" class="LineNr">18 </span> cd/syscall 0x80/imm8
<span id="L19" class="LineNr">19 </span> <span class="subxS1Comment"># . stream = EAX</span>
<span id="L20" class="LineNr">20 </span> 89/copy 3/mod/direct 6/rm32/ESI <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0/r32/EAX <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy EAX to ESI</span>
<span id="L21" class="LineNr">21 </span>
<span id="L22" class="LineNr">22 </span><span class="Constant">$loop</span>:
<span id="L23" class="LineNr">23 </span>
<span id="L24" class="LineNr">24 </span> <span class="subxComment"># syscall(read, Stream, N, 4)</span>
<span id="L25" class="LineNr">25 </span> 89/copy 3/mod/direct 3/rm32/EBX <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 6/r32/ESI <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy ESI to EBX</span>
<span id="L26" class="LineNr">26 </span> b9/copy-to-ECX <span class="SpecialChar"><a href='random.subx.html#L56'>N</a></span>/imm32
<span id="L27" class="LineNr">27 </span> ba/copy-to-EDX 4/imm32/size
<span id="L28" class="LineNr">28 </span> b8/copy-to-EAX 3/imm32/read
<span id="L29" class="LineNr">29 </span> cd/syscall 0x80/imm8
<span id="L30" class="LineNr">30 </span>
<span id="L31" class="LineNr">31 </span> <span class="subxComment"># print-int32-buffered(Stdout, *N)</span>
<span id="L32" class="LineNr">32 </span> <span class="subxS2Comment"># . . push args</span>
<span id="L33" class="LineNr">33 </span> ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="SpecialChar"><a href='random.subx.html#L56'>N</a></span>/disp32 <span class="subxComment"># push *N</span>
<span id="L34" class="LineNr">34 </span> 68/push <span class="SpecialChar"><a href='../064write-byte.subx.html#L10'>Stdout</a></span>/imm32
<span id="L35" class="LineNr">35 </span> <span class="subxS2Comment"># . . call</span>
<span id="L36" class="LineNr">36 </span> e8/call <a href='../066print-int.subx.html#L267'>print-int32-buffered</a>/disp32
<span id="L37" class="LineNr">37 </span>
<span id="L38" class="LineNr">38 </span> <span class="subxComment"># write-buffered(Stdout, Newline)</span>
<span id="L39" class="LineNr">39 </span> <span class="subxS2Comment"># . . push args</span>
<span id="L40" class="LineNr">40 </span> 68/push <span class="SpecialChar"><a href='../051test.subx.html#L83'>Newline</a></span>/imm32
<span id="L41" class="LineNr">41 </span> 68/push <span class="SpecialChar"><a href='../064write-byte.subx.html#L10'>Stdout</a></span>/imm32
<span id="L42" class="LineNr">42 </span> <span class="subxS2Comment"># . . call</span>
<span id="L43" class="LineNr">43 </span> e8/call <a href='../065write-buffered.subx.html#L8'>write-buffered</a>/disp32
<span id="L44" class="LineNr">44 </span> <span class="subxS2Comment"># . . discard args</span>
<span id="L45" class="LineNr">45 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to ESP</span>
<span id="L46" class="LineNr">46 </span>
<span id="L47" class="LineNr">47 </span> eb/jump $loop/disp8
<span id="L48" class="LineNr">48 </span>
<span id="L49" class="LineNr">49 </span> <span class="subxComment"># syscall(exit, 0)</span>
<span id="L50" class="LineNr">50 </span> bb/copy-to-EBX 0/imm32
<span id="L51" class="LineNr">51 </span> b8/copy-to-EAX 1/imm32/exit
<span id="L52" class="LineNr">52 </span> cd/syscall 0x80/imm8
<span id="L53" class="LineNr">53 </span>
<span id="L54" class="LineNr">54 </span>== data 0x0a000000
<span id="L55" class="LineNr">55 </span>
<span id="L56" class="LineNr">56 </span><span class="SpecialChar">N</span>:
<span id="L57" class="LineNr">57 </span> 0/imm32
<span id="L58" class="LineNr">58 </span><span class="SpecialChar">Filename</span>:
<span id="L59" class="LineNr">59 </span> 2f 64 65 76 2f 72 61 6e 64 6f 6d 00
<span id="L60" class="LineNr">60 </span><span class="subxComment"># / d e v / r a n d o m null</span>
<span id="L61" class="LineNr">61 </span>
<span id="L62" class="LineNr">62 </span><span class="subxS2Comment"># . . vim&#0058;nowrap:textwidth=0</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@
set -e
set -v
./build
ALL=1 ./build
echo `cat $* |grep -v '^\s*#\|^\s*$' |wc -l` lines

308
test_apps
View File

@ -1,14 +1,25 @@
#!/bin/sh
# Build and test (in emulated mode) all included SubX programs.
# Also compare generated binaries.
# If running on Linux, also test natively.
# Build and test all included SubX programs:
# translate them into ELF binaries
# compare the generated binaries with what's already in git
# run/test the ELF binaries in emulated mode (unless $NO_EMULATION)
# run/test the ELF binaries in native mode (if on Linux)
#
# Example usage:
# test_apps # compare generated binaries, run them in emulated and native mode
# test_apps record # run binaries in emulated and native mode
# NO_EMULATION=1 test_apps # compare generated binaries, run them in native mode
# NO_EMULATION=1 test_apps record # run binaries just in native mode
set -e
cd `dirname $0`
test `uname` = 'Linux' && echo 'testing native runs as well'
test $NO_EMULATION || EMULATED=1
test $EMULATED && echo 'testing emulated runs'
test `uname` = 'Linux' && NATIVE=1
test $NATIVE && echo 'testing native runs'
CFLAGS=$CFLAGS ./build
./build
echo "== translating and running using C++"
@ -16,101 +27,121 @@ echo "== translating and running using C++"
echo ex1
./subx translate examples/ex1.subx -o examples/ex1
[ "$1" != record ] && git diff --exit-code examples/ex1
./subx run examples/ex1 || ret=$?
test $ret -eq 42 # life, the universe and everything
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code examples/ex1
test $EMULATED && {
./subx run examples/ex1 || ret=$?
test $ret -eq 42 # life, the universe and everything
}
test $NATIVE && {
examples/ex1 || ret=$?
test $ret -eq 42 # life, the universe and everything
}
echo ex2
./subx translate examples/ex2.subx -o examples/ex2
[ "$1" != record ] && git diff --exit-code examples/ex2
./subx run examples/ex2 || ret=$?
test $ret -eq 2 # 1 + 1
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code examples/ex2
test $EMULATED && {
./subx run examples/ex2 || ret=$?
test $ret -eq 2 # 1 + 1
}
test $NATIVE && {
examples/ex2 || ret=$?
test $ret -eq 2 # 1 + 1
}
echo ex3
./subx translate examples/ex3.subx -o examples/ex3
[ "$1" != record ] && git diff --exit-code examples/ex3
./subx run examples/ex3 || ret=$?
test $ret -eq 55 # 1 + 2 + ... + 10
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code examples/ex3
test $EMULATED && {
./subx run examples/ex3 || ret=$?
test $ret -eq 55 # 1 + 2 + ... + 10
}
test $NATIVE && {
examples/ex3 || ret=$?
test $ret -eq 55 # 1 + 2 + ... + 10
}
echo ex4
./subx translate examples/ex4.subx -o examples/ex4
[ "$1" != record ] && git diff --exit-code examples/ex4
echo a | ./subx run examples/ex4 >ex4.out || true
test `cat ex4.out` = 'a'
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code examples/ex4
test $EMULATED && {
echo a | ./subx run examples/ex4 >ex4.out || true
test `cat ex4.out` = 'a'
}
test $NATIVE && {
echo a | examples/ex4 >ex4.out || true
test `cat ex4.out` = 'a'
}
echo ex5
./subx translate examples/ex5.subx -o examples/ex5
[ "$1" != record ] && git diff --exit-code examples/ex5
echo a | ./subx run examples/ex5 >ex5.out || true
test `cat ex5.out` = 'a'
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code examples/ex5
test $EMULATED && {
echo a | ./subx run examples/ex5 >ex5.out || true
test `cat ex5.out` = 'a'
}
test $NATIVE && {
echo a | examples/ex5 >ex5.out || true
test `cat ex5.out` = 'a'
}
echo ex6
./subx translate examples/ex6.subx -o examples/ex6
[ "$1" != record ] && git diff --exit-code examples/ex6
./subx run examples/ex6 >ex6.out || true
test "`cat ex6.out`" = 'Hello, world!'
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code examples/ex6
test $EMULATED && {
./subx run examples/ex6 >ex6.out || true
test "`cat ex6.out`" = 'Hello, world!'
}
test $NATIVE && {
examples/ex6 >ex6.out || true
test "`cat ex6.out`" = 'Hello, world!'
}
echo ex7
./subx translate examples/ex7.subx -o examples/ex7
[ "$1" != record ] && git diff --exit-code examples/ex7
./subx run examples/ex7 || ret=$?
test $ret -eq 97 # 'a'
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code examples/ex7
test $EMULATED && {
./subx run examples/ex7 || ret=$?
test $ret -eq 97 # 'a'
}
test $NATIVE && {
examples/ex7 || ret=$?
test $ret -eq 97 # 'a'
}
echo ex8
./subx translate examples/ex8.subx -o examples/ex8
[ "$1" != record ] && git diff --exit-code examples/ex8
./subx run examples/ex8 abcd || ret=$?
test $ret -eq 4 # length('abcd')
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code examples/ex8
test $EMULATED && {
./subx run examples/ex8 abcd || ret=$?
test $ret -eq 4 # length('abcd')
}
test $NATIVE && {
examples/ex8 abcd || ret=$?
test $ret -eq 4 # length('abcd')
}
echo ex9
./subx translate examples/ex9.subx -o examples/ex9
[ "$1" != record ] && git diff --exit-code examples/ex9
./subx run examples/ex9 z x || ret=$?
test $ret -eq 2 # 'z' - 'x'
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code examples/ex9
test $EMULATED && {
./subx run examples/ex9 z x || ret=$?
test $ret -eq 2 # 'z' - 'x'
}
test $NATIVE && {
examples/ex9 z x || ret=$?
test $ret -eq 2 # 'z' - 'x'
}
echo ex10
./subx translate examples/ex10.subx -o examples/ex10
[ "$1" != record ] && git diff --exit-code examples/ex10
./subx run examples/ex10 abc abc || ret=$?
test $ret -eq 1 # equal
./subx run examples/ex10 abc abcd # 0; not equal
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code examples/ex10
test $EMULATED && {
./subx run examples/ex10 abc abc || ret=$?
test $ret -eq 1 # equal
./subx run examples/ex10 abc abcd # 0; not equal
}
test $NATIVE && {
examples/ex10 abc abc || ret=$?
test $ret -eq 1 # equal
examples/ex10 abc abcd # 0; not equal
@ -118,30 +149,34 @@ test `uname` = 'Linux' && {
echo ex11
./subx translate examples/ex11.subx -o examples/ex11
[ "$1" != record ] && git diff --exit-code examples/ex11
./subx run examples/ex11
echo
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code examples/ex11
test $EMULATED && {
./subx run examples/ex11
echo
}
test $NATIVE && {
examples/ex11
echo
}
echo ex12
./subx translate examples/ex12.subx -o examples/ex12
[ "$1" != record ] && git diff --exit-code examples/ex12
./subx run examples/ex12 # final byte of mmap'd address is well-nigh guaranteed to be 0
test `uname` = 'Linux' && examples/ex12
test "$1" = 'record' || git diff --exit-code examples/ex12
test $EMULATED && ./subx run examples/ex12 # final byte of mmap'd address is well-nigh guaranteed to be 0
test $NATIVE && examples/ex12
# Larger apps that use the standard library.
echo factorial
./subx translate 0*.subx apps/factorial.subx -o apps/factorial
[ "$1" != record ] && git diff --exit-code apps/factorial
./subx run apps/factorial || ret=$?
test $ret -eq 120 # factorial(5)
./subx run apps/factorial test
echo
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code apps/factorial
test $EMULATED && {
./subx run apps/factorial || ret=$?
test $ret -eq 120 # factorial(5)
./subx run apps/factorial test
echo
}
test $NATIVE && {
apps/factorial || ret=$?
test $ret -eq 120 # factorial(5)
apps/factorial test
@ -150,31 +185,37 @@ test `uname` = 'Linux' && {
echo crenshaw2-1
./subx translate 0*.subx apps/crenshaw2-1.subx -o apps/crenshaw2-1
[ "$1" != record ] && git diff --exit-code apps/crenshaw2-1
./subx run apps/crenshaw2-1 test
echo
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code apps/crenshaw2-1
test $EMULATED && {
./subx run apps/crenshaw2-1 test
echo
}
test $NATIVE && {
apps/crenshaw2-1 test
echo
}
echo crenshaw2-1b
./subx translate 0*.subx apps/crenshaw2-1b.subx -o apps/crenshaw2-1b
[ "$1" != record ] && git diff --exit-code apps/crenshaw2-1b
./subx run apps/crenshaw2-1b test
echo
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code apps/crenshaw2-1b
test $EMULATED && {
./subx run apps/crenshaw2-1b test
echo
}
test $NATIVE && {
apps/crenshaw2-1b test
echo
}
echo handle
./subx translate 0*.subx apps/handle.subx -o apps/handle
[ "$1" != record ] && git diff --exit-code apps/handle
./subx run apps/handle > handle.out 2>&1 || true
grep -q 'lookup succeeded' handle.out || { echo "missing success test"; exit 1; }
grep -q 'lookup failed' handle.out || { echo "missing failure test"; exit 1; }
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code apps/handle
test $EMULATED && {
./subx run apps/handle > handle.out 2>&1 || true
grep -q 'lookup succeeded' handle.out || { echo "missing success test"; exit 1; }
grep -q 'lookup failed' handle.out || { echo "missing failure test"; exit 1; }
}
test $NATIVE && {
apps/handle > handle.out 2>&1 || true
grep -q 'lookup succeeded' handle.out || { echo "missing success test"; exit 1; }
grep -q 'lookup failed' handle.out || { echo "missing failure test"; exit 1; }
@ -184,60 +225,72 @@ test `uname` = 'Linux' && {
echo hex
./subx translate 0*.subx apps/subx-common.subx apps/hex.subx -o apps/hex
[ "$1" != record ] && git diff --exit-code apps/hex
./subx run apps/hex test
echo
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code apps/hex
test $EMULATED && {
./subx run apps/hex test
echo
}
test $NATIVE && {
apps/hex test
echo
}
echo survey
./subx translate 0*.subx apps/subx-common.subx apps/survey.subx -o apps/survey
[ "$1" != record ] && git diff --exit-code apps/survey
./subx run apps/survey test
echo
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code apps/survey
test $EMULATED && {
./subx run apps/survey test
echo
}
test $NATIVE && {
apps/survey test
echo
}
echo pack
./subx translate 0*.subx apps/subx-common.subx apps/pack.subx -o apps/pack
[ "$1" != record ] && git diff --exit-code apps/pack
./subx run apps/pack test
echo
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code apps/pack
test $EMULATED && {
./subx run apps/pack test
echo
}
test $NATIVE && {
apps/pack test
echo
}
echo assort
./subx translate 0*.subx apps/subx-common.subx apps/assort.subx -o apps/assort
[ "$1" != record ] && git diff --exit-code apps/assort
./subx run apps/assort test
echo
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code apps/assort
test $EMULATED && {
./subx run apps/assort test
echo
}
test $NATIVE && {
apps/assort test
echo
}
echo dquotes
./subx translate 0*.subx apps/subx-common.subx apps/dquotes.subx -o apps/dquotes
[ "$1" != record ] && git diff --exit-code apps/dquotes
./subx run apps/dquotes test
echo
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code apps/dquotes
test $EMULATED && {
./subx run apps/dquotes test
echo
}
test $NATIVE && {
apps/dquotes test
echo
}
echo tests
./subx translate 0*.subx apps/subx-common.subx apps/tests.subx -o apps/tests
[ "$1" != record ] && git diff --exit-code apps/tests
./subx run apps/tests test
echo
test `uname` = 'Linux' && {
test "$1" = 'record' || git diff --exit-code apps/tests
test $EMULATED && {
./subx run apps/tests test
echo
}
test $NATIVE && {
apps/tests test
echo
}
@ -259,67 +312,88 @@ echo "== translating using SubX"
# example programs
echo ex1
cat examples/ex1.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex1 -
test `uname` = 'Linux' && {
test $EMULATED && {
cat examples/ex1.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex1 -
}
test $NATIVE && {
cat examples/ex1.subx |apps/tests |apps/dquotes |apps/assort |apps/pack |apps/survey |apps/hex |diff examples/ex1 -
}
echo ex2
cat examples/ex2.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex2 -
test `uname` = 'Linux' && {
test $EMULATED && {
cat examples/ex2.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex2 -
}
test $NATIVE && {
cat examples/ex2.subx |apps/tests |apps/dquotes |apps/assort |apps/pack |apps/survey |apps/hex |diff examples/ex2 -
}
echo ex3
cat examples/ex3.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex3 -
test `uname` = 'Linux' && {
test $EMULATED && {
cat examples/ex3.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex3 -
}
test $NATIVE && {
cat examples/ex3.subx |apps/tests |apps/dquotes |apps/assort |apps/pack |apps/survey |apps/hex |diff examples/ex3 -
}
echo ex4
cat examples/ex4.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex4 -
test `uname` = 'Linux' && {
test $EMULATED && {
cat examples/ex4.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex4 -
}
test $NATIVE && {
cat examples/ex4.subx |apps/tests |apps/dquotes |apps/assort |apps/pack |apps/survey |apps/hex |diff examples/ex4 -
}
echo ex5
cat examples/ex5.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex5 -
test `uname` = 'Linux' && {
test $EMULATED && {
cat examples/ex5.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex5 -
}
test $NATIVE && {
cat examples/ex5.subx |apps/tests |apps/dquotes |apps/assort |apps/pack |apps/survey |apps/hex |diff examples/ex5 -
}
echo ex6
cat examples/ex6.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex6 -
test `uname` = 'Linux' && {
test $EMULATED && {
cat examples/ex6.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex6 -
}
test $NATIVE && {
cat examples/ex6.subx |apps/tests |apps/dquotes |apps/assort |apps/pack |apps/survey |apps/hex |diff examples/ex6 -
}
echo ex7
cat examples/ex7.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex7 -
test `uname` = 'Linux' && {
test $EMULATED && {
cat examples/ex7.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex7 -
}
test $NATIVE && {
cat examples/ex7.subx |apps/tests |apps/dquotes |apps/assort |apps/pack |apps/survey |apps/hex |diff examples/ex7 -
}
echo ex8
cat examples/ex8.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex8 -
test `uname` = 'Linux' && {
test $EMULATED && {
cat examples/ex8.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex8 -
}
test $NATIVE && {
cat examples/ex8.subx |apps/tests |apps/dquotes |apps/assort |apps/pack |apps/survey |apps/hex |diff examples/ex8 -
}
echo ex9
cat examples/ex9.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex9 -
test `uname` = 'Linux' && {
test $EMULATED && {
cat examples/ex9.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex9 -
}
test $NATIVE && {
cat examples/ex9.subx |apps/tests |apps/dquotes |apps/assort |apps/pack |apps/survey |apps/hex |diff examples/ex9 -
}
echo ex10
cat examples/ex10.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex10 -
test `uname` = 'Linux' && {
test $EMULATED && {
cat examples/ex10.subx |./subx_bin run apps/tests |./subx_bin run apps/dquotes |./subx_bin run apps/assort |./subx_bin run apps/pack |./subx_bin run apps/survey |./subx_bin run apps/hex |diff examples/ex10 -
}
test $NATIVE && {
cat examples/ex10.subx |apps/tests |apps/dquotes |apps/assort |apps/pack |apps/survey |apps/hex |diff examples/ex10 -
}
# Only native runs beyond this point. Emulated runs time out on travis-ci.org.
test `uname` = 'Linux' || exit 0
test $EMULATED && echo "skipping remaining runs in emulated mode"
test $NATIVE || exit 0
echo ex11
cat examples/ex11.subx |apps/tests |apps/dquotes |apps/assort |apps/pack |apps/survey |apps/hex |diff examples/ex11 -

View File

@ -15,7 +15,7 @@ done
# build everything one last time
./clean
CFLAGS=$CFLAGS ./build # build optimized by default since we'll be running it repeatedly below
./build # build optimized since we'll be running it repeatedly below
# add SubX files one at a time
for f in [0-9]*.subx

View File

@ -14,7 +14,7 @@
set -e
set -v
./build
ALL=1 ./build
echo `cat $* |grep -v '^\s*#\|^\s*$' |wc -l` lines