From ef227ee6cf898518cf71dd19fef73f2e9ca05493 Mon Sep 17 00:00:00 2001 From: trans_soup <> Date: Tue, 31 Oct 2023 17:43:57 +0100 Subject: [PATCH] initial commit. --- main.io | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 main.io diff --git a/main.io b/main.io new file mode 100644 index 0000000..2771e8a --- /dev/null +++ b/main.io @@ -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)