summaryrefslogtreecommitdiff
path: root/internal/interpreter/interpreter.ha
diff options
context:
space:
mode:
authorJulian Hurst <ark@mansus.space>2026-03-17 17:52:34 +0100
committerJulian Hurst <ark@mansus.space>2026-03-17 17:52:34 +0100
commitbd6a57220d6643223952419a68faea6d9bc0725a (patch)
tree6cf6d1aacaa231caa44b298b4398e6cae8cbbfeb /internal/interpreter/interpreter.ha
parent9c4f57d5e8fc015fcc4d47990e334556357ed568 (diff)
downloadrabbitscript-bd6a57220d6643223952419a68faea6d9bc0725a.tar.gz
Initial parser/interp and test file
Diffstat (limited to 'internal/interpreter/interpreter.ha')
-rw-r--r--internal/interpreter/interpreter.ha56
1 files changed, 56 insertions, 0 deletions
diff --git a/internal/interpreter/interpreter.ha b/internal/interpreter/interpreter.ha
new file mode 100644
index 0000000..5e92461
--- /dev/null
+++ b/internal/interpreter/interpreter.ha
@@ -0,0 +1,56 @@
+use internal::parser;
+use strconv;
+use strings;
+
+export type variable = (str, str);
+export type interpreter = struct {
+ vars: []variable,
+};
+
+export type error = !(interperror | nomem);
+export type interperror = !str;
+
+export fn interpret(it: *interpreter, tree: parser::ast) void = {
+ match (tree.value) {
+ case parser::assign =>
+ assign(it, tree.children)!;
+ };
+};
+
+fn assign(it: *interpreter, nodes: []parser::ast) (void | error) = {
+ const varname = nodes[0].value as parser::varname;
+ const operation = nodes[1].value as parser::operation;
+
+ let value = 0;
+
+ let stack: []int = [];
+
+ for (let i = 0z; i < len(operation.stack); i += 1) {
+ const arg = operation.stack[i];
+ match (arg) {
+ case let i: int =>
+ append(stack, i)?;
+ case let o: parser::operator =>
+ if (len(stack) >= 2) {
+ let last = len(stack) - 1;
+ let val = switch (o) {
+ case parser::operator::ADD =>
+ yield stack[last] + stack[last-1];
+ case parser::operator::SUBTRACT =>
+ yield stack[last] - stack[last-1];
+ case parser::operator::MULTIPLY =>
+ yield stack[last] * stack[last-1];
+ case parser::operator::DIVIDE =>
+ yield stack[last] / stack[last-1];
+ };
+ delete(stack[last-1..]);
+ append(stack, val)?;
+ } else {
+ return "Invalid operation": interperror;
+ };
+ };
+ };
+
+ let last = len(stack) - 1;
+ append(it.vars, (varname, strings::dup(strconv::itos(stack[last]))?))?;
+};