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; }
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; }
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); }
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); */ /* } */ }
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; }