int main(int argc, char *argv[])
{
  struct Stack *s = Stack_new(5);
  push(s, 5);
  push(s, 3);
  push(s, 2);
  pop(s);
  Stack_print(s);

  return 0;
}
Esempio n. 2
0
File: vm.c Progetto: txus/terrorvm
VALUE VM_run(STATE)
{
  Debugger_load_current_file(state);

  int *ip = CURR_FRAME->fn->code;

  while(1) {
    switch(*ip) {
      case NOOP:
        break;
      case SETLINE: { // debugging
        ip++;
        Debugger_setline(state, *ip);
        break;
      }
      case PUSH: {
        Debugger_evaluate(state);
        ip++;
        debugi("PUSH %i", *ip);
        VALUE value = LITERAL(*ip);
        Stack_push(STACK, value);
        break;
      }
      case PUSHTRUE: {
        Debugger_evaluate(state);
        debugi("PUSHTRUE");
        Stack_push(STACK, TrueObject);
        break;
      }
      case PUSHFALSE: {
        Debugger_evaluate(state);
        debugi("PUSHFALSE");
        Stack_push(STACK, FalseObject);
        break;
      }
      case PUSHNIL: {
        Debugger_evaluate(state);
        debugi("PUSHNIL");
        Stack_push(STACK, NilObject);
        break;
      }
      case JMP: {
        Debugger_evaluate(state);
        ip++;
        int jump = *ip;
        debugi("JMP %i", jump);
        while(jump--) ip++;
        break;
      }
      case JIF: {
        Debugger_evaluate(state);
        ip++;
        int jump = *ip;
        debugi("JIF %i", jump);

        VALUE value = Stack_pop(STACK);
        if (value == FalseObject || value == NilObject) {
          while(jump--) ip++;
        }

        break;
      }
      case JIT: {
        Debugger_evaluate(state);
        ip++;
        int jump = *ip;
        debugi("JIT %i", jump);

        VALUE value = Stack_pop(STACK);
        if (value != FalseObject && value != NilObject) {
          while(jump--) ip++;
        }

        break;
      }
      case GOTO: {
        Debugger_evaluate(state);
        ip++;
        int jump = *ip - 2;

        debugi("GOTO %i", jump);

        ip = CURR_FRAME->fn->code;
        while(jump--) ip++;

        break;
      }
      case GETSLOT: {
        Debugger_evaluate(state);
        ip++;
        debugi("GETSLOT %i", *ip);
        VALUE receiver = Stack_pop(STACK);
        VALUE slot     = LITERAL(*ip);

        check(receiver->type != NilType, "Tried to get a slot from nil.");
        check(slot->type == StringType, "Slot name must be a String.");

        VALUE value = Value_get(receiver, VAL2STR(slot));
        check(value, "Undefined slot %s on object type %i.", VAL2STR(slot), receiver->type);

        Stack_push(STACK, value);
        break;
      }
      case SETSLOT: {
        Debugger_evaluate(state);
        ip++;
        debugi("SETSLOT %i", *ip);
        VALUE value    = Stack_pop(STACK);
        VALUE receiver = Stack_pop(STACK);
        VALUE slot     = LITERAL(*ip);

        check(receiver->type != NilType, "Tried to set a slot on nil.");
        check(slot->type == StringType, "Slot name must be a String.");

        Value_set(state, receiver, VAL2STR(slot), value);
        Stack_push(STACK, value); // push the rhs back to the stack
        break;
      }
      case DEFN: {
        Debugger_evaluate(state);
        ip++;
        debugi("DEFN %i", *ip);
        VALUE fn_name = LITERAL(*ip);
        bstring state_fn = bfromcstr(VAL2STR(fn_name));
        VALUE closure = Closure_new(state, STATE_FN(state_fn), CURR_FRAME);
        bdestroy(state_fn);
        Stack_push(STACK, closure);
        break;
      }
      case MAKEVEC: {
        Debugger_evaluate(state);
        ip++;
        debugi("MAKEVEC %i", *ip);
        int count = *ip;
        DArray *array = DArray_create(sizeof(VALUE), count || 1);

        while(count--) {
          VALUE elem = Stack_pop(STACK);
          check(elem, "Stack underflow.");
          GC_protect(elem);
          DArray_push(array, elem);
        }

        VALUE vector = Vector_new(state, array);
        Stack_push(STACK, vector);
        Vector_each(vector, ^ void (VALUE element) {
          GC_unprotect(element);
        });
        break;
      }
      case SEND: {
        Debugger_evaluate(state);
        ip++;
        int op1 = *ip;
        ip++;
        int op2 = *ip;

        debugi("SEND %i %i", op1, op2);

        VALUE name = LITERAL(op1);
        int argcount = op2;

        DArray *locals = DArray_create(sizeof(VALUE), argcount+1);
        while(argcount--) {
          DArray_push(locals, Stack_pop(STACK));
        }
        VALUE receiver = Stack_pop(STACK);

        // Special chicken-egg case. We cannot define "apply" as a native method
        // on Closure, since that triggers the creation of a new closure ad
        // infinitum, so we have to handle this special function here.
        if(receiver->type == ClosureType &&
           strcmp(VAL2STR(name), "apply") == 0) {

          state->ret = ip; // save where we want to return
          ip = Function_call(state, VAL2FN(receiver), CURR_FRAME->self, locals, VAL2STR(name));
          break;
        }

        VALUE closure = Value_get(receiver, VAL2STR(name));
        check(closure, "Undefined slot %s on object type %i.", VAL2STR(name), receiver->type);

        if (closure->type != ClosureType && closure != NilObject) {
          // GETSLOT
          Stack_push(STACK, closure);
          DArray_destroy(locals);
          break;
        }

#ifdef OPTIMIZE_SEND
        if(op2 == 1 && strcmp(VAL2STR(name), "[]") == 0) { // getslot
          VALUE key = (VALUE)DArray_at(locals, 0);
          Stack_push(STACK, Value_get(receiver, VAL2STR(key)));
          DArray_destroy(locals);
          break;
        }

        if(op2 == 2 && strcmp(VAL2STR(name), "[]=") == 0) { // setslot
          VALUE key   = (VALUE)DArray_at(locals, 0);
          VALUE value = (VALUE)DArray_at(locals, 1);
          Value_set(receiver, VAL2STR(key), value);
          Stack_push(STACK, value);
          DArray_destroy(locals);
          break;
        }
#endif

        state->ret = ip; // save where we want to return
        ip = Function_call(state, VAL2FN(closure), receiver, locals, VAL2STR(name));
        break;
      }
      case PUSHLOBBY: {
        Debugger_evaluate(state);
        debugi("PUSHLOBBY");
        Stack_push(STACK, state->lobby);
        break;
      }
      case PUSHSELF: {
        Debugger_evaluate(state);
        debugi("PUSHSELF");
        Stack_push(STACK, CURR_FRAME->self);
        break;
      }
      case PUSHLOCAL: {
        Debugger_evaluate(state);
        ip++;
        Stack_push(STACK, LOCAL(*ip));
        debugi("PUSHLOCAL %i", *ip);
        break;
      }
      case PUSHLOCALDEPTH: {
        Debugger_evaluate(state);
        ip++;
        int depth = *ip;
        ip++;
        Stack_push(STACK, DEEPLOCAL(depth, *ip));
        debugi("PUSHLOCALDEPTH %i %i", depth, *ip);
        break;
      }
      case SETLOCAL: {
        Debugger_evaluate(state);
        ip++;
        debugi("SETLOCAL %i", *ip);
        LOCALSET(*ip, Stack_peek(STACK));
        break;
      }
      case SETLOCALDEPTH: {
        Debugger_evaluate(state);
        ip++;
        int depth = *ip;
        ip++;
        debugi("SETLOCAL %i %i", depth, *ip);
        DEEPLOCALSET(depth, *ip, Stack_peek(STACK));
        break;
      }
      case POP: {
        Debugger_evaluate(state);
        ip++;
        int count = *ip;
        debugi("POP %i", count);
        check(Stack_count(STACK) >= count, "Stack underflow.");
        while(count--) Stack_pop(STACK);
        break;
      }
      case RET: {
        Debugger_evaluate(state);
        debugi("RET");
        CallFrame *old_frame = Stack_pop(FRAMES);

        ip = old_frame->ret;

        CallFrame_destroy(old_frame);

        check(Stack_count(STACK) > 0, "Stack underflow.");

        if (ip == NULL) return Stack_pop(STACK); // if there's nowhere to return, exit

        break;
      }
      case DUMP: {
        Debugger_evaluate(state);
        debugi("DUMP");
        Stack_print(state, STACK);
        DArray *literals = CURR_FRAME->fn->literals;
        printf("--LITERALS (%i)--\n", DArray_count(literals));
        Value_print_all(state, literals);

        DArray *locals = CURR_FRAME->locals;
        printf("--LOCALS (%i)--\n", DArray_count(locals));
        Value_print_all(state, locals);
        break;
      }
    }
Esempio n. 3
0
void UnlambdaEval_eval(UnlambdaEval* self, char* xs){
  char x;
  Stack* stack;
  Memory * memory;

  stack = UnlambdaEval_getStack(self);
  memory = UnlambdaEval_getMemory(self);

  while (*xs){
    x = *xs;

    switch(x){
      case '`':
        Stack_push(stack, quote());
        break;

      case '.':
        xs++;
        Stack_push(stack, (print(*xs)));
        break;

      case 'r':
        Stack_push(stack, (print('\n')));
        break;

      case 'i':
        Stack_push(stack, identity());
        break;

      case 'k':
        Stack_push(stack, constant_function());
        break;

      case 's':
        Stack_push(stack, generalized_evaluation());
        break;

      default:
        break;
    }
    while (runnable()){
      if(World_getDebug(getWorld()))
        Stack_print(stack);
      UnlambdaEval_runOnce(self);
      Memory_mark(memory, stack);
      Memory_sweep(memory);
      if(World_getDebug(getWorld()))
        Memory_stat(memory);
    }
    xs++;
  }
  while (runnable()){
    if(World_getDebug(getWorld()))
      Stack_print(stack);
    UnlambdaEval_runOnce(self);
    Memory_mark(memory, stack);
    Memory_sweep(memory);
    if(World_getDebug(getWorld()))
      Memory_stat(memory);
  }

  return;
}