initial commit.
This commit is contained in:
commit
ef227ee6cf
157
main.io
Normal file
157
main.io
Normal file
|
@ -0,0 +1,157 @@
|
|||
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)
|
Loading…
Reference in a new issue