Annotation of parser3/src/types/pa_vmethod_frame.h, revision 1.26
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.26 ! paf 7: $Id: pa_vmethod_frame.h,v 1.25 2002/04/18 10:51:02 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.25 paf 35: Value *get_element(const String& fname) {
36: if(junction.method->max_numbered_params_count==0) {
37: Value *result=static_cast<Value *>(my.get(fname));
1.1 paf 38: if(result)
39: return result;
40: }
1.25 paf 41: return fself->get_element(fname);
1.1 paf 42: }
1.4 paf 43: /// VMethodFrame: my or self_transparent
1.25 paf 44: void put_element(const String& fname, Value *value){
45: if(!(junction.method->max_numbered_params_count==0 && my.put_replace(fname, value)))
46: fself->put_element(fname, value);
1.1 paf 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.24 paf 57: StringOrValue result() {
1.1 paf 58: // check the $result value
1.24 paf 59: Value *result_value=get_result_variable();
1.1 paf 60: // if we have one, return it, else return as usual: accumulated fstring or fvalue
1.24 paf 61: return result_value ? StringOrValue(0, result_value) : WContext::result();
1.1 paf 62: }
63:
64: public: // usage
65:
66: VMethodFrame(Pool& apool,
1.25 paf 67: const String& aname,
1.13 parser 68: const Junction& ajunction/*info: always method-junction*/) :
1.14 parser 69: WContext(apool, 0 /* empty */),
1.1 paf 70:
1.25 paf 71: fname(aname),
1.1 paf 72: junction(ajunction),
73: store_param_index(0),
1.25 paf 74:
75: my(apool),
76: fnumbered_params(apool, aname),
77:
1.15 parser 78: fself(0),
79: fresult_initial_void(0) {
1.1 paf 80:
1.25 paf 81: if(has_my()) { // this method uses named params?
82: const Method &method=*junction.method;
1.1 paf 83: if(method.locals_names) { // are there any local var names?
84: // remember them
1.25 paf 85: // those are flags that fname is local == to be looked up in 'my'
1.1 paf 86: for(int i=0; i<method.locals_names->size(); i++) {
1.25 paf 87: // speedup: not checking for clash with "result" fname
1.12 parser 88: Value *value=NEW VVoid(pool());
1.25 paf 89: const String& fname=*method.locals_names->get_string(i);
90: set_my_variable(fname, value);
1.1 paf 91: }
92: }
93: { // always there is one local: $result
1.15 parser 94: fresult_initial_void=NEW VVoid(pool());
1.18 paf 95: set_my_variable(*result_var_name, fresult_initial_void);
1.1 paf 96: }
97: }
98: }
99:
1.25 paf 100: const String& name() { return fname; }
101:
1.1 paf 102: void set_self(Value& aself) { fself=&aself; }
103: Value *self() { return fself; }
104:
1.26 ! paf 105: void store_param(Value *value) {
1.1 paf 106: const Method& method=*junction.method;
107: int max_params=
108: method.max_numbered_params_count?method.max_numbered_params_count:
109: method.params_names?method.params_names->size():
110: 0;
111: if(store_param_index==max_params)
1.23 paf 112: throw Exception("parser.runtime",
1.26 ! paf 113: &name(),
1.7 paf 114: "method of %s (%s) accepts maximum %d parameter(s)",
1.25 paf 115: junction.self.get_class()->name_cstr(),
1.1 paf 116: junction.self.type(),
117: max_params);
118:
119: if(method.max_numbered_params_count) { // are this method params numbered?
1.25 paf 120: fnumbered_params+=value;
1.1 paf 121: } else { // named param
1.25 paf 122: // speedup: not checking for clash with "result" fname
123: const String& fname=*method.params_names->get_string(store_param_index);
124: set_my_variable(fname, value);
1.1 paf 125: }
126: store_param_index++;
127: }
128: void fill_unspecified_params() {
129: const Method &method=*junction.method;
130: if(method.params_names) // there are any named parameters might need filling?
131: for(; store_param_index<method.params_names->size(); store_param_index++) {
1.25 paf 132: const String& fname=*method.params_names->get_string(store_param_index);
133: my.put(fname, NEW VVoid(pool()));
1.1 paf 134: }
135: }
136:
1.25 paf 137: MethodParams *numbered_params() { return &fnumbered_params; }
1.18 paf 138:
139: private:
140:
1.25 paf 141: bool has_my() {
142: return junction.method->max_numbered_params_count==0;
143: }
144:
145: void set_my_variable(const String& fname, Value *value) {
146: my.put(fname, value); // remember param
1.20 paf 147: }
148:
149: Value *get_result_variable() {
1.25 paf 150: Value *result=has_my()?static_cast<Value*>(my.get(*result_var_name)):0;
1.20 paf 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:
1.25 paf 159: const String& fname;
160:
1.1 paf 161: int store_param_index;
1.25 paf 162: Hash my;/*OR*/MethodParams fnumbered_params;
1.1 paf 163: Value *fself;
1.15 parser 164:
165: private:
166: Value *fresult_initial_void;
1.1 paf 167:
168: };
169:
170: #endif
E-mail: