/*************************************************************************** augmentedassignment.cpp - description ------------------- begin : Thu Mar 20 20:37:30 2003 copyright : (C) 2002 by Cavalli Andrea email : cavalli@bioc.unizh.ch **************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include ZObj * AugmentedAssignment::eval(){ //exec_line done exec_line = line; ZObj * ident; ZObj * res = NULL; //decode primary switch(lval->type){ case ZSYMB: res = do_ident_aassign((Identifier*)lval); break; case SUBSCRIPTION: res = do_sub_aassign(lval); break; case CALL: res = do_call_aassign(lval); break; case ATTRIBUTEREF: res = do_attr_aassign(lval); break; default: throw ZError(line,"augassignment ignored .... "); } if(dynamic_cast(res)!=NULL){ ZObj::collect(SymbolTable::instance()); return new ZStatus(true); } else throw ZError(line,"Something wrong ..."); //newr reached return new ZStatus(false); } ZObj * AugmentedAssignment::do_ident_aassign(Identifier * lval){ //find if there map::iterator iter = SYMBOLTABLE.find(lval->val); if(iter==SYMBOLTABLE.end()){ throw ZError(line,"unknown identifier"); } else{ ZObj * r = apply(ZObj::reference(iter->second)); ZObj::remove(iter->second); SYMBOLTABLE[lval->val]=r; } return new ZStatus(true); } ZObj * AugmentedAssignment::do_sub_aassign(Code * sub){ ZObj * l = ZObj::lvalue(sub->eval()); ZListRef * ref = (ZListRef*) l; ZObj * r = apply(ZObj::rvalue(ref)); ZObj::remove(*(ref->iter)); *(ref->iter) = r; ZObj::remove(ref); return new ZStatus(true); } ZObj * AugmentedAssignment::do_attr_aassign(Code * attr){ ZObj * attr_ref = ZObj::lvalue(attr->eval()); if(attr_ref==NULL) throw ZError(line,"invalid lvalue"); ZObj * r = apply(attr_ref); ZObj * status; if(r!=NULL) status =ZObj::BinaryOperator<'='>::apply(attr_ref,r); if(status!=NULL) return new ZStatus(true); throw ZError(line,"invalid operand"); } ZObj * AugmentedAssignment::do_call_aassign(Code * call){ throw ZError(line,"Not implemented ...."); } ZObj * AugmentedAssignment::apply(ZObj * l){ //perform operation ZObj * tmp = NULL; ZObj * exp = ZObj::rvalue(expression->eval()); switch(op){ case ADD_ASSIGN: tmp = ZObj::BinaryOperator<'+'>::apply(l,exp); break; case SUB_ASSIGN: tmp = ZObj::BinaryOperator<'-'>::apply(l,exp); break; case MUL_ASSIGN: tmp = ZObj::BinaryOperator<'*'>::apply(l,exp); break; case DIV_ASSIGN: tmp = ZObj::BinaryOperator<'/'>::apply(l,exp); break; case MOD_ASSIGN: tmp = ZObj::BinaryOperator<'%'>::apply(l,exp); break; case EXP_ASSIGN: tmp = ZObj::BinaryOperator::apply(l,exp); break; case RIGHT_ASSIGN: tmp = ZObj::BinaryOperator::apply(l,exp); break; case LEFT_ASSIGN: tmp = ZObj::BinaryOperator::apply(l,exp); break; case AND_ASSIGN: tmp = ZObj::BinaryOperator<'&'>::apply(l,exp); break; case OR_ASSIGN: tmp = ZObj::BinaryOperator<'|'>::apply(l,exp); break; case XOR_ASSIGN: tmp = ZObj::BinaryOperator<'^'>::apply(l,exp); break; default: Almost::aout<<"NOT IMPLEMENTED OPERATOR "<