From 65f17438de5983ca010e10b4b24c5da65756a9b5 Mon Sep 17 00:00:00 2001 From: Teddy Date: Sun, 4 Aug 2013 11:50:41 +0800 Subject: added exception facilities --- builtin.cpp | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'builtin.cpp') diff --git a/builtin.cpp b/builtin.cpp index 1ac0cf2..806d911 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -1,3 +1,5 @@ +#include "exc.h" +#include "consts.h" #include "builtin.h" #include #include @@ -120,7 +122,7 @@ Cons *SpecialOptLambda::call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr) { Cons *ret_addr = static_cast(*top_ptr)->addr; Cons *pc = static_cast(ret_addr->car); - SymbolList *para_list = dynamic_cast(pc->cdr->car); // parameter list + SymbolList *para_list = static_cast(pc->cdr->car); // Clear the flag to avoid side-effects (e.g. proc calling) FILL_MARKS(pc, false); @@ -157,16 +159,25 @@ Cons *SpecialOptDefine::call(ArgList *args, Environment * &envt, EvalObj *obj; SymObj *id; // TODO: check identifier - if (pc->cdr->car->is_simple_obj()) + EvalObj *first = pc->cdr->car; + if (first->is_simple_obj()) { - id = dynamic_cast(pc->cdr->car); + if (!first->is_sym_obj()) + throw TokenError(first->ext_repr(), SYN_ERR_NOT_AN_ID); + + id = static_cast(first); obj = args->cdr->car; } else { // static_cast because of is_simple_obj() is false Cons *plst = static_cast(pc->cdr->car); - id = dynamic_cast(plst->car); + if (plst == empty_list) + throw NormalError(SYN_ERR_ID_EXPECTED); + if (!plst->car->is_sym_obj()) + throw TokenError(first->ext_repr(), SYN_ERR_NOT_AN_ID); + + id = static_cast(plst->car); ArgList *para_list = plst->cdr; // Clear the flag to avoid side-effects (e.g. proc calling) FILL_MARKS(pc, false); @@ -197,9 +208,15 @@ Cons *SpecialOptSet::call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr) { Cons *ret_addr = static_cast(*top_ptr)->addr; Cons *pc = static_cast(ret_addr->car); - SymObj *id = dynamic_cast(pc->cdr->car); + EvalObj *first = pc->cdr->car; + + if (!first->is_sym_obj()) + throw TokenError(first->ext_repr(), SYN_ERR_NOT_AN_ID); + + SymObj *id = static_cast(first); + bool flag = envt->add_binding(id, args->cdr->car, false); - // TODO: throw an exc "unbound variable" + if (!flag) throw TokenError(id->ext_repr(), SYN_ERR_UNBOUND_VAR); *top_ptr++ = new UnspecObj(); return ret_addr->next; } -- cgit v1.2.3