Annotation of parser3/src/types/pa_vmethod_frame.h, revision 1.37
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: */
7:
8: #ifndef PA_VMETHOD_FRAME_H
9: #define PA_VMETHOD_FRAME_H
1.28 paf 10:
1.37 ! paf 11: static const char* IDENT_VMETHOD_FRAME_H="$Date: 2002/09/10 12:02:24 $";
1.1 paf 12:
13: #include "pa_wcontext.h"
1.12 parser 14: #include "pa_vvoid.h"
1.1 paf 15: #include "pa_vjunction.h"
1.35 paf 16: #include "pa_request.h"
1.1 paf 17:
1.4 paf 18: /** Method frame write context
19: accepts values written by method code
20: also handles method parameters and local variables
1.3 paf 21: */
1.1 paf 22: class VMethodFrame : public WContext {
23: public: // Value
24:
25: const char *type() const { return "method_frame"; }
1.20 paf 26:
27: /// VMethodFrame: $result | parent get_string(=accumulated fstring)
28: const String *get_string() {
29: // check the $result value
30: Value *result=get_result_variable();
31: // if we have one, return it's string value, else return as usual: accumulated fstring or fvalue
32: return result ? result->get_string() : WContext::get_string();
33: }
34:
1.4 paf 35: /// VMethodFrame: my or self_transparent
1.34 paf 36: Value *get_element(const String& aname, Value *aself, bool looking_up) {
1.25 paf 37: if(junction.method->max_numbered_params_count==0) {
1.32 paf 38: if(Value *result=static_cast<Value *>(my.get(aname)))
1.1 paf 39: return result;
40: }
1.37 ! paf 41: return self(&aname).get_element(aname, aself, looking_up);
1.1 paf 42: }
1.4 paf 43: /// VMethodFrame: my or self_transparent
1.32 paf 44: /*override*/ bool put_element(const String& aname, Value *avalue, bool replace) {
45: if(junction.method->max_numbered_params_count==0 && my.put_replace(aname, avalue))
46: return true;
47:
1.37 ! paf 48: return self(&aname).put_element(aname, avalue, replace);
1.1 paf 49: }
50:
1.4 paf 51: /// VMethodFrame: self_transparent
1.37 ! paf 52: VStateless_class* get_class() { return fself?fself->get_class():0; }
1.1 paf 53:
1.30 paf 54: public: // WContext
1.1 paf 55:
1.35 paf 56: /* override */ StringOrValue result() {
1.1 paf 57: // check the $result value
1.24 paf 58: Value *result_value=get_result_variable();
1.1 paf 59: // if we have one, return it, else return as usual: accumulated fstring or fvalue
1.24 paf 60: return result_value ? StringOrValue(0, result_value) : WContext::result();
1.1 paf 61: }
62:
63: public: // usage
64:
65: VMethodFrame(Pool& apool,
1.25 paf 66: const String& aname,
1.13 parser 67: const Junction& ajunction/*info: always method-junction*/) :
1.36 paf 68: WContext(apool, 0 /* empty */, 0 /* no parent, junctions can be reattached only up to VMethodFrame */ ),
1.1 paf 69:
1.25 paf 70: fname(aname),
1.1 paf 71: junction(ajunction),
72: store_param_index(0),
1.25 paf 73:
74: my(apool),
75: fnumbered_params(apool, aname),
76:
1.15 parser 77: fself(0),
1.36 paf 78: fresult_initial_void(0) {
1.1 paf 79:
1.25 paf 80: if(has_my()) { // this method uses named params?
81: const Method &method=*junction.method;
1.1 paf 82: if(method.locals_names) { // are there any local var names?
83: // remember them
1.25 paf 84: // those are flags that fname is local == to be looked up in 'my'
1.1 paf 85: for(int i=0; i<method.locals_names->size(); i++) {
1.25 paf 86: // speedup: not checking for clash with "result" fname
1.12 parser 87: Value *value=NEW VVoid(pool());
1.25 paf 88: const String& fname=*method.locals_names->get_string(i);
89: set_my_variable(fname, value);
1.1 paf 90: }
91: }
92: { // always there is one local: $result
1.15 parser 93: fresult_initial_void=NEW VVoid(pool());
1.18 paf 94: set_my_variable(*result_var_name, fresult_initial_void);
1.1 paf 95: }
96: }
97: }
98:
1.25 paf 99: const String& name() { return fname; }
100:
1.37 ! paf 101: void set_self(Value *aself) { fself=aself; }
! 102: Value& self(const String *source) {
! 103: if(!fself)
! 104: throw Exception("parser.runtime",
! 105: source,
! 106: "you can not access nonlocal variables here");
! 107: return *fself;
! 108: }
1.1 paf 109:
1.27 paf 110: bool can_store_param() {
111: const Method& method=*junction.method;
112: return method.params_names && store_param_index<method.params_names->size();
113: }
1.26 paf 114: void store_param(Value *value) {
1.1 paf 115: const Method& method=*junction.method;
116: int max_params=
117: method.max_numbered_params_count?method.max_numbered_params_count:
118: method.params_names?method.params_names->size():
119: 0;
120: if(store_param_index==max_params)
1.23 paf 121: throw Exception("parser.runtime",
1.26 paf 122: &name(),
1.7 paf 123: "method of %s (%s) accepts maximum %d parameter(s)",
1.37 ! paf 124: junction.self?junction.self->get_class()->name_cstr():"<unknown class>",
! 125: junction.self?junction.self->type():"<unknown type>",
1.1 paf 126: max_params);
127:
128: if(method.max_numbered_params_count) { // are this method params numbered?
1.25 paf 129: fnumbered_params+=value;
1.1 paf 130: } else { // named param
1.25 paf 131: // speedup: not checking for clash with "result" fname
132: const String& fname=*method.params_names->get_string(store_param_index);
133: set_my_variable(fname, value);
1.1 paf 134: }
135: store_param_index++;
136: }
137: void fill_unspecified_params() {
138: const Method &method=*junction.method;
139: if(method.params_names) // there are any named parameters might need filling?
140: for(; store_param_index<method.params_names->size(); store_param_index++) {
1.25 paf 141: const String& fname=*method.params_names->get_string(store_param_index);
142: my.put(fname, NEW VVoid(pool()));
1.1 paf 143: }
144: }
145:
1.25 paf 146: MethodParams *numbered_params() { return &fnumbered_params; }
1.18 paf 147:
148: private:
149:
1.25 paf 150: bool has_my() {
151: return junction.method->max_numbered_params_count==0;
152: }
153:
154: void set_my_variable(const String& fname, Value *value) {
155: my.put(fname, value); // remember param
1.20 paf 156: }
157:
158: Value *get_result_variable() {
1.25 paf 159: Value *result=has_my()?static_cast<Value*>(my.get(*result_var_name)):0;
1.20 paf 160: return result && result!=fresult_initial_void ? result : 0;
1.18 paf 161: }
1.1 paf 162:
163: public:
164:
165: const Junction& junction;
166:
167: private:
1.35 paf 168:
1.25 paf 169: const String& fname;
170:
1.1 paf 171: int store_param_index;
1.25 paf 172: Hash my;/*OR*/MethodParams fnumbered_params;
1.1 paf 173: Value *fself;
1.15 parser 174:
175: private:
1.35 paf 176:
1.15 parser 177: Value *fresult_initial_void;
1.1 paf 178:
179: };
180:
181: #endif
E-mail: