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

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);
        !           128:                        if(!oc) // bad: no such class
        !           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
        !           133:                                        ;
        !           134:                                else // static call
        !           135:                                        context=right_class;
        !           136:                        } else { // constructor: $some(^class:method[..]) call
        !           137:                                context=new(pool) VClass(pool, right_class);
        !           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.8     ! paf       163:                awcontext,
1.1       paf       164:                &param_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.6       paf       171:        WContext local_wcontext(pool, local_self);
                    172:        process(
                    173:                context, local_rcontext, 
                    174:                local_rcontext, local_wcontext, 
                    175:                iter, ']');
1.7       paf       176:        awcontext.write(local_wcontext);
1.1       paf       177: }

E-mail: