This commit is contained in:
Kartik Agaram 2021-03-29 18:47:52 -07:00
parent 386641c021
commit 16f2bd1174
41 changed files with 106 additions and 131 deletions

View File

@ -3,9 +3,9 @@ We're now past C++ bootstrap.
Layers in the 1xx series are in bare SubX, without any syntax sugar. They are
intended to be used by the phases of the self-hosted translator to replicate
the functionality of the C++ bootstrap:
apps/hex.subx
apps/survey_elf.subx
apps/pack.subx
apps/dquotes.subx
apps/assort.subx
apps/tests.subx
hex.subx
survey_elf.subx
pack.subx
dquotes.subx
assort.subx
tests.subx

View File

@ -1,5 +1,5 @@
Layers in the 2xx series are in bare SubX, without any syntax sugar. They are
intended to be used by various syntax-sugar phases:
apps/sigils.subx
apps/calls.subx
apps/braces.subx
sigils.subx
calls.subx
braces.subx

View File

@ -7,7 +7,7 @@
# because we don't know if they refer to the line above or the line below.
#
# To run:
# $ bootstrap/bootstrap translate [01]*.subx apps/subx-params.subx apps/assort.subx -o apps/assort
# $ bootstrap/bootstrap translate [01]*.subx subx-params.subx assort.subx -o assort
# $ cat x
# == code
# abc

View File

@ -27,7 +27,7 @@ put_new(Help, "syntax",
"after a '/', but they can never contain whitespace. Metadata has no effect\n"
"at runtime, but can be handy when rewriting macros.\n"
"\n"
"Check out the example programs in the apps/ directory, particularly apps/ex*.\n"
"Check out the example programs linux/ex*.\n"
);
:(before "End Help Contents")
cerr << " syntax\n";

View File

@ -1,8 +1,8 @@
# Structured control flow using break/loop rather than jump.
#
# To run (on Linux):
# $ ./translate_subx init.linux [012]*.subx apps/subx-params.subx apps/braces.subx
# $ mv a.elf apps/braces
# $ ./translate_subx init.linux [012]*.subx subx-params.subx braces.subx
# $ mv a.elf braces
#
# Example 1:
# $ cat x.subx
@ -10,7 +10,7 @@
# 7c/jump-if-< break/disp8
# 74/jump-if-= loop/disp8
# }
# $ cat x.subx |apps/braces
# $ cat x.subx |braces
# _loop1:
# 7c/jump-if-< _break1/disp8
# 74/jump-if-= _loop1/disp8
@ -24,7 +24,7 @@
# {
# 74/jump-if-= loop/disp8
# }
# $ cat x.subx |apps/braces
# $ cat x.subx |braces
# _loop1:
# 7c/jump-if-< _break1/disp8
# _break1:
@ -40,7 +40,7 @@
# }
# 7c/jump-if-< loop/disp8
# }
# $ cat x.subx |apps/braces
# $ cat x.subx |braces
# _loop1:
# _loop2:
# 74/jump-if-= _loop2/disp8

View File

@ -1,18 +1,18 @@
# Function calls in a single line.
#
# To run (on Linux):
# $ ./translate_subx init.linux [012]*.subx apps/subx-params.subx apps/calls.subx
# $ mv a.elf apps/calls
# $ ./translate_subx init.linux [012]*.subx subx-params.subx calls.subx
# $ mv a.elf calls
#
# Example 1:
# $ echo '(foo %eax)' | apps/calls
# $ echo '(foo %eax)' | calls
# # . (foo %eax) # output has comments
# ff 6/subop/push %eax # push
# e8/call foo/disp32 # call
# 81 0/subop/add %esp 4/imm32 # undo push
#
# Example 2:
# $ echo '(foo Var1 *(eax + 4) "blah")' | apps/calls
# $ echo '(foo Var1 *(eax + 4) "blah")' | calls
# # . (foo Var1 *(eax + 4) "blah")
# 68/push "blah"/imm32
# ff 6/subop/push *(eax + 4) # push args in..

View File

@ -3,7 +3,7 @@
# except that we support hex digits.
#
# To run:
# $ bootstrap/bootstrap translate [01]*.subx apps/crenshaw2-1.subx -o apps/crenshaw2-1
# $ bootstrap/bootstrap translate [01]*.subx crenshaw2-1.subx -o crenshaw2-1
# $ echo '3' |bootstrap/bootstrap run crenshaw2-1
# Expected output:
# # syscall(exit, 3)

View File

@ -3,7 +3,7 @@
# except that we support hex numbers of multiple digits.
#
# To run:
# $ bootstrap/bootstrap translate [01]*.subx apps/crenshaw2-1b.subx -o apps/crenshaw2-1b
# $ bootstrap/bootstrap translate [01]*.subx crenshaw2-1b.subx -o crenshaw2-1b
# $ echo '1a' |bootstrap/bootstrap run crenshaw2-1b
# Expected output:
# # syscall(exit, 1a)

View File

@ -2,7 +2,7 @@
# Replace them with references to new variables in the data segment.
#
# To run:
# $ bootstrap/bootstrap translate [01]*.subx apps/subx-params.subx apps/dquotes.subx -o apps/dquotes
# $ bootstrap/bootstrap translate [01]*.subx subx-params.subx dquotes.subx -o dquotes
# $ cat x
# == code
# ab "cd ef"/imm32

View File

@ -2,7 +2,7 @@
# Just return 42.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex1.subx -o apps/ex1
# $ bootstrap/bootstrap translate ex1.subx -o ex1
# $ bootstrap/bootstrap run ex1
# Expected result:
# $ echo $?

View File

@ -1,7 +1,7 @@
# String comparison: return 1 iff the two args passed in at the commandline are equal.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex10.subx -o apps/ex10
# $ bootstrap/bootstrap translate ex10.subx -o ex10
# $ bootstrap/bootstrap run ex10 abc abd
# Expected result:
# $ echo $?

View File

@ -6,7 +6,7 @@
# a null-terminated 'kernel string' with a size-prefixed 'SubX string'.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex11.subx -o apps/ex11
# $ bootstrap/bootstrap translate ex11.subx -o ex11
# $ bootstrap/bootstrap run ex11 # runs a series of tests
# ...... # all tests pass
#

View File

@ -2,7 +2,7 @@
# Create a new segment using mmap, save the address, write to it.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex12.subx -o apps/ex12
# $ bootstrap/bootstrap translate ex12.subx -o ex12
# $ bootstrap/bootstrap run ex12
# You shouldn't get a segmentation fault.

View File

@ -1,7 +1,7 @@
# Compare 3 and 3.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex13.subx -o apps/ex13
# $ bootstrap/bootstrap translate ex13.subx -o ex13
# $ bootstrap/bootstrap run ex13
# Expected result:
# $ echo $?

View File

@ -1,7 +1,7 @@
# Multiply 2 numbers.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex14.subx -o apps/ex14
# $ bootstrap/bootstrap translate ex14.subx -o ex14
# $ bootstrap/bootstrap run ex14
# Expected result:
# $ echo $?

View File

@ -1,7 +1,7 @@
# Add 3 and 4, and return the result in the exit code.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex2.subx -o apps/ex2
# $ bootstrap/bootstrap translate ex2.subx -o ex2
# $ bootstrap/bootstrap run ex2
# Expected result:
# $ echo $?

View File

@ -1,7 +1,7 @@
# Add the first 10 numbers, and return the result in the exit code.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex3.subx -o apps/ex3
# $ bootstrap/bootstrap translate ex3.subx -o ex3
# $ bootstrap/bootstrap run ex3
# Expected result:
# $ echo $?

View File

@ -1,7 +1,7 @@
# Read a character from stdin, save it to a global, write it to stdout.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex4.subx -o apps/ex4
# $ bootstrap/bootstrap translate ex4.subx -o ex4
# $ bootstrap/bootstrap run ex4
== data

View File

@ -1,7 +1,7 @@
# Read a character from stdin, save it to a local on the stack, write it to stdout.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex5.subx -o apps/ex5
# $ bootstrap/bootstrap translate ex5.subx -o ex5
# $ bootstrap/bootstrap run ex5
== code

View File

@ -1,7 +1,7 @@
# Print out a (global variable) string to stdout.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex6.subx -o apps/ex6
# $ bootstrap/bootstrap translate ex6.subx -o ex6
# $ bootstrap/bootstrap run ex6
# Hello, world!

View File

@ -5,7 +5,7 @@
# the character read.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex7.subx -o apps/ex7
# $ bootstrap/bootstrap translate ex7.subx -o ex7
# $ bootstrap/bootstrap run ex7
# Expected result:
# $ echo $?

View File

@ -1,7 +1,7 @@
# Example reading commandline arguments: compute length of first arg.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex8.subx -o apps/ex8
# $ bootstrap/bootstrap translate ex8.subx -o ex8
# $ bootstrap/bootstrap run ex8 abc de fghi
# Expected result:
# $ echo $?

View File

@ -4,7 +4,7 @@
# letter of second arg.
#
# To run:
# $ bootstrap/bootstrap translate apps/ex9.subx -o apps/ex9
# $ bootstrap/bootstrap translate ex9.subx -o ex9
# $ bootstrap/bootstrap run ex9 z x
# Expected result:
# $ echo $?

View File

@ -14,7 +14,7 @@
# There's only one test in this file, but you'll also see tests running from
# Mu's standard library.
#
# Compare apps/factorial4.subx
# Compare factorial4.subx
fn factorial n: int -> _/eax: int {
compare n, 1

View File

@ -1,7 +1,7 @@
## compute the factorial of 5, and print the result
#
# To run:
# $ bootstrap/bootstrap translate [01]*.subx apps/factorial.subx -o apps/factorial
# $ bootstrap/bootstrap translate [01]*.subx factorial.subx -o factorial
# $ bootstrap/bootstrap run factorial
# Expected result:
# $ echo $?

View File

@ -4,7 +4,7 @@
# rm32 operands
#
# To run:
# $ ./translate_subx init.linux [01]*.subx apps/factorial.subx -o apps/factorial
# $ ./translate_subx init.linux [01]*.subx factorial.subx -o factorial
# $ bootstrap/bootstrap run factorial
# Expected result:
# $ echo $?
@ -16,7 +16,7 @@
# ........
# Every '.' indicates a passing test. Failing tests get a 'F'.
#
# Compare apps/factorial.subx
# Compare factorial.subx
== code

View File

@ -5,7 +5,7 @@
# function calls
#
# To run:
# $ ./translate_subx init.linux [01]*.subx apps/factorial.subx -o apps/factorial
# $ ./translate_subx init.linux [01]*.subx factorial.subx -o factorial
# $ bootstrap/bootstrap run factorial
# Expected result:
# $ echo $?
@ -17,7 +17,7 @@
# ........
# Every '.' indicates a passing test. Failing tests get a 'F'.
#
# Compare apps/factorial2.subx
# Compare factorial2.subx
== code

View File

@ -6,7 +6,7 @@
# control flow
#
# To run:
# $ ./translate_subx init.linux [01]*.subx apps/factorial.subx -o apps/factorial
# $ ./translate_subx init.linux [01]*.subx factorial.subx -o factorial
# $ bootstrap/bootstrap run factorial
# Expected result:
# $ echo $?
@ -18,7 +18,7 @@
# ........
# Every '.' indicates a passing test. Failing tests get a 'F'.
#
# Compare apps/factorial3.subx
# Compare factorial3.subx
== code

View File

@ -3,7 +3,7 @@
# comments between '#' and newline.
#
# To run:
# $ bootstrap/bootstrap translate [01]*.subx apps/subx-params.subx apps/hex.subx -o apps/hex
# $ bootstrap/bootstrap translate [01]*.subx subx-params.subx hex.subx -o hex
# $ echo '80 81 82 # comment' |bootstrap/bootstrap run hex |xxd -
# Expected output:
# 00000000: 8081 82

View File

@ -2,7 +2,7 @@
# http://akkartik.name/post/mu-2019-2
#
# To run:
# $ ./translate_subx init.linux [0-9]*.subx apps/mu.subx
# $ ./translate_subx init.linux [0-9]*.subx mu.subx
# $ ./a.elf < prog.mu > prog.elf
# == Goals

View File

@ -3,7 +3,7 @@
# uses are left untouched.
#
# To run:
# $ bootstrap/bootstrap translate [01]*.subx apps/subx-params.subx apps/pack.subx -o apps/pack
# $ bootstrap/bootstrap translate [01]*.subx subx-params.subx pack.subx -o pack
# $ echo '05/add-to-eax 0x20/imm32' |bootstrap/bootstrap run pack
# Expected output:
# 05 20 00 00 00 # 05/add-to-eax 0x20/imm32

View File

@ -1,7 +1,7 @@
# Repeatedly read 32-bit numbers from /dev/random, print them to stdout.
#
# To run:
# $ bootstrap/bootstrap translate [01]*.subx apps/random.subx -o apps/random
# $ bootstrap/bootstrap translate [01]*.subx random.subx -o random
# $ bootstrap/bootstrap run random
== code 0x09000000

View File

@ -2,7 +2,7 @@
# arguments.
#
# To run:
# $ bootstrap/bootstrap translate [012]*.subx apps/subx-params.subx apps/sigils.subx -o apps/sigils
# $ bootstrap/bootstrap translate [012]*.subx subx-params.subx sigils.subx -o sigils
#
# We currently support the following notations:
#

View File

@ -1,52 +1,52 @@
## Lines in source files
Initial -whitespace/comments/tests
apps/factorial.subx 120 44
apps/crenshaw2-1.subx 561 180
apps/crenshaw2-1b.subx 757 186
apps/hex.subx 1442 149
apps/survey_elf.subx 4733 905
apps/pack.subx 5881 840
apps/dquotes.subx 1925 383
apps/assort.subx 905 183
apps/tests.subx 284 137
apps/sigils.subx 4641 896
apps/calls.subx 1785 448
apps/braces.subx 360 121
apps/mu.subx 36692 12858
Initial -whitespace/comments/tests
factorial.subx 120 44
crenshaw2-1.subx 561 180
crenshaw2-1b.subx 757 186
hex.subx 1442 149
survey_elf.subx 4733 905
pack.subx 5881 840
dquotes.subx 1925 383
assort.subx 905 183
tests.subx 284 137
sigils.subx 4641 896
calls.subx 1785 448
braces.subx 360 121
mu.subx 36692 12858
## Total source lines needed including libraries
Initial -whitespace/comments/tests/dead code
apps/factorial.subx 8436 1700
apps/crenshaw2-1.subx 8644 1925
apps/crenshaw2-1b.subx 8736 1931
apps/hex.subx 9065 1908
apps/survey_elf.subx 10217 3248
apps/pack.subx 10589 2727
apps/dquotes.subx 9262 2468
apps/assort.subx 8686 2425
apps/tests.subx 8519 2214
apps/sigils.subx 10578 3043
apps/calls.subx 9242 2388
apps/braces.subx 8545 2111
apps/mu.subx 35438 15820
Initial -whitespace/comments/tests/dead code
factorial.subx 8436 1700
crenshaw2-1.subx 8644 1925
crenshaw2-1b.subx 8736 1931
hex.subx 9065 1908
survey_elf.subx 10217 3248
pack.subx 10589 2727
dquotes.subx 9262 2468
assort.subx 8686 2425
tests.subx 8519 2214
sigils.subx 10578 3043
calls.subx 9242 2388
braces.subx 8545 2111
mu.subx 35438 15820
## executable size in KB
Initial -tests/dead code
apps/crenshaw2-1 41 4.3
apps/crenshaw2-1b 42 5.2
apps/factorial 42 5.2
apps/hex 45 5.0
apps/survey_elf 51 9.6
apps/pack 54 7.6
apps/dquotes 46 6.5
apps/assort 42 6.4
apps/tests 41 5.8
apps/sigils 54 9.1
apps/calls 47 7.1
apps/braces 42 5.9
apps/mu 563 131.0
Initial -tests/dead code
crenshaw2-1 41 4.3
crenshaw2-1b 42 5.2
factorial 42 5.2
hex 45 5.0
survey_elf 51 9.6
pack 54 7.6
dquotes 46 6.5
assort 42 6.4
tests 41 5.8
sigils 54 9.1
calls 47 7.1
braces 42 5.9
mu 563 131.0
## history of apps/mu.subx
## history of mu.subx
date commit mu.subx -tests/cmts binary (KB excl. dead code)
parsing function headers 2019 Oct 30 5725 621 277 6.9
function calls Nov 10 5739 1202 346 7.2

View File

@ -3,7 +3,7 @@
# Use the addresses assigned to replace labels.
#
# To build:
# $ bootstrap/bootstrap translate [01]*.subx apps/subx-params.subx apps/survey_baremetal.subx -o apps/survey_baremetal
# $ bootstrap/bootstrap translate [01]*.subx subx-params.subx survey_baremetal.subx -o survey_baremetal
#
# The expected input is a stream of bytes and some interspersed labels.
# Comments and '==' segment headers are allowed, but names are ignored. The

View File

@ -5,7 +5,7 @@
# b) add an ELF header and segment headers with addresses and offsets correctly filled in
#
# To build:
# $ bootstrap/bootstrap translate [01]*.subx apps/subx-params.subx apps/survey_elf.subx -o apps/survey_elf
# $ bootstrap/bootstrap translate [01]*.subx subx-params.subx survey_elf.subx -o survey_elf
#
# The expected input is a stream of bytes with '==' segment headers, comments
# and some interspersed labels.

View File

@ -2,7 +2,7 @@
# all functions starting with 'test-'.
#
# To build:
# $ bootstrap/bootstrap translate [01]*.subx apps/subx-params.subx apps/tests.subx -o apps/tests
# $ bootstrap/bootstrap translate [01]*.subx subx-params.subx tests.subx -o tests
== code
# instruction effective address register displacement immediate

View File

@ -27,7 +27,7 @@ $ ./a.elf type
This is just a prototype. There are no tests.
To add a new primitive you'll need to hard-code it into the `evaluate`
function (apps/tile/rpn.mu).
function (linux/tile/rpn.mu).
There's also a second place you'll want to teach about predefined primitives:
`bound-function?` (apps/tile/environment.mu)
`bound-function?` (linux/tile/environment.mu)

View File

@ -1,6 +1,6 @@
## SubX
SubX is a notation for a subset of x86 machine code. [The Mu translator](http://akkartik.github.io/mu/html/apps/mu.subx.html)
SubX is a notation for a subset of x86 machine code. [The Mu translator](http://akkartik.github.io/mu/html/linux/mu.subx.html)
is implemented in SubX and also emits SubX code.
Here's an example program in SubX that adds 1 and 1 and returns the result to
@ -158,8 +158,8 @@ string literal surrounded by quotes (`"`) in an `imm32` argument. SubX will
transparently copy it to the `data` segment and replace it with its address.
Strings are the only place where a SubX word is allowed to contain spaces.
That should be enough information for writing SubX programs. The `apps/`
directory provides some fodder for practice in the `apps/ex*.subx` files,
That should be enough information for writing SubX programs. The `linux/`
directory provides some fodder for practice in the `linux/ex*.subx` files,
giving a more gradual introduction to SubX features. In particular, you should
work through `apps/factorial4.subx`, which demonstrates all the above ideas in
work through `linux/factorial4.subx`, which demonstrates all the above ideas in
concert.

View File

@ -79,7 +79,7 @@ and digest it:
Here's an example showing these arguments at work:
<img alt='apps/ex3.subx' src='html/ex3.png'>
<img alt='linux/ex3.subx' src='html/ex3.png'>
This program sums the first 10 natural numbers. By convention I use horizontal
tabstops to help read instructions, dots to help follow the long lines,
@ -151,7 +151,8 @@ $ echo $?
42
# or, automating the above steps
$ ./translate_subx init.linux apps/ex1.subx
$ cd linux
$ ./translate_subx 000init.linux ex1.subx
$ ./a.elf
$ echo $?
42
@ -160,7 +161,7 @@ $ echo $?
Or, running in a VM on other platforms (much slower):
```sh
$ ./translate_subx_emulated init.linux apps/ex1.subx # generates identical a.elf to above
$ ./translate_subx_emulated init.linux linux/ex1.subx # generates identical a.elf to above
$ bootstrap/bootstrap run a.elf
$ echo $?
42

View File

@ -27,32 +27,6 @@ augroup LocalVimrc
autocmd BufRead,BufNewFile *.subx set ft=subx
augroup END
" Scenarios considered:
" opening or starting vim with a new or existing file without an extension (should interpret as C++)
" opening or starting vim with a new or existing file with a .mu extension
" starting vim or opening a buffer without a file name (ok to do nothing)
" opening a second file in a new or existing window (shouldn't mess up existing highlighting)
" reloading an existing file (shouldn't mess up existing highlighting)
command! -nargs=1 E call EditMuFile("edit", <f-args>)
if exists("&splitvertical")
command! -nargs=1 S call EditMuFile("vert split", <f-args>)
command! -nargs=1 H call EditMuFile("hor split", <f-args>)
else
command! -nargs=1 S call EditMuFile("vert split", <f-args>)
command! -nargs=1 H call EditMuFile("split", <f-args>)
endif
function! EditMuFile(cmd, arg)
let l:full_path = "apps/" . a:arg
if filereadable(l:full_path . ".mu")
let l:full_path = l:full_path . ".mu"
else
let l:full_path = l:full_path . ".subx"
endif
exec "silent! " . a:cmd . " " . l:full_path
endfunction
" we often want to crib lines of machine code from other files
function! GrepSubX(regex)
" https://github.com/mtth/scratch.vim