--- parser3/src/main/execute.C 2001/10/29 16:07:36 1.200 +++ parser3/src/main/execute.C 2001/11/16 11:03:02 1.206 @@ -2,9 +2,9 @@ Parser: executor part of request class. Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) - Author: Alexander Petrosyan (http://design.ru/paf) + Author: Alexander Petrosyan (http://paf.design.ru) - $Id: execute.C,v 1.200 2001/10/29 16:07:36 paf Exp $ + $Id: execute.C,v 1.206 2001/11/16 11:03:02 paf Exp $ */ #include "pa_opcode.h" @@ -25,7 +25,7 @@ //#define DEBUG_EXECUTE -const uint ANTI_ENDLESS_EXECUTE_RECOURSION=200; +const uint ANTI_ENDLESS_EXECUTE_RECOURSION=500; #ifdef DEBUG_EXECUTE char *opcode_name[]={ @@ -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", @@ -371,12 +371,14 @@ void Request::execute(const Array& ops) // this is a constructor call if(Value *value=called_class->create_new_value(pool())) { - // some stateless_object creatable derivates + // some stateless_class creatable derivates self=value; - } else { - // stateful object - self=NEW VObject(pool(), *called_class); - } + } else + throw Exception(0, 0, + &frame->name(), + "is not a constructor, system class '%s' can be constructed only implicitly", + called_class->name().cstr()); + frame->write(*self, String::UL_CLEAN // not used, always an object, not string ); @@ -400,7 +402,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 +416,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 +424,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, @@ -579,6 +583,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(); @@ -736,7 +762,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)