7401 - clean up support for non-Linux platforms
This commit is contained in:
parent
56bfd52643
commit
47287fbf1a
21
README.md
21
README.md
|
@ -24,7 +24,8 @@ to _some_ safe and clear syntax with as few layers of translation as possible.
|
|||
The emphasis is on internal consistency at any point in time rather than
|
||||
compatibility with the past. ([More details.](http://akkartik.name/akkartik-convivial-20200607.pdf))
|
||||
|
||||
Currently Mu requires a 32-bit x86 processor and Linux kernel.
|
||||
Currently Mu requires a 32-bit x86 processor. Generated programs require just
|
||||
a Linux kernel and nothing else.
|
||||
|
||||
## Goals
|
||||
|
||||
|
@ -67,12 +68,20 @@ The Mu stack consists of:
|
|||
- _bare_ SubX, a more rudimentary form of SubX without certain syntax sugar.
|
||||
|
||||
All Mu programs get translated through these layers into tiny zero-dependency
|
||||
ELF binaries. The translators for most levels are built out of lower levels.
|
||||
The translator from Mu to SubX is written in SubX, and the translator from
|
||||
SubX to bare SubX is built in bare SubX.
|
||||
ELF binaries that run natively on Linux. The translators for most levels are
|
||||
built out of lower levels. The translator from Mu to SubX is written in SubX,
|
||||
and the translator from SubX to bare SubX is built in bare SubX.
|
||||
|
||||
Mu programs can be run in emulated mode to emit traces, which permit time-travel
|
||||
debugging. ([More details.](subx_debugging.md))
|
||||
There's an emulator for running Mu binaries (more slowly) on other Unix-like
|
||||
systems.
|
||||
|
||||
```sh
|
||||
$ ./translate_mu_emulated apps/ex2.mu # emit a.elf using the emulator
|
||||
$ ./bootstrap run ./a.elf # run in the emulator
|
||||
$ echo $?
|
||||
```
|
||||
|
||||
The emulator is also useful for [debugging](subx_debugging.md).
|
||||
|
||||
### incomplete tools
|
||||
|
||||
|
|
|
@ -27,28 +27,16 @@ rudimentary but hopefully still workable toolkit:
|
|||
mode (`bootstrap run`):
|
||||
|
||||
```
|
||||
$ ./bootstrap translate input.subx -o binary
|
||||
$ ./bootstrap --trace run binary arg1 arg2 2>trace
|
||||
$ ./translate_subx_debug file1.subx file2.subx ... # generating a.elf
|
||||
$ ./bootstrap --trace run a.elf arg1 arg2
|
||||
saving trace to 'last_run'
|
||||
```
|
||||
|
||||
The ability to generate a trace is the essential reason for the existence of
|
||||
`bootstrap run` mode. It gives far better visibility into program internals than
|
||||
running natively.
|
||||
|
||||
- As a further refinement, it is possible to render label names in the trace
|
||||
by adding a second flag to the `bootstrap translate` command:
|
||||
|
||||
```
|
||||
$ ./bootstrap --debug translate input.subx -o binary
|
||||
$ ./bootstrap --trace run binary arg1 arg2 2>trace
|
||||
```
|
||||
|
||||
`bootstrap --debug translate` emits a mapping from label to address in a file
|
||||
called `labels`. `bootstrap --trace run` reads in the `labels` file if
|
||||
it exists and prints out any matching label name as it traces each instruction
|
||||
executed.
|
||||
|
||||
Here's a sample of what a trace looks like, with a few boxes highlighted:
|
||||
Here's a sample of the contents of `last_run`, with a few boxes highlighted:
|
||||
|
||||
<img alt='trace example' src='html/trace.png'>
|
||||
|
||||
|
@ -60,10 +48,10 @@ rudimentary but hopefully still workable toolkit:
|
|||
address `0x0900005e` maps to label `$loop` and presumably marks the start of
|
||||
some loop. Function names get similar `run: == label` lines.
|
||||
|
||||
- One trick when emitting traces with labels:
|
||||
- One quick trick when scanning a trace for the first time:
|
||||
|
||||
```
|
||||
$ grep label trace
|
||||
$ grep label last_run
|
||||
```
|
||||
|
||||
This is useful for quickly showing you the control flow for the run, and the
|
||||
|
@ -115,11 +103,21 @@ rudimentary but hopefully still workable toolkit:
|
|||
`./translate_subx_debug`, and then running:
|
||||
|
||||
```
|
||||
./bootstrap --trace --dump run a.elf test 2>&1 |grep 'label test'
|
||||
grep 'label test-' |tail
|
||||
```
|
||||
|
||||
Just read out the last test printed out before the segfault.
|
||||
|
||||
Even outside of tests, I can often quickly debug an error just by scanning
|
||||
the end of a trace for labels:
|
||||
|
||||
```
|
||||
$ grep label last_run |tail
|
||||
```
|
||||
|
||||
Knowing _where_ the error occurred is often enough to put me on the right
|
||||
track to debugging an error.
|
||||
|
||||
Hopefully these hints are enough to get you started. The main thing to
|
||||
remember is to not be afraid of modifying the sources. A good debugging
|
||||
session gets into a nice rhythm of generating a trace, staring at it for a
|
||||
|
|
244
test_apps
244
test_apps
|
@ -1,180 +1,171 @@
|
|||
#!/bin/sh
|
||||
# Build and test all included SubX programs:
|
||||
# Build and test all included SubX programs on Linux:
|
||||
# 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)
|
||||
# run/test the ELF binaries in emulated mode
|
||||
# run/test the ELF binaries in native mode
|
||||
#
|
||||
# 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
|
||||
# test_apps
|
||||
# test_apps record # don't compare with what's in git
|
||||
|
||||
set -e
|
||||
cd `dirname $0`
|
||||
|
||||
test $NO_EMULATION || EMULATED=1
|
||||
test $EMULATED && echo 'testing emulated runs'
|
||||
test `uname` = 'Linux' && NATIVE=1
|
||||
test $NATIVE && echo 'testing native runs'
|
||||
|
||||
./build
|
||||
|
||||
export OS=${OS:-linux}
|
||||
|
||||
echo "== translating and running using C++"
|
||||
echo "== translating using the bootstrap C++ translator"
|
||||
|
||||
# example programs
|
||||
|
||||
echo ex1
|
||||
./bootstrap translate init.$OS apps/ex1.subx -o apps/ex1
|
||||
./bootstrap_bin translate init.linux apps/ex1.subx -o apps/ex1
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex1
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/ex1 || ret=$?
|
||||
{
|
||||
./bootstrap_bin run apps/ex1 || ret=$?
|
||||
test $ret -eq 42 # life, the universe and everything
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/ex1 || ret=$?
|
||||
test $ret -eq 42 # life, the universe and everything
|
||||
}
|
||||
|
||||
echo ex2
|
||||
./bootstrap translate init.$OS apps/ex2.subx -o apps/ex2
|
||||
./bootstrap_bin translate init.linux apps/ex2.subx -o apps/ex2
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex2
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/ex2 || ret=$?
|
||||
{
|
||||
./bootstrap_bin run apps/ex2 || ret=$?
|
||||
test $ret -eq 7 # 3 + 4
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/ex2 || ret=$?
|
||||
test $ret -eq 7 # 3 + 4
|
||||
}
|
||||
|
||||
echo ex3
|
||||
./bootstrap translate init.$OS apps/ex3.subx -o apps/ex3
|
||||
./bootstrap_bin translate init.linux apps/ex3.subx -o apps/ex3
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex3
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/ex3 || ret=$?
|
||||
{
|
||||
./bootstrap_bin run apps/ex3 || ret=$?
|
||||
test $ret -eq 55 # 1 + 2 + ... + 10
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/ex3 || ret=$?
|
||||
test $ret -eq 55 # 1 + 2 + ... + 10
|
||||
}
|
||||
|
||||
echo ex4
|
||||
./bootstrap translate init.$OS apps/ex4.subx -o apps/ex4
|
||||
./bootstrap_bin translate init.linux apps/ex4.subx -o apps/ex4
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex4
|
||||
test $EMULATED && {
|
||||
echo a | ./bootstrap run apps/ex4 >ex4.out || true
|
||||
{
|
||||
echo a | ./bootstrap_bin run apps/ex4 >ex4.out || true
|
||||
test `cat ex4.out` = 'a'
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
echo a | apps/ex4 >ex4.out || true
|
||||
test `cat ex4.out` = 'a'
|
||||
}
|
||||
|
||||
echo ex5
|
||||
./bootstrap translate init.$OS apps/ex5.subx -o apps/ex5
|
||||
./bootstrap_bin translate init.linux apps/ex5.subx -o apps/ex5
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex5
|
||||
test $EMULATED && {
|
||||
echo a | ./bootstrap run apps/ex5 >ex5.out || true
|
||||
{
|
||||
echo a | ./bootstrap_bin run apps/ex5 >ex5.out || true
|
||||
test `cat ex5.out` = 'a'
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
echo a | apps/ex5 >ex5.out || true
|
||||
test `cat ex5.out` = 'a'
|
||||
}
|
||||
|
||||
echo ex6
|
||||
./bootstrap translate init.$OS apps/ex6.subx -o apps/ex6
|
||||
./bootstrap_bin translate init.linux apps/ex6.subx -o apps/ex6
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex6
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/ex6 >ex6.out || true
|
||||
{
|
||||
./bootstrap_bin run apps/ex6 >ex6.out || true
|
||||
test "`cat ex6.out`" = 'Hello, world!'
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/ex6 >ex6.out || true
|
||||
test "`cat ex6.out`" = 'Hello, world!'
|
||||
}
|
||||
|
||||
echo ex7
|
||||
./bootstrap translate init.$OS apps/ex7.subx -o apps/ex7
|
||||
./bootstrap_bin translate init.linux apps/ex7.subx -o apps/ex7
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex7
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/ex7 || ret=$?
|
||||
{
|
||||
./bootstrap_bin run apps/ex7 || ret=$?
|
||||
test $ret -eq 97 # 'a'
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/ex7 || ret=$?
|
||||
test $ret -eq 97 # 'a'
|
||||
}
|
||||
|
||||
echo ex8
|
||||
./bootstrap translate init.$OS apps/ex8.subx -o apps/ex8
|
||||
./bootstrap_bin translate init.linux apps/ex8.subx -o apps/ex8
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex8
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/ex8 abcd || ret=$?
|
||||
{
|
||||
./bootstrap_bin run apps/ex8 abcd || ret=$?
|
||||
test $ret -eq 4 # length('abcd')
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/ex8 abcd || ret=$?
|
||||
test $ret -eq 4 # length('abcd')
|
||||
}
|
||||
|
||||
echo ex9
|
||||
./bootstrap translate init.$OS apps/ex9.subx -o apps/ex9
|
||||
./bootstrap_bin translate init.linux apps/ex9.subx -o apps/ex9
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex9
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/ex9 z x || ret=$?
|
||||
{
|
||||
./bootstrap_bin run apps/ex9 z x || ret=$?
|
||||
test $ret -eq 2 # 'z' - 'x'
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/ex9 z x || ret=$?
|
||||
test $ret -eq 2 # 'z' - 'x'
|
||||
}
|
||||
|
||||
echo ex10
|
||||
./bootstrap translate init.$OS apps/ex10.subx -o apps/ex10
|
||||
./bootstrap_bin translate init.linux apps/ex10.subx -o apps/ex10
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex10
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/ex10 abc abc || ret=$?
|
||||
{
|
||||
./bootstrap_bin run apps/ex10 abc abc || ret=$?
|
||||
test $ret -eq 1 # equal
|
||||
./bootstrap run apps/ex10 abc abcd # 0; not equal
|
||||
./bootstrap_bin run apps/ex10 abc abcd # 0; not equal
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/ex10 abc abc || ret=$?
|
||||
test $ret -eq 1 # equal
|
||||
apps/ex10 abc abcd # 0; not equal
|
||||
}
|
||||
|
||||
echo ex11
|
||||
./bootstrap translate init.$OS apps/ex11.subx -o apps/ex11
|
||||
./bootstrap_bin translate init.linux apps/ex11.subx -o apps/ex11
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex11
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/ex11
|
||||
{
|
||||
./bootstrap_bin run apps/ex11
|
||||
echo
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/ex11
|
||||
echo
|
||||
}
|
||||
|
||||
echo ex12
|
||||
./bootstrap translate init.$OS apps/ex12.subx -o apps/ex12
|
||||
./bootstrap_bin translate init.linux apps/ex12.subx -o apps/ex12
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex12
|
||||
test $EMULATED && ./bootstrap run apps/ex12 # final byte of mmap'd address is well-nigh guaranteed to be 0
|
||||
test $EMULATED && ./bootstrap_bin run apps/ex12 # final byte of mmap'd address is well-nigh guaranteed to be 0
|
||||
test $NATIVE && apps/ex12
|
||||
|
||||
echo ex13
|
||||
./bootstrap translate init.$OS apps/ex13.subx -o apps/ex13
|
||||
./bootstrap_bin translate init.linux apps/ex13.subx -o apps/ex13
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex13
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/ex13 || ret=$?
|
||||
{
|
||||
./bootstrap_bin run apps/ex13 || ret=$?
|
||||
test $ret -eq 1 # 3 == 3
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/ex13 || ret=$?
|
||||
test $ret -eq 1 # 3 == 3
|
||||
}
|
||||
|
@ -182,15 +173,15 @@ test $NATIVE && {
|
|||
# Larger apps that use the standard library.
|
||||
|
||||
echo factorial
|
||||
./bootstrap translate init.$OS [01]*.subx apps/factorial.subx -o apps/factorial
|
||||
./bootstrap_bin translate init.linux [01]*.subx apps/factorial.subx -o apps/factorial
|
||||
test "$1" = 'record' || git diff --exit-code apps/factorial
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/factorial || ret=$?
|
||||
{
|
||||
./bootstrap_bin run apps/factorial || ret=$?
|
||||
test $ret -eq 120 # factorial(5)
|
||||
./bootstrap run apps/factorial test
|
||||
./bootstrap_bin run apps/factorial test
|
||||
echo
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/factorial || ret=$?
|
||||
test $ret -eq 120 # factorial(5)
|
||||
apps/factorial test
|
||||
|
@ -198,25 +189,25 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo crenshaw2-1
|
||||
./bootstrap translate init.$OS [01]*.subx apps/crenshaw2-1.subx -o apps/crenshaw2-1
|
||||
./bootstrap_bin translate init.linux [01]*.subx apps/crenshaw2-1.subx -o apps/crenshaw2-1
|
||||
test "$1" = 'record' || git diff --exit-code apps/crenshaw2-1
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/crenshaw2-1 test
|
||||
{
|
||||
./bootstrap_bin run apps/crenshaw2-1 test
|
||||
echo
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/crenshaw2-1 test
|
||||
echo
|
||||
}
|
||||
|
||||
echo crenshaw2-1b
|
||||
./bootstrap translate init.$OS [01]*.subx apps/crenshaw2-1b.subx -o apps/crenshaw2-1b
|
||||
./bootstrap_bin translate init.linux [01]*.subx apps/crenshaw2-1b.subx -o apps/crenshaw2-1b
|
||||
test "$1" = 'record' || git diff --exit-code apps/crenshaw2-1b
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/crenshaw2-1b test
|
||||
{
|
||||
./bootstrap_bin run apps/crenshaw2-1b test
|
||||
echo
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/crenshaw2-1b test
|
||||
echo
|
||||
}
|
||||
|
@ -226,13 +217,13 @@ test $NATIVE && {
|
|||
for phase in hex survey pack assort dquotes tests
|
||||
do
|
||||
echo $phase
|
||||
./bootstrap translate init.$OS [01]*.subx apps/subx-params.subx apps/$phase.subx -o apps/$phase
|
||||
./bootstrap_bin translate init.linux [01]*.subx apps/subx-params.subx apps/$phase.subx -o apps/$phase
|
||||
test "$1" = 'record' || git diff --exit-code apps/$phase
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/$phase test
|
||||
{
|
||||
./bootstrap_bin run apps/$phase test
|
||||
echo
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/$phase test
|
||||
echo
|
||||
}
|
||||
|
@ -241,70 +232,67 @@ done
|
|||
# Higher-level syntax.
|
||||
|
||||
# Certain phases of translation run native beyond this point. We're starting
|
||||
# to go beyond functionality of the C++ bootstrap.
|
||||
# to go beyond functionality of the C++ bootstrap_bin.
|
||||
|
||||
echo sigils
|
||||
./bootstrap translate init.$OS [012]*.subx apps/subx-params.subx apps/sigils.subx -o apps/sigils
|
||||
./bootstrap_bin translate init.linux [012]*.subx apps/subx-params.subx apps/sigils.subx -o apps/sigils
|
||||
test "$1" = 'record' || git diff --exit-code apps/sigils
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/sigils test
|
||||
{
|
||||
./bootstrap_bin run apps/sigils test
|
||||
echo
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/sigils test
|
||||
echo
|
||||
}
|
||||
|
||||
test $NATIVE || { echo 'there are more tests, but you need Linux to run them'; exit 0; }
|
||||
|
||||
echo calls
|
||||
cat init.$OS [012]*.subx apps/subx-params.subx apps/calls.subx | apps/sigils > a.sigils
|
||||
./bootstrap translate a.sigils -o apps/calls
|
||||
cat init.linux [012]*.subx apps/subx-params.subx apps/calls.subx | apps/sigils > a.sigils
|
||||
./bootstrap_bin translate a.sigils -o apps/calls
|
||||
test "$1" = 'record' || git diff --exit-code apps/calls
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/calls test
|
||||
{
|
||||
./bootstrap_bin run apps/calls test
|
||||
echo
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/calls test
|
||||
echo
|
||||
}
|
||||
|
||||
echo braces
|
||||
cat init.$OS [012]*.subx apps/subx-params.subx apps/braces.subx | apps/calls | apps/sigils > a.sigils
|
||||
./bootstrap translate a.sigils -o apps/braces
|
||||
cat init.linux [012]*.subx apps/subx-params.subx apps/braces.subx | apps/calls | apps/sigils > a.sigils
|
||||
./bootstrap_bin translate a.sigils -o apps/braces
|
||||
test "$1" = 'record' || git diff --exit-code apps/braces
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/braces test
|
||||
{
|
||||
./bootstrap_bin run apps/braces test
|
||||
echo
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/braces test
|
||||
echo
|
||||
}
|
||||
|
||||
echo mu
|
||||
cat init.$OS [0-2]*.subx apps/mu.subx | apps/braces | apps/calls | apps/sigils > a.sigils
|
||||
./bootstrap translate a.sigils -o apps/mu
|
||||
cat init.linux [0-2]*.subx apps/mu.subx | apps/braces | apps/calls | apps/sigils > a.sigils
|
||||
./bootstrap_bin translate a.sigils -o apps/mu
|
||||
test "$1" = 'record' || git diff --exit-code apps/mu
|
||||
test $EMULATED && {
|
||||
./bootstrap run apps/mu test
|
||||
{
|
||||
./bootstrap_bin run apps/mu test
|
||||
echo
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
apps/mu test
|
||||
echo
|
||||
}
|
||||
|
||||
test $NATIVE || exit 0
|
||||
echo "== translating using SubX (native only)"
|
||||
echo "== translating using the self-hosted translator"
|
||||
|
||||
# example programs
|
||||
|
||||
for n in `seq 1 12`
|
||||
do
|
||||
echo ex$n
|
||||
./translate_subx init.$OS apps/ex$n.subx
|
||||
./translate_subx init.linux apps/ex$n.subx
|
||||
diff apps/ex$n a.elf
|
||||
done
|
||||
|
||||
|
@ -313,7 +301,7 @@ done
|
|||
for app in factorial crenshaw2-1 crenshaw2-1b
|
||||
do
|
||||
echo $app
|
||||
./translate_subx init.$OS [01]*.subx apps/$app.subx
|
||||
./translate_subx init.linux [01]*.subx apps/$app.subx
|
||||
diff apps/$app a.elf
|
||||
done
|
||||
|
||||
|
@ -322,77 +310,77 @@ done
|
|||
for app in hex survey pack assort dquotes tests
|
||||
do
|
||||
echo $app
|
||||
./translate_subx init.$OS [01]*.subx apps/subx-params.subx apps/$app.subx
|
||||
./translate_subx init.linux [01]*.subx apps/subx-params.subx apps/$app.subx
|
||||
diff apps/$app a.elf
|
||||
done
|
||||
|
||||
for app in sigils calls braces
|
||||
do
|
||||
echo $app
|
||||
./translate_subx init.$OS [012]*.subx apps/subx-params.subx apps/$app.subx
|
||||
./translate_subx init.linux [012]*.subx apps/subx-params.subx apps/$app.subx
|
||||
diff apps/$app a.elf
|
||||
done
|
||||
|
||||
# Mu translator
|
||||
echo mu
|
||||
./translate_subx init.$OS [0-2]*.subx apps/mu.subx
|
||||
./translate_subx init.linux [0-2]*.subx apps/mu.subx
|
||||
diff apps/mu a.elf
|
||||
|
||||
# Mu programs
|
||||
|
||||
echo ex1.mu
|
||||
./translate_mu apps/ex1.mu
|
||||
test $EMULATED && {
|
||||
./bootstrap run a.elf || ret=$?
|
||||
{
|
||||
./bootstrap_bin run a.elf || ret=$?
|
||||
test $ret -eq 42 # life, the universe and everything
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
./a.elf || ret=$?
|
||||
test $ret -eq 42 # life, the universe and everything
|
||||
}
|
||||
|
||||
echo ex2.mu
|
||||
./translate_mu apps/ex2.mu
|
||||
test $EMULATED && {
|
||||
./bootstrap run a.elf || ret=$?
|
||||
{
|
||||
./bootstrap_bin run a.elf || ret=$?
|
||||
test $ret -eq 7
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
./a.elf || ret=$?
|
||||
test $ret -eq 7
|
||||
}
|
||||
|
||||
echo ex3.mu
|
||||
./translate_mu apps/ex3.mu
|
||||
test $EMULATED && {
|
||||
./bootstrap run a.elf || ret=$?
|
||||
{
|
||||
./bootstrap_bin run a.elf || ret=$?
|
||||
test $ret -eq 55
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
./a.elf || ret=$?
|
||||
test $ret -eq 55
|
||||
}
|
||||
|
||||
echo ex3.2.mu
|
||||
./translate_mu apps/ex3.2.mu
|
||||
test $EMULATED && {
|
||||
./bootstrap run a.elf || ret=$?
|
||||
{
|
||||
./bootstrap_bin run a.elf || ret=$?
|
||||
test $ret -eq 55
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
./a.elf || ret=$?
|
||||
test $ret -eq 55
|
||||
}
|
||||
|
||||
echo factorial.mu
|
||||
./translate_mu apps/factorial.mu
|
||||
test $EMULATED && {
|
||||
./bootstrap run a.elf || ret=$?
|
||||
{
|
||||
./bootstrap_bin run a.elf || ret=$?
|
||||
test $ret -eq 120
|
||||
./bootstrap run a.elf test
|
||||
./bootstrap_bin run a.elf test
|
||||
echo
|
||||
}
|
||||
test $NATIVE && {
|
||||
{
|
||||
./a.elf || ret=$?
|
||||
test $ret -eq 120
|
||||
./a.elf test
|
||||
|
|
|
@ -0,0 +1,286 @@
|
|||
#!/bin/sh
|
||||
# Build and test all included SubX programs on non-Linux platforms:
|
||||
# translate them into ELF binaries
|
||||
# compare the generated binaries with what's already in git
|
||||
# run/test the ELF binaries in emulated mode
|
||||
#
|
||||
# Example usage:
|
||||
# test_apps_emulated
|
||||
# test_apps_emulated record # don't compare with what's in git
|
||||
#
|
||||
# This script is slow. 20+ times slower than running natively on Linux.
|
||||
|
||||
set -e
|
||||
cd `dirname $0`
|
||||
|
||||
./build
|
||||
|
||||
echo "== translating using the bootstrap C++ translator"
|
||||
|
||||
# example programs
|
||||
|
||||
echo ex1
|
||||
./bootstrap_bin translate init.linux apps/ex1.subx -o apps/ex1
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex1
|
||||
{
|
||||
./bootstrap_bin run apps/ex1 || ret=$?
|
||||
test $ret -eq 42 # life, the universe and everything
|
||||
}
|
||||
|
||||
echo ex2
|
||||
./bootstrap_bin translate init.linux apps/ex2.subx -o apps/ex2
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex2
|
||||
{
|
||||
./bootstrap_bin run apps/ex2 || ret=$?
|
||||
test $ret -eq 7 # 3 + 4
|
||||
}
|
||||
|
||||
echo ex3
|
||||
./bootstrap_bin translate init.linux apps/ex3.subx -o apps/ex3
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex3
|
||||
{
|
||||
./bootstrap_bin run apps/ex3 || ret=$?
|
||||
test $ret -eq 55 # 1 + 2 + ... + 10
|
||||
}
|
||||
|
||||
echo ex4
|
||||
./bootstrap_bin translate init.linux apps/ex4.subx -o apps/ex4
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex4
|
||||
{
|
||||
echo a | ./bootstrap_bin run apps/ex4 >ex4.out || true
|
||||
test `cat ex4.out` = 'a'
|
||||
}
|
||||
|
||||
echo ex5
|
||||
./bootstrap_bin translate init.linux apps/ex5.subx -o apps/ex5
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex5
|
||||
{
|
||||
echo a | ./bootstrap_bin run apps/ex5 >ex5.out || true
|
||||
test `cat ex5.out` = 'a'
|
||||
}
|
||||
|
||||
echo ex6
|
||||
./bootstrap_bin translate init.linux apps/ex6.subx -o apps/ex6
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex6
|
||||
{
|
||||
./bootstrap_bin run apps/ex6 >ex6.out || true
|
||||
test "`cat ex6.out`" = 'Hello, world!'
|
||||
}
|
||||
|
||||
echo ex7
|
||||
./bootstrap_bin translate init.linux apps/ex7.subx -o apps/ex7
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex7
|
||||
{
|
||||
./bootstrap_bin run apps/ex7 || ret=$?
|
||||
test $ret -eq 97 # 'a'
|
||||
}
|
||||
|
||||
echo ex8
|
||||
./bootstrap_bin translate init.linux apps/ex8.subx -o apps/ex8
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex8
|
||||
{
|
||||
./bootstrap_bin run apps/ex8 abcd || ret=$?
|
||||
test $ret -eq 4 # length('abcd')
|
||||
}
|
||||
|
||||
echo ex9
|
||||
./bootstrap_bin translate init.linux apps/ex9.subx -o apps/ex9
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex9
|
||||
{
|
||||
./bootstrap_bin run apps/ex9 z x || ret=$?
|
||||
test $ret -eq 2 # 'z' - 'x'
|
||||
}
|
||||
|
||||
echo ex10
|
||||
./bootstrap_bin translate init.linux apps/ex10.subx -o apps/ex10
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex10
|
||||
{
|
||||
./bootstrap_bin run apps/ex10 abc abc || ret=$?
|
||||
test $ret -eq 1 # equal
|
||||
./bootstrap_bin run apps/ex10 abc abcd # 0; not equal
|
||||
}
|
||||
|
||||
echo ex11
|
||||
./bootstrap_bin translate init.linux apps/ex11.subx -o apps/ex11
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex11
|
||||
{
|
||||
./bootstrap_bin run apps/ex11
|
||||
echo
|
||||
}
|
||||
|
||||
echo ex12
|
||||
./bootstrap_bin translate init.linux apps/ex12.subx -o apps/ex12
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex12
|
||||
test $EMULATED && ./bootstrap_bin run apps/ex12 # final byte of mmap'd address is well-nigh guaranteed to be 0
|
||||
test $NATIVE && apps/ex12
|
||||
|
||||
echo ex13
|
||||
./bootstrap_bin translate init.linux apps/ex13.subx -o apps/ex13
|
||||
test "$1" = 'record' || git diff --exit-code apps/ex13
|
||||
{
|
||||
./bootstrap_bin run apps/ex13 || ret=$?
|
||||
test $ret -eq 1 # 3 == 3
|
||||
}
|
||||
|
||||
# Larger apps that use the standard library.
|
||||
|
||||
echo factorial
|
||||
./bootstrap_bin translate init.linux [01]*.subx apps/factorial.subx -o apps/factorial
|
||||
test "$1" = 'record' || git diff --exit-code apps/factorial
|
||||
{
|
||||
./bootstrap_bin run apps/factorial || ret=$?
|
||||
test $ret -eq 120 # factorial(5)
|
||||
./bootstrap_bin run apps/factorial test
|
||||
echo
|
||||
}
|
||||
|
||||
echo crenshaw2-1
|
||||
./bootstrap_bin translate init.linux [01]*.subx apps/crenshaw2-1.subx -o apps/crenshaw2-1
|
||||
test "$1" = 'record' || git diff --exit-code apps/crenshaw2-1
|
||||
{
|
||||
./bootstrap_bin run apps/crenshaw2-1 test
|
||||
echo
|
||||
}
|
||||
|
||||
echo crenshaw2-1b
|
||||
./bootstrap_bin translate init.linux [01]*.subx apps/crenshaw2-1b.subx -o apps/crenshaw2-1b
|
||||
test "$1" = 'record' || git diff --exit-code apps/crenshaw2-1b
|
||||
{
|
||||
./bootstrap_bin run apps/crenshaw2-1b test
|
||||
echo
|
||||
}
|
||||
|
||||
# Phases of the self-hosted SubX translator.
|
||||
|
||||
for phase in hex survey pack assort dquotes tests
|
||||
do
|
||||
echo $phase
|
||||
./bootstrap_bin translate init.linux [01]*.subx apps/subx-params.subx apps/$phase.subx -o apps/$phase
|
||||
test "$1" = 'record' || git diff --exit-code apps/$phase
|
||||
{
|
||||
./bootstrap_bin run apps/$phase test
|
||||
echo
|
||||
}
|
||||
done
|
||||
|
||||
# Higher-level syntax.
|
||||
|
||||
# Certain phases of translation run native beyond this point. We're starting
|
||||
# to go beyond functionality of the C++ bootstrap_bin.
|
||||
|
||||
echo sigils
|
||||
./bootstrap_bin translate init.linux [012]*.subx apps/subx-params.subx apps/sigils.subx -o apps/sigils
|
||||
test "$1" = 'record' || git diff --exit-code apps/sigils
|
||||
{
|
||||
./bootstrap_bin run apps/sigils test
|
||||
echo
|
||||
}
|
||||
|
||||
echo calls
|
||||
cat init.linux [012]*.subx apps/subx-params.subx apps/calls.subx | ./bootstrap_bin run apps/sigils > a.sigils
|
||||
./bootstrap_bin translate a.sigils -o apps/calls
|
||||
test "$1" = 'record' || git diff --exit-code apps/calls
|
||||
{
|
||||
./bootstrap_bin run apps/calls test
|
||||
echo
|
||||
}
|
||||
|
||||
echo braces
|
||||
cat init.linux [012]*.subx apps/subx-params.subx apps/braces.subx | ./bootstrap_bin run apps/calls | ./bootstrap_bin run apps/sigils > a.sigils
|
||||
./bootstrap_bin translate a.sigils -o apps/braces
|
||||
test "$1" = 'record' || git diff --exit-code apps/braces
|
||||
{
|
||||
./bootstrap_bin run apps/braces test
|
||||
echo
|
||||
}
|
||||
|
||||
echo mu
|
||||
cat init.linux [0-2]*.subx apps/mu.subx | ./bootstrap_bin run apps/braces | ./bootstrap_bin run apps/calls | ./bootstrap_bin run apps/sigils > a.sigils
|
||||
./bootstrap_bin translate a.sigils -o apps/mu
|
||||
test "$1" = 'record' || git diff --exit-code apps/mu
|
||||
{
|
||||
./bootstrap_bin run apps/mu test
|
||||
echo
|
||||
}
|
||||
|
||||
echo "== translating using the self-hosted translator"
|
||||
|
||||
# example programs
|
||||
|
||||
for n in `seq 1 12`
|
||||
do
|
||||
echo ex$n
|
||||
./translate_subx_emulated init.linux apps/ex$n.subx
|
||||
diff apps/ex$n a.elf
|
||||
done
|
||||
|
||||
# Larger apps that use the standard library.
|
||||
|
||||
for app in factorial crenshaw2-1 crenshaw2-1b
|
||||
do
|
||||
echo $app
|
||||
./translate_subx_emulated init.linux [01]*.subx apps/$app.subx
|
||||
diff apps/$app a.elf
|
||||
done
|
||||
|
||||
# Phases of the self-hosted SubX translator.
|
||||
|
||||
for app in hex survey pack assort dquotes tests
|
||||
do
|
||||
echo $app
|
||||
./translate_subx_emulated init.linux [01]*.subx apps/subx-params.subx apps/$app.subx
|
||||
diff apps/$app a.elf
|
||||
done
|
||||
|
||||
for app in sigils calls braces
|
||||
do
|
||||
echo $app
|
||||
./translate_subx_emulated init.linux [012]*.subx apps/subx-params.subx apps/$app.subx
|
||||
diff apps/$app a.elf
|
||||
done
|
||||
|
||||
# Mu translator
|
||||
echo mu
|
||||
./translate_subx_emulated init.linux [0-2]*.subx apps/mu.subx
|
||||
diff apps/mu a.elf
|
||||
|
||||
# Mu programs
|
||||
|
||||
echo ex1.mu
|
||||
./translate_mu_emulated apps/ex1.mu
|
||||
{
|
||||
./bootstrap_bin run a.elf || ret=$?
|
||||
test $ret -eq 42 # life, the universe and everything
|
||||
}
|
||||
|
||||
echo ex2.mu
|
||||
./translate_mu_emulated apps/ex2.mu
|
||||
{
|
||||
./bootstrap_bin run a.elf || ret=$?
|
||||
test $ret -eq 7
|
||||
}
|
||||
|
||||
echo ex3.mu
|
||||
./translate_mu_emulated apps/ex3.mu
|
||||
{
|
||||
./bootstrap_bin run a.elf || ret=$?
|
||||
test $ret -eq 55
|
||||
}
|
||||
|
||||
echo ex3.2.mu
|
||||
./translate_mu_emulated apps/ex3.2.mu
|
||||
{
|
||||
./bootstrap_bin run a.elf || ret=$?
|
||||
test $ret -eq 55
|
||||
}
|
||||
|
||||
echo factorial.mu
|
||||
./translate_mu_emulated apps/factorial.mu
|
||||
{
|
||||
./bootstrap_bin run a.elf || ret=$?
|
||||
test $ret -eq 120
|
||||
./bootstrap_bin run a.elf test
|
||||
echo
|
||||
}
|
||||
|
||||
exit 0
|
|
@ -1,6 +1,5 @@
|
|||
#!/bin/sh
|
||||
# Translate given Mu programs into ELF binaries.
|
||||
# Linux only for now.
|
||||
# Translate a given Mu program into an ELF binary on Linux.
|
||||
|
||||
set -e
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#!/bin/sh
|
||||
# Translate Mu programs with debug information on Linux.
|
||||
# Translate given Mu files with debug information on Linux.
|
||||
#
|
||||
# (You _could_ do something similar on other platforms using emulation. But I
|
||||
# often find that to be too slow.)
|
||||
|
||||
set -e
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
# Translate a Mu program using emulated mode on Linux or BSD or Mac.
|
||||
|
||||
set -e
|
||||
|
||||
./build
|
||||
|
||||
cat $* [0-9]*.mu |./bootstrap_bin run apps/mu > a.subx
|
||||
|
||||
./translate_subx_emulated init.linux [0-9]*.subx mu-init.subx a.subx
|
|
@ -1,19 +1,6 @@
|
|||
#!/bin/sh
|
||||
# Translate SubX by running the self-hosted translator natively on Linux.
|
||||
#
|
||||
# Possible knobs:
|
||||
# Whether to run a phase natively or in emulated mode.
|
||||
# This script is for running natively.
|
||||
# Whether to stop after a phase.
|
||||
# This script assumes inputs are already working so doesn't easily show
|
||||
# which phase an error happens in.
|
||||
# Whether to trace a phase. Whether to always trace or rerun with tracing
|
||||
# enabled after an error.
|
||||
# Leave tracing to other scripts. We save intermediate files so it's easy
|
||||
# to rerun a single phase afterwards.
|
||||
# Whether to run a phase with debug information. (Need to juggle multiple
|
||||
# sets of debug files.)
|
||||
# Again, that's for subsequent scripts.
|
||||
# Translate given SubX files by running the self-hosted translator natively on
|
||||
# Linux.
|
||||
|
||||
set -e
|
||||
|
||||
|
|
|
@ -1,28 +1,32 @@
|
|||
#!/bin/sh
|
||||
# Translate SubX files with debug information on Linux.
|
||||
# Translate given SubX files with debug information on Linux.
|
||||
#
|
||||
# Mu's core tooling has a gap:
|
||||
# 0. The C++ translator 'subx translate' can generate debug information on
|
||||
# Linux or BSD or Mac, but doesn't support any syntax sugar.
|
||||
# 1. The self-hosted translator 'translate' runs in emulated mode and can
|
||||
# run on Linux or BSD or Mac. However, syntax sugar passes (sigils and
|
||||
# calls) can be very slow to run emulated.
|
||||
# 2. The self-hosted translator 'translate_subx' runs natively on Linux. It is
|
||||
# fast, but you get no trace for runs and zero error-checking on the code
|
||||
# emitted by sigils and calls. Which could still be buggy.
|
||||
# Mu provides 3 canonical ways to translate unsafe SubX programs:
|
||||
# 0. The C++ translator 'bootstrap translate' can generate traces for
|
||||
# debugging on Linux or BSD or Mac, but doesn't support any syntax sugar.
|
||||
# 1. The self-hosted translator can be run natively on Linux using
|
||||
# 'translate_subx'. It is fast and supports all syntax sugar, but you get no
|
||||
# trace for debugging.
|
||||
# 2. The self-hosted translator can be run emulated on Linux or BSD or Mac
|
||||
# using 'translate_subx_emulated'. It supports all syntax sugar. However, it
|
||||
# can be slow if you generate traces.
|
||||
#
|
||||
# This script is a hack to get the best of all worlds. We run natively what we
|
||||
# must, and leverage as much debug information as possible. This arrangement
|
||||
# is snappy but requires Linux just like 'translate_subx'. You also are on your
|
||||
# own to mentally map desugared instructions in traces and error messages back
|
||||
# to the original sources.
|
||||
# This script fills in the gap above by stitching together aspects from
|
||||
# multiple approaches. It translates syntax sugar natively, but emulates lower
|
||||
# levels using the C++ translator. The result is complete and relatively fast
|
||||
# even when generating traces.
|
||||
#
|
||||
# The cost: it needs Linux. There is no script to generate traces while
|
||||
# running emulated on BSD or Mac. That's often impractically slow.
|
||||
|
||||
set -e
|
||||
|
||||
./build
|
||||
|
||||
cat $* |apps/braces > a.braces
|
||||
cat a.braces |apps/calls > a.calls
|
||||
cat a.calls |apps/sigils > a.sigils
|
||||
|
||||
./bootstrap --debug translate a.sigils -o a.elf
|
||||
./bootstrap_bin --debug translate a.sigils -o a.elf
|
||||
|
||||
chmod +x a.elf
|
||||
|
|
|
@ -1,20 +1,8 @@
|
|||
#!/bin/sh
|
||||
# Translate SubX by running the self-hosted translator in emulated mode on
|
||||
# Linux or BSD or Mac.
|
||||
# Translate given SubX files by running the self-hosted translator in emulated
|
||||
# mode on Linux or BSD or Mac.
|
||||
#
|
||||
# Possible knobs:
|
||||
# Whether to run a phase natively or in emulated mode.
|
||||
# Just always emulate for now since we debug on non-Linux.
|
||||
# Whether to stop after a phase.
|
||||
# Just always run all phases, but print out phases so it's clear where an
|
||||
# error happens.
|
||||
# Whether to trace a phase. Whether to always trace or rerun with tracing
|
||||
# enabled after an error.
|
||||
# Leave tracing to other scripts. We save intermediate files so it's easy
|
||||
# to rerun a single phase afterwards.
|
||||
# Whether to run a phase with debug information. (Need to juggle multiple
|
||||
# sets of debug files.)
|
||||
# Again, that's for subsequent scripts.
|
||||
# We _could_ generate traces here, but that's often extremely slow.
|
||||
|
||||
set -e
|
||||
|
||||
|
@ -24,9 +12,10 @@ cat $* |./bootstrap_bin run apps/braces > a.braces
|
|||
cat a.braces |./bootstrap_bin run apps/calls > a.calls
|
||||
cat a.calls |./bootstrap_bin run apps/sigils > a.sigils
|
||||
cat a.sigils |./bootstrap_bin run apps/tests > a.tests
|
||||
cat a.tests |./bootstrap_bin run apps/dquotes > a.dquotes
|
||||
cat a.dquotes |./bootstrap_bin run apps/assort > a.assort
|
||||
cat a.assort |./bootstrap_bin run apps/pack > a.pack
|
||||
cat a.tests |./bootstrap_bin run apps/assort > a.assort
|
||||
cat a.assort |./bootstrap_bin run apps/dquotes > a.dquotes
|
||||
cat a.dquotes |./bootstrap_bin run apps/assort > a.assort2
|
||||
cat a.assort2 |./bootstrap_bin run apps/pack > a.pack
|
||||
cat a.pack |./bootstrap_bin run apps/survey > a.survey
|
||||
cat a.survey |./bootstrap_bin run apps/hex > a.elf
|
||||
|
||||
|
|
Loading…
Reference in New Issue