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