/*************************************************************************** assignment.cpp - description ------------------- begin : Thu Mar 20 20:42:02 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 #include ZObj * Assignment::eval(){ //exec_line done exec_line = line; ZObj * res = NULL; switch(lval->type){ case ZSYMB: res = do_ident_assign((Identifier*)lval,expression); break; case SUBSCRIPTION: res = do_sub_assign(lval,expression); break; case CALL: res = do_call_assign(lval,expression); break; case ATTRIBUTEREF: res = do_attrref_assign(lval,expression); break; default: Almost::aout<<"ASSIGNMENT IGNORED .... "<type<(res)!=NULL){ ZObj::collect(SymbolTable::instance()); return new ZStatus(true); } else throw ZError(line,"Something wrong ..."); } throw ZError(line,"Somthing wrong ..."); } ZObj * Assignment::do_ident_assign(Identifier * lval,Code * expression){ // cout<<"DEBUG "<eval(); // cout<<"DEBUG left "<)){ left = ZObj::rvalue(left); } else if(typeid(*left)==typeid(ZType)){ left = ZObj::rvalue(left); } else if(typeid(*left)==typeid(ZType)){ left = ZObj::rvalue(left); } // else cout<<"DEBUG new object"<class_name()<::iterator iter = SYMBOLTABLE.find(lval->val); if(iter==SYMBOLTABLE.end()){ SYMBOLTABLE[lval->val]=res; } else{ ZObj::remove(iter->second); SYMBOLTABLE[lval->val]=res; // Almost::aout<<"DEBUG "<val]->class_name()<class_name()<eval()); ZObj * r = ZObj::rvalue(expression->eval()); if(l==NULL){ throw ZError(line,"Invalid lvalue: "+sub->eval()->class_name() ); } ZObj * status = ZObj::BinaryOperator<'='>::apply(l,r); if(status==NULL) throw ZError(line,"invalid operands: "+ l->class_name()+" "+ r->class_name()); return status; } ZObj * Assignment::do_call_assign(Code * call, Code * expression){ // cout<<"DEBUG call_assign "<eval()); if(l==NULL){ throw ZError(line,"Invalid lvalue: "+call->eval()->class_name() ); } ZObj * r = expression->eval(); if(SymbolTable::instance().is_referenced(r)){ r = ZObj::rvalue(r); } // else cout<<"DEBUG new object"<eval()); ZObj * status = ZObj::BinaryOperator<'='>::apply(l,r); if(status==NULL) throw ZError(line,"invalid operands: "+ l->class_name()+" "+ r->class_name()); return status; } ZObj * Assignment::do_attrref_assign(Code * attr, Code * expression){ ZObj * o = attr->eval(); // cout<<"ATTR "<type()<eval()); if(!exp) throw ZError(line,"invalid rvalue"); ZObj * status = NULL; AttributeRef * _ref = (AttributeRef*) attr; ZObj * inst = ZObj::rvalue(_ref->primary->eval()); if(typeid(*inst)==typeid(ZInstance)){ ZInstance * zinst = dynamic_cast(inst); //cout<<_ref->identifier->val<)){ exp = ZObj::rvalue(exp); } else if(typeid(*exp)==typeid(ZType)){ exp = ZObj::rvalue(exp); } else if(typeid(*exp)==typeid(ZType)){ exp = ZObj::rvalue(exp); } status = zinst->attribute_assign(_ref->identifier->val,exp); if(status==NULL) throw ZError(line,"invalid operands"); } else { ZObj * attr_ref = ZObj::lvalue(o); if(attr_ref==NULL) throw ZError(line,"invalid lvalue"); status = ZObj::BinaryOperator<'='>::apply(attr_ref,exp); if(status==NULL) throw ZError(line,"invalid operands: "+ attr_ref->class_name()+" "+ exp->class_name()); } return status; }