157 lines
2.1 KiB
Io
157 lines
2.1 KiB
Io
input := ""
|
|
stack := List clone
|
|
should_quit := false
|
|
|
|
ops := Map clone
|
|
|
|
add_op := method(name, action,
|
|
ops atPut(name, action)
|
|
)
|
|
|
|
add_op("+", block(a, b, a + b))
|
|
add_op("-", block(a, b, b - a))
|
|
add_op("*", block(a, b, a * b))
|
|
|
|
add_op(">", block(a, b,
|
|
if(a > b, push(a); return(b), push(b); return(a))
|
|
))
|
|
|
|
add_op(":", block(a, b,
|
|
push(b)
|
|
push(a)
|
|
return(a)
|
|
))
|
|
|
|
add_op("~", block(a, b,
|
|
push(a)
|
|
return(b)
|
|
))
|
|
|
|
add_op("_", block(a, b,
|
|
return(b)
|
|
))
|
|
|
|
fns := Map clone
|
|
|
|
add_fn := method(name, action,
|
|
fns atPut(name, action)
|
|
)
|
|
|
|
add_fn("quit", block(
|
|
should_quit = true
|
|
))
|
|
|
|
add_fn("clear", block(
|
|
stack empty
|
|
))
|
|
|
|
add_fn("exec", block(
|
|
doword(pop)
|
|
))
|
|
add_fn("quote", block(
|
|
word := pop
|
|
word = "'#{word}" interpolate
|
|
push(word)
|
|
))
|
|
|
|
add_fn("exec_if_0", block(
|
|
value := pop
|
|
action := pop
|
|
if(value == 0, doword(action))
|
|
))
|
|
|
|
add_fn("peek", block(
|
|
depth := pop
|
|
push(stack at(stack size - 1 - depth))
|
|
))
|
|
add_fn("deref", block(
|
|
index := pop
|
|
push(stack at(index))
|
|
))
|
|
add_fn("write", block(
|
|
index := pop
|
|
stack atPut(index, pop)
|
|
))
|
|
add_fn("size", block(
|
|
push(stack size)
|
|
))
|
|
|
|
|
|
|
|
isnan := method(x, x asNumber != x asNumber)
|
|
|
|
pop := method(
|
|
stack pop
|
|
)
|
|
push := method(x,
|
|
if(x != nil,
|
|
stack append(x)
|
|
)
|
|
)
|
|
|
|
print_stack := method(
|
|
stack foreach(v, write(v, ", "))
|
|
write("\n")
|
|
)
|
|
|
|
read := method(
|
|
if(should_quit, return)
|
|
|
|
input = File standardInput readLine
|
|
|
|
doall(input)
|
|
|
|
print_stack
|
|
)
|
|
|
|
doall := method(line,
|
|
actions := line splitNoEmpties
|
|
actions foreach(v, doword(v))
|
|
)
|
|
|
|
doword := method(word,
|
|
if(isnan(word), exec(word), push(word asNumber))
|
|
)
|
|
|
|
exec := method(op,
|
|
if(op at(0) asCharacter == "'",
|
|
push(op exSlice(1))
|
|
return
|
|
)
|
|
|
|
if(op == "defun",
|
|
name := pop
|
|
|
|
code := stack clone
|
|
stack empty
|
|
|
|
add_fn(name, block(
|
|
code foreach(v, doword(v))
|
|
))
|
|
|
|
return
|
|
)
|
|
|
|
if(ops hasKey(op),
|
|
action := ops at(op)
|
|
result := action call(pop, pop)
|
|
push(result)
|
|
|
|
return
|
|
)
|
|
|
|
if(fns hasKey(op),
|
|
action := fns at(op)
|
|
action call
|
|
|
|
return
|
|
)
|
|
)
|
|
|
|
if(System args size > 1,
|
|
file := File with(System args at(1)) openForReading
|
|
doall(file contents)
|
|
)
|
|
|
|
print_stack
|
|
while(should_quit == false, read)
|