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