Exemple #1
0
void add_while(Process *process, Obj *env, Obj *bytecodeObj, int *position, Obj *form) {
  assert(false);
  int start = *position;
  Obj *expression = form_to_bytecode(process, env, form->cdr->car);
  Obj *body = form_to_bytecode(process, env, form->cdr->cdr->car);
  Obj *literals = bytecodeObj->bytecode_literals;
  char new_literal_index = literals->count;
  obj_array_mut_append(literals, expression);
  obj_array_mut_append(literals, body);
  bytecodeObj->bytecode[*position + 0] = 'w';
  bytecodeObj->bytecode[*position + 1] = new_literal_index + 65;
  bytecodeObj->bytecode[*position + 2] = start + 65; // index to jump to
  *position += 3;
}
Exemple #2
0
void add_if(Process *process, Obj *env, Obj *bytecodeObj, int *position, Obj *form) {
  assert_or_set_error(form->cdr->car, "Too few body forms in 'if' form: ", form);
  assert_or_set_error(form->cdr->cdr->car, "Too few body forms in 'if' form: ", form);
  assert_or_set_error(form->cdr->cdr->cdr->car, "Too few body forms in 'if' form: ", form);
  assert_or_set_error(form->cdr->cdr->cdr->cdr->car == NULL, "Too many body forms in 'if' form (use explicit 'do').", form);
  Obj *true_branch = form_to_bytecode(process, env, form->cdr->cdr->car);
  Obj *false_branch = form_to_bytecode(process, env, form->cdr->cdr->cdr->car);
  Obj *literals = bytecodeObj->bytecode_literals;
  char new_literal_index = literals->count;
  obj_array_mut_append(literals, true_branch);
  obj_array_mut_append(literals, false_branch);
  visit_form(process, env, bytecodeObj, position, form->cdr->car);
  bytecodeObj->bytecode[*position] = 'i';
  bytecodeObj->bytecode[*position + 1] = new_literal_index + 65;
  *position += 2;
}
Exemple #3
0
void add_let(Process *process, Obj *env, Obj *bytecodeObj, int *position, Obj *form) {
  
  Obj *bindings = form->cdr->car;
  Obj *body = form->cdr->cdr->car;
  shadow_stack_push(process, bindings);
  shadow_stack_push(process, body);

  //printf("bindings: %s\n", obj_to_string(process, bindings)->s);

  Obj *bindings_only_symbols = obj_new_array(bindings->count / 2);
  shadow_stack_push(process, bindings_only_symbols);
  
  for(int i = 0; i < bindings_only_symbols->count; i++) {
    bindings_only_symbols->array[i] = bindings->array[i * 2];
    visit_form(process, env, bytecodeObj, position, bindings->array[i * 2 + 1]);
  }
  //printf("bindings_only_symbols: %s\n", obj_to_string(process, bindings_only_symbols)->s);

  Obj *literals = bytecodeObj->bytecode_literals;
  char new_literal_index = literals->count;
  Obj *let_body_code = form_to_bytecode(process, env, body);

  obj_array_mut_append(literals, bindings_only_symbols);
  obj_array_mut_append(literals, let_body_code);
  
  bytecodeObj->bytecode[*position] = 't';
  bytecodeObj->bytecode[*position + 1] = new_literal_index + 65;
  bytecodeObj->bytecode[*position + 2] = new_literal_index + 1 + 65;

  *position += 3;

  shadow_stack_pop(process);
  shadow_stack_pop(process);
  shadow_stack_pop(process);
}
Exemple #4
0
void visit_form(Process *process, Obj *env, Obj *bytecodeObj, int *position, Obj *form) {
  if(eval_error) {
    return;
  }
  else if(form->tag == 'C') {
    if(form->car->car == NULL) {
      add_literal(bytecodeObj, position, nil);
    }
    else if(HEAD_EQ("quote")) {
      add_literal(bytecodeObj, position, form->car);
    }
    else if(HEAD_EQ("if")) {
      add_if(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("while")) {
      add_while(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("do")) {
      add_do(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("let")) {
      add_let(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("def")) {
      add_def(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("reset!")) {
      add_reset(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("ref")) {
      add_ref(process, env, bytecodeObj, position, form);
    }
    /* else if(HEAD_EQ("or")) { */
    /*   add_or(process, env, bytecodeObj, position, form); */
    /* } */
    else if(HEAD_EQ("not")) {
      add_not(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("fn")) {
      Obj *lambda = obj_new_lambda(form->cdr->car, form_to_bytecode(process, env, form->cdr->cdr->car), env, form);
      add_literal(bytecodeObj, position, lambda);
    }
    else {
      add_call(process, env, bytecodeObj, position, form);
    }
  }
  else if(form->tag == 'Y') {
    add_lookup(bytecodeObj, position, form);
  }
  else {
    add_literal(bytecodeObj, position, form);
  }
  /* else { */
  /*   printf("Bytecode can't handle form: "); */
  /*   obj_print_cout(form); */
  /*   exit(1); */
  /* } */
}
Exemple #5
0
void process_eval(Process *process, Obj *form) {
  process->bytecodeObj = form_to_bytecode(process, process->global_env, form, false);
  //printf("Process will eval bytecode: %s\n", obj_to_string(process, process->bytecodeObj)->s);
  process->frames[process->frame].p = 0;
  process->frames[process->frame].bytecodeObj = process->bytecodeObj;
  process->frames[process->frame].env = process->global_env;
  process->final_result = NULL;
  stack_push(process, process->bytecodeObj); // make it not be GC:ed
  return;
}