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

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

E-mail: