--- parser3/src/main/execute.C 2001/10/22 12:30:24 1.198 +++ parser3/src/main/execute.C 2001/11/01 16:27:20 1.202 @@ -4,7 +4,7 @@ Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) Author: Alexander Petrosyan (http://design.ru/paf) - $Id: execute.C,v 1.198 2001/10/22 12:30:24 parser Exp $ + $Id: execute.C,v 1.202 2001/11/01 16:27:20 paf Exp $ */ #include "pa_opcode.h" @@ -47,7 +47,7 @@ char *opcode_name[]={ // expression ops: unary "NEG", "INV", "NOT", "DEF", "IN", "FEXISTS", "DEXISTS", // expression ops: binary - "SUB", "ADD", "MUL", "DIV", "MOD", + "SUB", "ADD", "MUL", "DIV", "MOD", "INTDIV", "BIN_AND", "BIN_OR", "BIN_XOR", "LOG_AND", "LOG_OR", "LOG_XOR", "NUM_LT", "NUM_GT", "NUM_LE", "NUM_GE", "NUM_EQ", "NUM_NE", @@ -244,7 +244,7 @@ void Request::execute(const Array& ops) // forget the fact they've entered some ^object.method[]. // see OP_GET_ELEMENT - wcontext->clear_somebody_entered_some_object(); + wcontext->set_somebody_entered_some_object(false); break; } case OP_WRITE_EXPR_RESULT: @@ -266,7 +266,7 @@ void Request::execute(const Array& ops) case OP_GET_ELEMENT: { // maybe they do ^object.method[] call, remember the fact - wcontext->inc_somebody_entered_some_object(); + wcontext->set_somebody_entered_some_object(true); //_asm int 3; value=get_element(); @@ -349,7 +349,7 @@ void Request::execute(const Array& ops) case OP_PREPARE_TO_CONSTRUCT_OBJECT: { - wcontext->constructing(true); + wcontext->set_constructing(true); break; } case OP_CALL: @@ -365,8 +365,8 @@ void Request::execute(const Array& ops) PUSH(wcontext); VStateless_class *called_class=frame->junction.self.get_class(); - if(wcontext->constructing()) { - wcontext->constructing(false); + if(wcontext->get_constructing()) { + wcontext->set_constructing(false); if(frame->junction.method->call_type!=Method::CT_STATIC) { // this is a constructor call @@ -391,8 +391,8 @@ void Request::execute(const Array& ops) // is context object or class & is it my class or my parent's class and? VStateless_class *read_class=rcontext->get_class(); if( - !(wcontext->somebody_entered_some_object() && - !wcontext->somebody_entered_some_class()) && + !(wcontext->get_somebody_entered_some_object() && + !wcontext->get_somebody_entered_some_class()) && read_class && read_class->is_or_derived_from(*called_class)) // yes self=rcontext; // dynamic call else // no, not me or relative of mine (=total stranger) @@ -400,7 +400,7 @@ void Request::execute(const Array& ops) } frame->set_self(*self); - root=rcontext=wcontext=frame; + rcontext=wcontext=frame; { // take object or class from any wrappers // and substitute class alias to the class they are called AS @@ -414,6 +414,7 @@ void Request::execute(const Array& ops) method.call_type==call_type) { // allowed call type? try { if(method.native_code) { // native code? + // root unchanged, so that ^for ^foreach & co may write to locals method.check_actual_numbered_params( frame->junction.self, frame->name(), frame->numbered_params()); @@ -421,6 +422,7 @@ void Request::execute(const Array& ops) *this, frame->name(), frame->numbered_params()); // execute it } else { // parser code + root=frame; if(++anti_endless_execute_recoursion==ANTI_ENDLESS_EXECUTE_RECOURSION) { anti_endless_execute_recoursion=0; // give @exception a chance throw Exception(0, 0, @@ -488,6 +490,7 @@ void Request::execute(const Array& ops) } case OP_IN: { + /// @test String::cmp Value *operand=POP(); const char *path=operand->as_string().cstr(); value=NEW VBool(pool(), @@ -578,6 +581,28 @@ void Request::execute(const Array& ops) PUSH(value); break; } + case OP_INTDIV: + { + b=POP(); a=POP(); + + int a_int=a->as_int(); + int b_int=b->as_int(); + + if(b_int == 0) { + const String *problem_source=&b->as_string(); +#ifndef NO_STRING_ORIGIN + if(!problem_source->origin().file) + problem_source=&b->name(); +#endif + throw Exception(0, 0, + problem_source, + "Division by zero"); + } + + value=NEW VInt(pool(), a_int / b_int); + PUSH(value); + break; + } case OP_BIN_AND: { b=POP(); a=POP(); @@ -735,7 +760,7 @@ Value *Request::get_element() { if(Method* method=OP.get_method(name)) { // maybe operator? // as if that method were in self and we have normal dynamic method here Junction& junction=*NEW Junction(pool(), - *root/*self*/, self->get_class(), method, 0,0,0,0); + *root, self->get_class(), method, 0,0,0,0); value=NEW VJunction(junction); } if(value)