io_calculator/main.io
2023-10-31 17:43:57 +01:00

158 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)