|
|
| version 1.3, 2001/02/25 09:42:03 | version 1.22, 2001/03/09 08:28:33 |
|---|---|
| Line 13 class VMethodFrame : public WContext { | Line 13 class VMethodFrame : public WContext { |
| public: // Value | public: // Value |
| // all: for error reporting after fail(), etc | // all: for error reporting after fail(), etc |
| const char *type() const { return "MethodFrame"; } | const char *type() const { return "method_frame"; } |
| // frame: my or self_transparent | // frame: my or self_transparent |
| Value *get_element(const String& name) { | Value *get_element(const String& name) { |
| Value *result=static_cast<Value *>(my.get(name)); | if(my) { |
| if(!result) | Value *result=static_cast<Value *>(my->get(name)); |
| result=self->get_element(name); | if(result) |
| return result; | return result; |
| } | |
| return fself->get_element(name); | |
| } | } |
| // frame: my or self_transparent | // frame: my or self_transparent |
| void put_element(const String& name, Value *value){ | void put_element(const String& name, Value *value){ |
| if(!my.replace(name, value)) | if(!(my && my->put_replace(name, value))) |
| self->put_element(name, value); | fself->put_element(name, value); |
| } | } |
| // frame: self_transparent | |
| VClass* get_class() { return fself->get_class(); } | |
| // methodframe: self_transparent | |
| VAliased *get_aliased() { return fself->get_aliased(); } | |
| public: // usage | public: // usage |
| VMethodFrame(Pool& apool, const Junction& ajunction) : WContext(apool, 0 /* empty */), | VMethodFrame(Pool& apool, const Junction& ajunction/*info: always method-junction*/) : |
| WContext(apool, 0 /* empty */, false /* not constructing */), | |
| junction(ajunction), | junction(ajunction), |
| store_param_index(0), | store_param_index(0), |
| my(apool), | my(0), fnumbered_params(0), |
| self(0) { | fself(0) { |
| if(Method* method=junction.method) { // method junction? | |
| // remember local var names | Method &method=*junction.method; |
| if(method.max_numbered_params_count) // are this method params numbered? | |
| fnumbered_params=NEW Array(pool()); // create storage | |
| else // named params | |
| my=NEW Hash(pool()); // create storage | |
| if(method.locals_names) { // there are any local var names? | |
| // remember them | |
| // those are flags that name is local == to be looked up in 'my' | // those are flags that name is local == to be looked up in 'my' |
| for(int i=0; i<method->locals_names.size(); i++) { | for(int i=0; i<method.locals_names->size(); i++) { |
| my.put( | Value *value=NEW VUnknown(pool()); |
| *static_cast<String *>(method->locals_names.get(i)), | String& name=*static_cast<String *>(method.locals_names->get(i)); |
| NEW VUnknown(pool())); | my->put(name, value); |
| value->set_name(name); | |
| } | } |
| } | } |
| } | } |
| void set_self(Value *aself) { self=aself; } | void set_self(Value& aself) { fself=&aself; } |
| void store_param(Value *value) { | void store_param(Value *value) { |
| Method *method=junction.method; | Method& method=*junction.method; |
| if(store_param_index==method->params_names.size()) | int max_params= |
| method.max_numbered_params_count?method.max_numbered_params_count: | |
| method.params_names?method.params_names->size(): | |
| 0; | |
| if(store_param_index==max_params) | |
| THROW(0,0, | THROW(0,0, |
| name(), | &junction.self.name(), |
| "call: too many params (max=%d)", method->params_names.size()); | "(%s) method '%s' accepts maximum %d parameter(s)", |
| junction.self.type(), | |
| method.name.cstr(), | |
| max_params); | |
| my.put(*static_cast<String *>(method->params_names.get(store_param_index++)), value); | if(method.max_numbered_params_count) { // are this method params numbered? |
| *fnumbered_params+=value; | |
| } else { // named param | |
| String& name=*static_cast<String *>( | |
| method.params_names->get(store_param_index++)); | |
| my->put(name, value); // remember param | |
| value->set_name(name); // set param's 'name' | |
| } | |
| } | } |
| void fill_unspecified_params() { | void fill_unspecified_params() { |
| Method *method=junction.method; | Method &method=*junction.method; |
| for(; store_param_index<method->params_names.size(); store_param_index++) | if(method.params_names) // there are any named parameters might need filling? |
| my.put( | for(; store_param_index<method.params_names->size(); store_param_index++) { |
| *static_cast<String *>(method->params_names.get(store_param_index)), | Value *value=NEW VUnknown(pool()); |
| NEW VUnknown(pool())); | String& name=*static_cast<String *>( |
| method.params_names->get(store_param_index)); | |
| my->put(name, value); | |
| value->set_name(name); | |
| } | |
| } | } |
| Array *numbered_params() { return fnumbered_params; } | |
| public: | public: |
| const Junction& junction; | const Junction& junction; |
| private: | private: |
| int store_param_index; | int store_param_index; |
| Hash my; | Hash *my;/*OR*/Array *fnumbered_params; |
| Value *self; | Value *fself; |
| }; | }; |