get "libhdr"

// Read a string
let reads(v) be
$(  let ch = ?
    v%0 := 0
    ch := rdch()
    until ch = '*N' do
    $(  v%0 := v%0 + 1
        v%(v%0) := ch
        ch := rdch()
    $)
$)

// Try to read a number, fail on EOF
// (Alas, the included READN just returns 0 and that's a valid number)
let readnum(n) = valof
$(  let neg, ch = false, ?
    !n := 0
    $(  ch := rdch()
        if ch = endstreamch then resultis false
    $) repeatuntil ch = '-' | '0' <= ch <= '9'
    if ch = '-' then 
    $(  neg := true
        ch := rdch()
    $)
    while '0' <= ch <= '9' do 
    $(  !n := !n * 10 + ch - '0'
        ch := rdch()
    $)
    if neg then !n := -!n
    resultis true
$)

// Read SUBLEQ code 
let readfile(file, v) = valof
$(  let i, oldin = 0, input()
    selectinput(file)
    while readnum(v+i) do i := i + 1
    endread()
    selectinput(oldin)
    resultis i
$)

// Run SUBLEQ code
let run(v) be
$(  let ip = 0
    until ip < 0 do 
    $(  let a, b, c = v!ip, v!(ip+1), v!(ip+2)
        ip := ip + 3
        test a=-1 
            then v!b := rdch()
        else test b=-1 
            then wrch(v!a)
        else
        $(  v!b := v!b - v!a
            if v!b <= 0 then ip := c
        $)
    $)
$)

let start() be
$(  let filename = vec 64
    let file = ?
    
    writes("Filename? ")
    reads(filename)
    file := findinput(filename)
    test file = 0 then
        writes("Cannot open file.*N")
    else    
    $(  let top = maxvec()
        let mem = getvec(top)
        let progtop = readfile(file, mem)
        for i = progtop to top do mem!i := 0
        run(mem)
        freevec(mem)
    $)
$)