Annotation of parser3/src/main/core.C, revision 1.7

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?
                     33:                        prefix==ROOT?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
                     88:        
                     89:        Array/*<String&>*/ names(pool);  // what.they.refer.to left-to-right list
                     90:        char names_ended_before; // the char after long name
1.6       paf        91:        Prefix prefix;
1.1       paf        92:        get_names(
                     93:                iter, "[",
1.6       paf        94:                &prefix, &names, &names_ended_before); // can return count()=0 when ^self alone
1.1       paf        95: 
1.6       paf        96:        Value *context=
                     97:                prefix?
                     98:                        prefix==ROOT?root:self:
1.7     ! paf        99:                arcontext;
1.1       paf       100:        iter++; // skip '['
                    101: 
1.3       paf       102:        // 'context' dive into dotted path, excluding last .name
1.1       paf       103:        int steps=names.count()-1;
1.6       paf       104:        if(steps<0) // bad: "^self["; now we can safely do ".get[steps]" below
                    105:                pool.exception().raise("call: calling method named 'self'");
1.1       paf       106:        for(int i=0; i<steps; i++) {
                    107:                String& name=static_cast<String&>(names.get[i]);
1.6       paf       108:                context=context->get_element(name);
1.1       paf       109:                if(!context) // no such object field, sad story: can't call method of void
                    110:                        pool.exception().raise(name, "call: to void.method");
                    111:        }
                    112:        
1.3       paf       113:        // last .name
1.1       paf       114:        String& name=static_cast<String&>(names.get[steps]);
                    115:        // first we're trying to locate method with that 'name'
                    116:        Method *method=context.get_method(name);
                    117:        if(!method) { // no such method: try to locate method ref field
                    118:                Value *value=context.get_element(name);
1.6       paf       119:                if(value) { // good: we have some element of that 'name'
                    120:                        Method_ref *method_ref=value->get_method_ref();
                    121:                        if(!method_ref) // bad: that field wasn't method_ref
                    122:                                pool.exception().raise(name, "call: this field is not a method reference");
                    123:                        method=method_ref->method;
                    124:                        context=method_ref->self;
                    125:                } else { // no element of that 'name', that must be operator then
                    126:                        method=operators.get(name);
                    127:                        if(!method) // bad: that 'name' is neither method nor field nor operator
                    128:                                pool.exception().raise(name, "call: neither method nor field nor operator");
                    129:                }
1.1       paf       130:        }
                    131: 
                    132: 
                    133:        Array/*<String&>*/ param_values(pool);
                    134:        get_params(
1.6       paf       135:                iter,
1.1       paf       136:                &param_values);
                    137:        iter++; // skip ']'
                    138: 
1.7     ! paf       139:        method_self_n_params_n_locals local_rcontext(pool, 
1.6       paf       140:                context,
1.7     ! paf       141:                method->param_names, param_values,
        !           142:                method->local_names);
1.6       paf       143:        WContext local_wcontext(pool, local_self);
                    144:        process(
                    145:                context, local_rcontext, 
                    146:                local_rcontext, local_wcontext, 
                    147:                iter, ']');
1.7     ! paf       148:        awcontext.write(local_wcontext);
1.1       paf       149: }

E-mail: