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