Annotation of parser3/src/main/core.C, revision 1.3
1.1 paf 1: void process(Pool& pool,
2: Value& self,
3: RContext& rcontext, WContext& wcontext,
4: StringIterator& code, char char_to_stop_before) {
5:
6: // $ on code?
7: process_dollar(pool, rcontext, wcontext, code, char_to_stop_before);
8:
9: // ^ on code?
10: process_bird(pool, rcontext, wcontext, code, char_to_stop_before);
11: }
12:
13: void process_dollar(Pool& pool,
1.3 ! paf 14: Value& self,
1.1 paf 15: RContext& rcontext, WContext& wcontext,
16: StringIterator& iter, char char_to_stop_before) {
17:
18: // $name.field.subfield -- read
19: // $name.field.subfield(constructor code) -- construct
20: // $name.field.subfield[usage code & if none existed autoconstructed as VHash] -- use OR auto-VHash construct
21:
22: Array/*<String&>*/ names(pool); // what.they.refer.to left-to-right list
23: char names_ended_before; // the char after long name
24: get_names(
25: iter, " ([",
26: &names, &names_ended_before); // must return count()>0
27:
28: bool read_mode=name_ended_before==' ';
29: Value *context=read_mode?rcontext:wcontext;
30:
31: if(read_mode) {
1.3 ! paf 32: // 'context' dive into dotted path
1.1 paf 33: for(int i=0; i<names.count(); i++) {
34: context=context->get_element(static_cast<Value *>(names.get[i]));
35: if(!context) // no such object field, nothing bad, just ignore that
36: return;
37: }
38: wcontext.write(context);
39: } else { // write mode
40: iter++; // skip '(' '['
41:
42: bool construct_mode=names_ended_before=='(';
43:
44: int steps=names.count();
45: if(construct_mode)
46: steps--;
1.3 ! paf 47: // 'context' dive into dotted path, if constructing then "excluding last .name"
1.1 paf 48: for(int i=0; i<steps; i++) {
49: String& name=static_cast<String&>(names.get[i]);
50: Value *next_current=context->get_element(name);
51: if(next_current)
52: next_current=context->put_element(name, new(pool) VHash(pool));
53: context=new_current;
54: }
55:
56: if(construct_mode) {
1.3 ! paf 57: // .name(construct-code), processing on rcontext in empty temp wcontext
1.1 paf 58: // pure side effect, no wcontext.write here
1.3 ! paf 59: // last .name
1.1 paf 60: String& name=static_cast<String&>(names.get[steps]);
61: WContext local_wcontext(pool /* empty */);
62: process(pool, rcontext, local_wcontext, iter, ')');
63: context->put_element(name, local_wcontext.value());
64: } else { // =='['
1.3 ! paf 65: // .name[with-code], processing on 'context'
1.1 paf 66: WContext local_context(pool, context);
67: process(pool, local_context, local_context, iter, ']');
68: wcontext.write(local_context);
69: }
70:
71: iter++; // skip ')' ']'
72: }
73: }
74:
75: void process_bird(Pool& pool,
76: Value& self,
77: RContext& rcontext, WContext& wcontext,
78: StringIterator& iter, char char_to_stop_before) {
79:
80: // ^name.field.subfield.method[..] -- plain call
81: // ^name.field.subfield.method_ref[..] -- method ref call, when .get_method()!=0
82:
83: Array/*<String&>*/ names(pool); // what.they.refer.to left-to-right list
84: char names_ended_before; // the char after long name
85: get_names(
86: iter, "[",
87: &names, &names_ended_before); // must return count()>0
88:
89: Value *context=rcontext;
90: iter++; // skip '['
91:
1.3 ! paf 92: // 'context' dive into dotted path, excluding last .name
1.1 paf 93: Value *local_self=context;
94: int steps=names.count()-1;
95: for(int i=0; i<steps; i++) {
96: String& name=static_cast<String&>(names.get[i]);
97: context=(local_self=context)->get_element(name);
98: if(!context) // no such object field, sad story: can't call method of void
99: pool.exception().raise(name, "call: to void.method");
100: }
101:
1.3 ! paf 102: // last .name
1.1 paf 103: String& name=static_cast<String&>(names.get[steps]);
104: // first we're trying to locate method with that 'name'
105: Method *method=context.get_method(name);
106: if(!method) { // no such method: try to locate method ref field
107: Value *value=context.get_element(name);
108: if(!value) // failed: no element of that 'name'
109: pool.exception().raise(name, "call: no method field found");
110: method=value->get_method();
111: if(!method) // failed: that field wasn't method_ref
112: pool.exception().raise(name, "call: this field is not a method reference");
113: local_self=value->get_self();
114: }
115:
116:
117: Array/*<String&>*/ param_values(pool);
118: get_params(
119: iter, "]",
120: ¶m_values);
121: iter++; // skip ']'
122:
1.2 paf 123: Method_self_n_params local_rcontext(pool,
1.1 paf 124: local_self,
125: method->param_names, param_values);
126: WContext local_wcontext(pool /* empty */);
127: process(pool, local_rcontext, local_wcontext, iter, ']');
128: wcontext.write(local_wcontext);
129: }
E-mail: