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

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

E-mail: