Annotation of parser3/src/types/pa_vmethod_frame.h, revision 1.22
1.3 paf 1: /** @file
1.5 paf 2: Parser: @b method_frame write context
1.3 paf 3:
1.21 paf 4: Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
1.22 ! paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1 paf 6:
1.22 ! paf 7: $Id: pa_vmethod_frame.h,v 1.21 2002/02/08 07:27:53 paf Exp $
1.1 paf 8: */
9:
10: #ifndef PA_VMETHOD_FRAME_H
11: #define PA_VMETHOD_FRAME_H
12:
13: #include "pa_wcontext.h"
1.12 parser 14: #include "pa_vvoid.h"
1.1 paf 15: #include "pa_vjunction.h"
16:
1.4 paf 17: /** Method frame write context
18: accepts values written by method code
19: also handles method parameters and local variables
1.3 paf 20: */
1.1 paf 21: class VMethodFrame : public WContext {
22: public: // Value
23:
24: const char *type() const { return "method_frame"; }
1.20 paf 25:
26: /// VMethodFrame: $result | parent get_string(=accumulated fstring)
27: const String *get_string() {
28: // check the $result value
29: Value *result=get_result_variable();
30: // if we have one, return it's string value, else return as usual: accumulated fstring or fvalue
31: return result ? result->get_string() : WContext::get_string();
32: }
33:
1.4 paf 34: /// VMethodFrame: my or self_transparent
1.1 paf 35: Value *get_element(const String& name) {
36: if(my) {
37: Value *result=static_cast<Value *>(my->get(name));
38: if(result)
39: return result;
40: }
41: return fself->get_element(name);
42: }
1.4 paf 43: /// VMethodFrame: my or self_transparent
1.1 paf 44: void put_element(const String& name, Value *value){
45: if(!(my && my->put_replace(name, value)))
46: fself->put_element(name, value);
47: }
48:
1.4 paf 49: /// VMethodFrame: self_transparent
1.1 paf 50: VStateless_class* get_class() { return fself->get_class(); }
51:
1.4 paf 52: /// VMethodFrame: self_transparent
1.1 paf 53: VAliased *get_aliased() { return fself->get_aliased(); }
54:
55: public: // wcontext
56:
1.20 paf 57: Value& result() {
1.1 paf 58: // check the $result value
1.20 paf 59: Value *result=get_result_variable();
1.1 paf 60: // if we have one, return it, else return as usual: accumulated fstring or fvalue
1.20 paf 61: return result ? *result : WContext::result();
1.1 paf 62: }
63:
64: public: // usage
65:
66: VMethodFrame(Pool& apool,
1.8 parser 67: const String& name,
1.13 parser 68: const Junction& ajunction/*info: always method-junction*/) :
1.14 parser 69: WContext(apool, 0 /* empty */),
1.1 paf 70:
71: junction(ajunction),
72: store_param_index(0),
1.15 parser 73: fself(0),
74: fresult_initial_void(0) {
1.9 parser 75: set_name(name);
1.1 paf 76:
77: const Method &method=*junction.method;
78:
1.3 paf 79: if(method.max_numbered_params_count) { // are this method params numbered?
80: my=0; // no named parameters
1.8 parser 81: fnumbered_params=NEW MethodParams(pool(), name); // create storage
1.3 paf 82: } else { // named params
1.1 paf 83: my=NEW Hash(pool()); // create storage
1.3 paf 84: fnumbered_params=0; // no numbered parameters
1.1 paf 85:
86: if(method.locals_names) { // are there any local var names?
87: // remember them
88: // those are flags that name is local == to be looked up in 'my'
89: for(int i=0; i<method.locals_names->size(); i++) {
90: // speedup: not checking for clash with "result" name
1.12 parser 91: Value *value=NEW VVoid(pool());
1.1 paf 92: const String& name=*method.locals_names->get_string(i);
1.18 paf 93: set_my_variable(name, value);
1.1 paf 94: }
95: }
96: { // always there is one local: $result
1.15 parser 97: fresult_initial_void=NEW VVoid(pool());
1.18 paf 98: set_my_variable(*result_var_name, fresult_initial_void);
1.1 paf 99: }
100: }
101: }
102:
103: void set_self(Value& aself) { fself=&aself; }
104: Value *self() { return fself; }
105:
106: void store_param(const String& actual_method_name, Value *value) {
107: const Method& method=*junction.method;
108: int max_params=
109: method.max_numbered_params_count?method.max_numbered_params_count:
110: method.params_names?method.params_names->size():
111: 0;
112: if(store_param_index==max_params)
1.17 parser 113: throw Exception(0,0,
1.1 paf 114: &actual_method_name,
1.7 paf 115: "method of %s (%s) accepts maximum %d parameter(s)",
1.1 paf 116: junction.self.name().cstr(),
117: junction.self.type(),
118: max_params);
119:
120: if(method.max_numbered_params_count) { // are this method params numbered?
121: *fnumbered_params+=value;
122: } else { // named param
123: // speedup: not checking for clash with "result" name
124: const String& name=*method.params_names->get_string(store_param_index);
1.18 paf 125: set_my_variable(name, value);
1.1 paf 126: }
127: store_param_index++;
128: }
129: void fill_unspecified_params() {
130: const Method &method=*junction.method;
131: if(method.params_names) // there are any named parameters might need filling?
132: for(; store_param_index<method.params_names->size(); store_param_index++) {
1.12 parser 133: Value *value=NEW VVoid(pool());
1.1 paf 134: const String& name=*method.params_names->get_string(store_param_index);
135: my->put(name, value);
136: value->set_name(name);
137: }
138: }
139:
1.3 paf 140: MethodParams *numbered_params() { return fnumbered_params; }
1.18 paf 141:
142: private:
143:
144: void set_my_variable(const String& name, Value *value) {
145: my->put(name, value); // remember param
146: value->set_name(name); // set param's 'name'
1.20 paf 147: }
148:
149: Value *get_result_variable() {
150: Value *result=my?static_cast<Value*>(my->get(*result_var_name)):0;
151: return result && result!=fresult_initial_void ? result : 0;
1.18 paf 152: }
1.1 paf 153:
154: public:
155:
156: const Junction& junction;
157:
158: private:
159: int store_param_index;
1.3 paf 160: Hash *my;/*OR*/MethodParams *fnumbered_params;
1.1 paf 161: Value *fself;
1.15 parser 162:
163: private:
164: Value *fresult_initial_void;
1.1 paf 165:
166: };
167:
168: #endif
E-mail: