expr visit_macro(expr const & e) { buffer<expr> new_args; for (unsigned i = 0; i < macro_num_args(e); i++) new_args.push_back(visit(macro_arg(e, i))); auto def = macro_def(e); expr r = update_macro(e, new_args.size(), new_args.data()); if (def.trust_level() >= m_trust_lvl) { if (optional<expr> new_r = m_tc.expand_macro(r)) { return *new_r; } else { throw_generic_exception("failed to expand macro", e); } } else { return r; } }
[[ noreturn ]] void throw_class_exception(expr const & m, pp_fn const & fn) { throw_generic_exception(m, fn); }
OBJECT_PTR eval_backquote(OBJECT_PTR form) { OBJECT_PTR car_obj; assert(is_valid_object(form)); if(is_atom(form)) return form; car_obj = car(form); assert(is_valid_object(car_obj)); if(IS_SYMBOL_OBJECT(car_obj)) { char buf[SYMBOL_STRING_SIZE]; print_symbol(car_obj, buf); if(car_obj == COMMA) { OBJECT_PTR temp = compile(CADR(form), NIL); #ifdef WIN32 if(temp == ERROR1) #else if(temp == ERROR) #endif { throw_generic_exception("Backquote evaluation(1): compile failed"); return NIL; } reg_next_expression = cons(cons(FRAME, cons(cons(CONS_HALT_NIL, CADR(form)), cons(temp, CADR(form)))), CADR(form)); reg_current_value_rib = NIL; while(car(reg_next_expression) != NIL) { //print_object(car(reg_next_expression));printf("\n");getchar(); eval(false); if(in_error) { throw_generic_exception("Evaluation of backquote failed(1)"); return NIL; } } reg_next_expression = cons(CONS_RETURN_NIL, cdr(reg_next_expression)); reg_current_value_rib = NIL; return reg_accumulator; } } if(form_contains_comma_at(form)) { //1. loop through elements in form //2. if element is not comma-at, call eval_backquote on // it and append it to the result list without splicing //3. if it is comma-at, get its symbol value and // splice the value to the result list //4. return the result list OBJECT_PTR result = NIL; OBJECT_PTR rest = form; while(rest != NIL) { OBJECT_PTR ret; OBJECT_PTR obj; if(IS_CONS_OBJECT(car(rest)) && IS_SYMBOL_OBJECT(CAAR(rest))) { char buf[SYMBOL_STRING_SIZE]; print_symbol(CAAR(rest), buf); if(CAAR(rest) == COMMA_AT) { OBJECT_PTR temp = compile(CADAR(rest), NIL); #ifdef WIN32 if(temp == ERROR1) #else if(temp == ERROR) #endif { throw_generic_exception("Backquote evaluation(2): compile failed"); return NIL; } reg_next_expression = cons(cons(FRAME, cons(cons(CONS_HALT_NIL, CADAR(rest)), cons(temp, CADAR(rest)))), CADAR(rest)); reg_current_value_rib = NIL; while(car(reg_next_expression) != NIL) { eval(false); if(in_error) { throw_generic_exception("Evaluation of backquote failed(2)"); return NIL; } } reg_next_expression = cons(CONS_RETURN_NIL, cdr(reg_next_expression)); reg_current_value_rib = NIL; obj = reg_accumulator; if(result == NIL) result = obj; else set_heap(last_cell(result) & POINTER_MASK, 1, obj); } else { obj = eval_backquote(car(rest)); if(result == NIL) result = cons(obj, NIL); else set_heap(last_cell(result) & POINTER_MASK, 1, cons(obj, NIL)); } } else { obj = eval_backquote(car(rest)); if(result == NIL) result = cons(obj, NIL); else set_heap(last_cell(result) & POINTER_MASK, 1, cons(obj, NIL)); } rest = cdr(rest); } return result; } return cons(eval_backquote(car(form)), eval_backquote(cdr(form))); }
[[ noreturn ]] void throw_class_exception(char const * msg, expr const & m) { throw_generic_exception(msg, m); }