/nix/store/dlwqlnbaj5vfm9aw20r1yxk8y56lmgif-repo/header.tmpl
tree-sitter-oat-v1/calculator.oat

150 lines
3.1 KiB
Text
Raw Permalink Normal View History

2025-10-31 19:42:55 +01:00
int[] new_stack() {
var s = new int[7];
s[0] = 5;
s[1] = 0; /* current index of stack ptr (offset 2) */
return s;
}
int peek_stack(int[] s) {
var index = 1 + s[1];
return s[index];
}
int[] pop_stack(int[] s) {
var cur_index = s[1];
if(cur_index > 0) {
cur_index = cur_index - 1;
}
s[1] = cur_index;
return maybe_new_stack(s);
}
int[] push_stack(int[] s, int v) {
var cur_index = 2 + s[1];
s[cur_index] = v;
s[1] = cur_index - 1;
return maybe_new_stack(s);
}
int[] maybe_new_stack(int[] s) {
/* if index of s > half the size, double the size of s */
/* if index of s < quarter the size, half the size of s */
return s;
var cur_index = s[1];
var cur_size = s[0];
if(cur_size <= 5) {
/* min size is 5 */
return s;
}
if(cur_index > (cur_size << 1)) {
/* double size of s */
var new_s = new int[2 + cur_size * 2];
cur_size = cur_size * 2;
new_s[0] = cur_size;
new_s[1] = cur_index;
/* copy over values */
for(var i = 0; i <= cur_index; i = i + 1;) {
new_s[2 + i] = s[2 + i];
}
return new_s;
} else if(cur_index < ((cur_size << 1) << 1)) {
/* halve s */
var new_s = new int[2 + cur_size << 1];
cur_size = cur_size << 1;
new_s[0] = cur_size;
new_s[1] = cur_index;
/* copy over values */
for(var i = 0; i <= cur_index; i = i + 1;) {
new_s[2 + i] = s[2 + i];
}
return new_s;
}
return s;
}
int get_val(int i) {
/* turns a char_code i into a value v */
return i - 48;
}
int int_of_string(string s) {
var arr = array_of_string(s);
var len = length_of_string(s);
var sum = 0;
for(var i = 0; i < len; i = i + 1;) {
sum = sum * 10;
var val = get_val(arr[i]);
sum = sum + val;
}
return sum;
}
int program (int argc, string[] argv) {
/* a stack based calculator. feed in input numbers and operands + and - */
/* will calculate result. a reverse polish notation calculator */
var str = "\n";
var stack = new_stack();
for(var i = 1; i < argc; i = i + 1;) {
var current_item = argv[i];
var did_op = false;
var len = length_of_string(current_item);
if(len == 1) {
var arr = array_of_string(current_item);
did_op = true;
if(arr[0] == 43) {
/* plus op */
var x1 = peek_stack(stack);
stack = pop_stack(stack);
var x2 = peek_stack(stack);
stack = pop_stack(stack);
stack = push_stack(stack, x1 + x2);
} else if(arr[0] == 45) {
/* minus op */
var x1 = peek_stack(stack);
stack = pop_stack(stack);
var x2 = peek_stack(stack);
stack = pop_stack(stack);
stack = push_stack(stack, x1 - x2);
} else if(arr[0] == 120) {
/* times op */
var x1 = peek_stack(stack);
stack = pop_stack(stack);
var x2 = peek_stack(stack);
stack = pop_stack(stack);
stack = push_stack(stack, x1 * x2);
} else {
did_op = false;
}
}
if(!did_op) {
/* didn't do op! we have a number maybe */
var v = int_of_string(current_item);
stack = push_stack(stack, v);
}
}
print_int(peek_stack(stack));
return peek_stack(stack);
}