Annotation of parser3/src/types/pa_vmethod_frame.h, revision 1.43.4.1

1.3       paf         1: /** @file
1.5       paf         2:        Parser: @b method_frame write context
1.3       paf         3: 
1.21      paf         4:        Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
1.22      paf         5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1       paf         6: */
                      7: 
                      8: #ifndef PA_VMETHOD_FRAME_H
                      9: #define PA_VMETHOD_FRAME_H
1.28      paf        10: 
1.43.4.1! paf        11: static const char* IDENT_VMETHOD_FRAME_H="$Date: 2002/10/15 14:28:57 $";
1.1       paf        12: 
                     13: #include "pa_wcontext.h"
1.12      parser     14: #include "pa_vvoid.h"
1.1       paf        15: #include "pa_vjunction.h"
1.35      paf        16: #include "pa_request.h"
1.1       paf        17: 
1.40      paf        18: // defines
                     19: 
1.42      paf        20: #define CALLER_ELEMENT_NAME "caller"
                     21: #define SELF_ELEMENT_NAME "self"
1.40      paf        22: 
1.4       paf        23: /**    Method frame write context
                     24:        accepts values written by method code
                     25:        also handles method parameters and local variables
1.3       paf        26: */
1.1       paf        27: class VMethodFrame : public WContext {
                     28: public: // Value
                     29: 
                     30:        const char *type() const { return "method_frame"; }
1.20      paf        31: 
                     32:        /// VMethodFrame: $result | parent get_string(=accumulated fstring)
                     33:        const String *get_string() { 
                     34:                // check the $result value
                     35:                Value *result=get_result_variable();
                     36:                // if we have one, return it's string value, else return as usual: accumulated fstring or fvalue
                     37:                return result ? result->get_string() : WContext::get_string();
                     38:        }
                     39:        
1.40      paf        40:        /// VMethodFrame: my or self_transparent or $caller
1.43.4.1! paf        41:        Value *get_element(const String& aname, Value& aself, bool looking_up) { 
1.25      paf        42:                if(junction.method->max_numbered_params_count==0) {
1.32      paf        43:                        if(Value *result=static_cast<Value *>(my.get(aname)))
1.1       paf        44:                                return result;
                     45:                }
1.41      paf        46:                if(Value *result=self().get_element(aname, aself, looking_up))
1.40      paf        47:                        return result;
                     48: 
1.42      paf        49:                if(aname==CALLER_ELEMENT_NAME)
1.40      paf        50:                        return caller();
1.42      paf        51: 
                     52:                if(aname==SELF_ELEMENT_NAME)
                     53:                        return &self();
1.40      paf        54: 
                     55:                return 0;
1.1       paf        56:        }
1.4       paf        57:        /// VMethodFrame: my or self_transparent
1.32      paf        58:        /*override*/ bool put_element(const String& aname, Value *avalue, bool replace) { 
                     59:                if(junction.method->max_numbered_params_count==0 && my.put_replace(aname, avalue))
                     60:                        return true;
                     61: 
1.41      paf        62:                return self().put_element(aname, avalue, replace);
1.1       paf        63:        }
                     64: 
1.4       paf        65:        /// VMethodFrame: self_transparent
1.43.4.1! paf        66:        /*override*/ VStateless_class* get_class() { return self().get_class(); }
        !            67: 
        !            68:        /// VMethodFrame: self_transparent
        !            69:        /*override*/ Value& get_last_derived() { return self().get_last_derived(); }
        !            70:        
        !            71:        /// VMethodFrame: self_transparent
        !            72:        /*override*/ Value *base() { return self().base(); }
1.1       paf        73: 
1.30      paf        74: public: // WContext
1.1       paf        75: 
1.35      paf        76:        /* override */ StringOrValue result() {
1.1       paf        77:                // check the $result value
1.24      paf        78:                Value *result_value=get_result_variable();
1.1       paf        79:                // if we have one, return it, else return as usual: accumulated fstring or fvalue
1.24      paf        80:                return result_value ? StringOrValue(0, result_value) : WContext::result();
1.1       paf        81:        }
                     82: 
                     83: public: // usage
                     84: 
                     85:        VMethodFrame(Pool& apool, 
1.25      paf        86:                const String& aname,
1.40      paf        87:                const Junction& ajunction/*info: always method-junction*/,
                     88:                VMethodFrame *acaller) : 
1.36      paf        89:                WContext(apool, 0 /* empty */, 0 /* no parent, junctions can be reattached only up to VMethodFrame */ ),
1.1       paf        90: 
1.25      paf        91:                fname(aname),
1.1       paf        92:                junction(ajunction),
1.40      paf        93:                fcaller(acaller),
1.1       paf        94:                store_param_index(0),
1.25      paf        95: 
                     96:                my(apool),
                     97:                fnumbered_params(apool, aname),
                     98: 
1.15      parser     99:                fself(0),
1.36      paf       100:                fresult_initial_void(0) {
1.1       paf       101: 
1.25      paf       102:                if(has_my()) { // this method uses named params?
                    103:                        const Method &method=*junction.method;
1.1       paf       104:                        if(method.locals_names) { // are there any local var names?
                    105:                                // remember them
1.25      paf       106:                                // those are flags that fname is local == to be looked up in 'my'
1.1       paf       107:                                for(int i=0; i<method.locals_names->size(); i++) {
1.25      paf       108:                                        // speedup: not checking for clash with "result" fname
1.12      parser    109:                                        Value *value=NEW VVoid(pool());
1.25      paf       110:                                        const String& fname=*method.locals_names->get_string(i);
                    111:                                        set_my_variable(fname, value);
1.1       paf       112:                                }
                    113:                        }
                    114:                        { // always there is one local: $result
1.15      parser    115:                                fresult_initial_void=NEW VVoid(pool());
1.18      paf       116:                                set_my_variable(*result_var_name, fresult_initial_void);
1.1       paf       117:                        }
                    118:                }
                    119:        }
                    120: 
1.25      paf       121:        const String& name() { return fname; }
1.40      paf       122:        VMethodFrame *caller() { return fcaller; }
1.25      paf       123: 
1.38      paf       124:        void set_self(Value& aself) { fself=&aself; }
1.41      paf       125:        /// we sure that someone already set our self with VMethodFrame::set_self(Value&)
                    126:        Value& self() { return *fself; }
1.1       paf       127: 
1.27      paf       128:        bool can_store_param() {
                    129:                const Method& method=*junction.method;
                    130:                return method.params_names && store_param_index<method.params_names->size();
                    131:        }
1.26      paf       132:        void store_param(Value *value) {
1.1       paf       133:                const Method& method=*junction.method;
                    134:                int max_params=
                    135:                        method.max_numbered_params_count?method.max_numbered_params_count:
                    136:                        method.params_names?method.params_names->size():
                    137:                        0;
                    138:                if(store_param_index==max_params)
1.23      paf       139:                        throw Exception("parser.runtime",
1.26      paf       140:                                &name(),
1.7       paf       141:                                "method of %s (%s) accepts maximum %d parameter(s)", 
1.38      paf       142:                                        junction.self.get_class()->name_cstr(),
                    143:                                        junction.self.type(),
1.1       paf       144:                                        max_params);
                    145:                
                    146:                if(method.max_numbered_params_count) { // are this method params numbered?
1.25      paf       147:                        fnumbered_params+=value;
1.1       paf       148:                } else { // named param
1.25      paf       149:                        // speedup: not checking for clash with "result" fname
                    150:                        const String& fname=*method.params_names->get_string(store_param_index);
                    151:                        set_my_variable(fname, value);
1.1       paf       152:                }
                    153:                store_param_index++;
                    154:        }
                    155:        void fill_unspecified_params() {
                    156:                const Method &method=*junction.method;
                    157:                if(method.params_names) // there are any named parameters might need filling?
                    158:                        for(; store_param_index<method.params_names->size(); store_param_index++) {
1.25      paf       159:                                const String& fname=*method.params_names->get_string(store_param_index);
                    160:                                my.put(fname, NEW VVoid(pool()));
1.1       paf       161:                        }
                    162:        }
                    163: 
1.25      paf       164:        MethodParams *numbered_params() { return &fnumbered_params; }
1.18      paf       165: 
                    166: private:
                    167: 
1.25      paf       168:        bool has_my() {
                    169:                return junction.method->max_numbered_params_count==0;
                    170:        }
                    171: 
                    172:        void set_my_variable(const String& fname, Value *value) {
                    173:                my.put(fname, value); // remember param
1.20      paf       174:        }
                    175: 
                    176:        Value *get_result_variable() {
1.25      paf       177:                Value *result=has_my()?static_cast<Value*>(my.get(*result_var_name)):0;
1.20      paf       178:                return result && result!=fresult_initial_void ? result : 0;
1.18      paf       179:        }
1.1       paf       180: 
                    181: public:
                    182:        
                    183:        const Junction& junction;
                    184: 
                    185: private:
1.35      paf       186: 
1.25      paf       187:        const String& fname;
1.40      paf       188:        VMethodFrame *fcaller;
1.25      paf       189: 
1.1       paf       190:        int store_param_index;
1.25      paf       191:        Hash my;/*OR*/MethodParams fnumbered_params;
1.1       paf       192:        Value *fself;
1.15      parser    193: 
                    194: private:
1.35      paf       195: 
1.15      parser    196:        Value *fresult_initial_void;
1.1       paf       197: 
1.41      paf       198: };
                    199: 
                    200: ///    Auto-object used for temporary changing VMethod_frame::fself.
                    201: class Temp_method_frame_self {
                    202:        VMethodFrame& fmethod_frame;
                    203:        Value& saved_self;
                    204: public:
                    205:        Temp_method_frame_self(VMethodFrame& amethod_frame, Value& aself) :
                    206:                fmethod_frame(amethod_frame),
                    207:                saved_self(amethod_frame.self()) {
                    208:                fmethod_frame.set_self(aself);
                    209:        }
                    210:        ~Temp_method_frame_self() {
                    211:                fmethod_frame.set_self(saved_self);
                    212:        }
1.1       paf       213: };
                    214: 
                    215: #endif

E-mail: