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