Annotation of parser3/src/main/core.C, revision 1.9
1.7 paf 1: void process(method_self_n_params_n_locals& root, Value& self,
2: arcontext& arcontext, WContext& awcontext,
1.5 paf 3: String_iterator& code, char char_to_stop_before) {
1.1 paf 4:
5: // $ on code?
1.7 paf 6: process_dollar(root, self, arcontext, awcontext, code, char_to_stop_before);
1.1 paf 7:
8: // ^ on code?
1.7 paf 9: process_bird(root, self, arcontext, awcontext, code, char_to_stop_before);
1.4 paf 10:
11: // TODO
12: // 2. вызовы статических методов
1.1 paf 13: }
14:
1.7 paf 15: void process_dollar(method_self_n_params_n_locals& root, Value& self,
16: arcontext& arcontext, WContext& awcontext,
1.5 paf 17: String_iterator& iter, char char_to_stop_before) {
1.1 paf 18:
19: // $name.field.subfield -- read
20: // $name.field.subfield(constructor code) -- construct
21: // $name.field.subfield[usage code & if none existed autoconstructed as VHash] -- use OR auto-VHash construct
22:
23: Array/*<String&>*/ names(pool); // what.they.refer.to left-to-right list
24: char names_ended_before; // the char after long name
1.6 paf 25: Prefix prefix;
1.1 paf 26: get_names(
27: iter, " ([",
1.6 paf 28: &prefix, &names, &names_ended_before); // can return count()=0 when $self alone
1.1 paf 29:
30: bool read_mode=name_ended_before==' ';
1.6 paf 31: Value *context=
32: prefix?
1.8 paf 33: prefix==ROOT_PREFIX?root:self:
1.7 paf 34: read_mode?arcontext:awcontext;
1.1 paf 35:
36: if(read_mode) {
1.3 paf 37: // 'context' dive into dotted path
1.1 paf 38: for(int i=0; i<names.count(); i++) {
39: context=context->get_element(static_cast<Value *>(names.get[i]));
40: if(!context) // no such object field, nothing bad, just ignore that
41: return;
42: }
1.7 paf 43: awcontext.write(context);
1.1 paf 44: } else { // write mode
45: iter++; // skip '(' '['
46:
47: bool construct_mode=names_ended_before=='(';
48:
1.4 paf 49: // 'context' dive into dotted path,
1.1 paf 50: int steps=names.count();
1.4 paf 51: // if constructing then "excluding last .name"
1.1 paf 52: if(construct_mode)
1.6 paf 53: if(!steps--) // bad: "$self("; now we can safely do ".get[steps]" below
54: pool.exception().raise("self re-construction prohibited");
1.1 paf 55: for(int i=0; i<steps; i++) {
56: String& name=static_cast<String&>(names.get[i]);
57: Value *next_current=context->get_element(name);
58: if(next_current)
59: next_current=context->put_element(name, new(pool) VHash(pool));
60: context=new_current;
61: }
62:
63: if(construct_mode) {
1.7 paf 64: // .name(construct-code), processing on arcontext in empty temp awcontext
65: // pure side effect, no awcontext.write here
1.3 paf 66: // last .name
1.1 paf 67: String& name=static_cast<String&>(names.get[steps]);
68: WContext local_wcontext(pool /* empty */);
1.7 paf 69: process(root, self, arcontext, local_wcontext, iter, ')');
1.1 paf 70: context->put_element(name, local_wcontext.value());
71: } else { // =='['
1.3 paf 72: // .name[with-code], processing on 'context'
1.1 paf 73: WContext local_context(pool, context);
1.6 paf 74: process(root, self, local_context, local_context, iter, ']');
1.7 paf 75: awcontext.write(local_context);
1.1 paf 76: }
77:
78: iter++; // skip ')' ']'
79: }
80: }
81:
1.7 paf 82: void process_bird(method_self_n_params_n_locals& root, Value& self,
83: arcontext& arcontext, WContext& awcontext,
1.5 paf 84: String_iterator& iter, char char_to_stop_before) {
1.1 paf 85:
86: // ^name.field.subfield.method[..] -- plain call
87: // ^name.field.subfield.method_ref[..] -- method ref call, when .get_method()!=0
1.8 paf 88: // ^class:method[..] -- no dotted path allowed before/after
89: // 1: wcontext.object_class == 0? -- constructor
90: // 2: wcontext.object_class.has_parent('class')? -- dynamic call
91: // 3: not -------------------------------------? -- static call
1.1 paf 92:
93: Array/*<String&>*/ names(pool); // what.they.refer.to left-to-right list
94: char names_ended_before; // the char after long name
1.6 paf 95: Prefix prefix;
1.1 paf 96: get_names(
97: iter, "[",
1.6 paf 98: &prefix, &names, &names_ended_before); // can return count()=0 when ^self alone
1.1 paf 99:
1.6 paf 100: Value *context=
101: prefix?
1.8 paf 102: prefix==ROOT_PREFIX?root:self:
1.7 paf 103: arcontext;
1.1 paf 104: iter++; // skip '['
105:
1.3 paf 106: // 'context' dive into dotted path, excluding last .name
1.1 paf 107: int steps=names.count()-1;
1.6 paf 108: if(steps<0) // bad: "^self["; now we can safely do ".get[steps]" below
109: pool.exception().raise("call: calling method named 'self'");
1.1 paf 110: for(int i=0; i<steps; i++) {
111: String& name=static_cast<String&>(names.get[i]);
1.6 paf 112: context=context->get_element(name);
1.1 paf 113: if(!context) // no such object field, sad story: can't call method of void
114: pool.exception().raise(name, "call: to void.method");
115: }
116:
1.3 paf 117: // last .name
1.1 paf 118: String& name=static_cast<String&>(names.get[steps]);
1.8 paf 119: if(steps==0) { // the sole name on path, maybe ^class:method[ call
120: String_iterator ni(name);
121: if(ni.skip_to(':')) { // it is
122: ni++; // skip ':'
123: String method_name(pool); method_name.append(ni, 0);
124: name=method_name; // trim "class:" prefix from the name
125:
126: String cn(pool); cn.append(0, ni);
127: Class *right_class=classes.get(cn);
1.9 ! paf 128: if(!right_class) // bad: no such class
1.8 paf 129: pool.exception().raise(cn, "call: undefined class");
130: Class *left_class=awcontext.get_class();
131: if(left_class) {
132: if(left_class.has_parent(right_class)) // dynamic call
1.9 ! paf 133: context=awcontext.value(); // it's 'self'
1.8 paf 134: else // static call
1.9 ! paf 135: context=right_class; // 'self' := class, not instance
1.8 paf 136: } else { // constructor: $some(^class:method[..]) call
1.9 ! paf 137: context=new(pool) VClass(pool, right_class); // 'self' := new VClass of 'class:'
1.8 paf 138: awcontext.write(context);
139: }
140: }
141: }
1.1 paf 142: // first we're trying to locate method with that 'name'
143: Method *method=context.get_method(name);
144: if(!method) { // no such method: try to locate method ref field
145: Value *value=context.get_element(name);
1.6 paf 146: if(value) { // good: we have some element of that 'name'
147: Method_ref *method_ref=value->get_method_ref();
148: if(!method_ref) // bad: that field wasn't method_ref
149: pool.exception().raise(name, "call: this field is not a method reference");
150: method=method_ref->method;
151: context=method_ref->self;
152: } else { // no element of that 'name', that must be operator then
153: method=operators.get(name);
154: if(!method) // bad: that 'name' is neither method nor field nor operator
155: pool.exception().raise(name, "call: neither method nor field nor operator");
156: }
1.1 paf 157: }
158:
159:
160: Array/*<String&>*/ param_values(pool);
161: get_params(
1.6 paf 162: iter,
1.9 ! paf 163: arcontext,
1.1 paf 164: ¶m_values);
165: iter++; // skip ']'
166:
1.7 paf 167: method_self_n_params_n_locals local_rcontext(pool,
1.6 paf 168: context,
1.7 paf 169: method->param_names, param_values,
170: method->local_names);
1.9 ! paf 171: WContext local_wcontext(pool, context);
1.6 paf 172: process(
1.9 ! paf 173: local_rcontext/* $:vars */, context /* $self.vars */,
1.6 paf 174: local_rcontext, local_wcontext,
175: iter, ']');
1.7 paf 176: awcontext.write(local_wcontext);
1.1 paf 177: }
E-mail: