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:                &param_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: