149 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
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);
 | 
						|
}
 |