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

1.3       paf         1: /** @file
1.5       paf         2:        Parser: @b method_frame write context
1.3       paf         3: 
1.1       paf         4:        Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
                      5:        Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
                      6: 
1.18    ! paf         7:        $Id: pa_vmethod_frame.h,v 1.17 2001/10/19 12:43:30 parser Exp $
1.1       paf         8: */
                      9: 
                     10: #ifndef PA_VMETHOD_FRAME_H
                     11: #define PA_VMETHOD_FRAME_H
                     12: 
                     13: #include "pa_wcontext.h"
1.12      parser     14: #include "pa_vvoid.h"
1.1       paf        15: #include "pa_vjunction.h"
                     16: 
1.4       paf        17: /**    Method frame write context
                     18:        accepts values written by method code
                     19:        also handles method parameters and local variables
1.3       paf        20: */
1.1       paf        21: class VMethodFrame : public WContext {
                     22: public: // Value
                     23: 
                     24:        const char *type() const { return "method_frame"; }
1.4       paf        25:        /// VMethodFrame: my or self_transparent
1.1       paf        26:        Value *get_element(const String& name) { 
                     27:                if(my) {
                     28:                        Value *result=static_cast<Value *>(my->get(name));
                     29:                        if(result)
                     30:                                return result;
                     31:                }
                     32:                return fself->get_element(name); 
                     33:        }
1.4       paf        34:        /// VMethodFrame: my or self_transparent
1.1       paf        35:        void put_element(const String& name, Value *value){ 
                     36:                if(!(my && my->put_replace(name, value)))
                     37:                        fself->put_element(name, value);
                     38:        }
                     39: 
1.4       paf        40:        /// VMethodFrame: self_transparent
1.1       paf        41:        VStateless_class* get_class() { return fself->get_class(); }
                     42: 
1.4       paf        43:        /// VMethodFrame: self_transparent
1.1       paf        44:        VAliased *get_aliased() { return fself->get_aliased(); }
                     45: 
                     46: public: // wcontext
                     47: 
                     48:        Value *result() {
                     49:                // check the $result value
                     50:                Value *result=my?static_cast<Value*>(my->get(*result_var_name)):0;
                     51:                // if we have one, return it, else return as usual: accumulated fstring or fvalue
1.15      parser     52:                return result && (result!=fresult_initial_void) ?result:WContext::result();
1.1       paf        53:        }
                     54: 
                     55: public: // usage
                     56: 
                     57:        VMethodFrame(Pool& apool, 
1.8       parser     58:                const String& name,
1.13      parser     59:                const Junction& ajunction/*info: always method-junction*/) : 
1.14      parser     60:                WContext(apool, 0 /* empty */),
1.1       paf        61: 
                     62:                junction(ajunction),
                     63:                store_param_index(0),
1.15      parser     64:                fself(0),
                     65:                fresult_initial_void(0) {
1.9       parser     66:                set_name(name);
1.1       paf        67: 
                     68:                const Method &method=*junction.method;
                     69: 
1.3       paf        70:                if(method.max_numbered_params_count) { // are this method params numbered?
                     71:                        my=0; // no named parameters
1.8       parser     72:                        fnumbered_params=NEW MethodParams(pool(), name); // create storage
1.3       paf        73:                } else { // named params
1.1       paf        74:                        my=NEW Hash(pool()); // create storage
1.3       paf        75:                        fnumbered_params=0; // no numbered parameters
1.1       paf        76:                        
                     77:                        if(method.locals_names) { // are there any local var names?
                     78:                                // remember them
                     79:                                // those are flags that name is local == to be looked up in 'my'
                     80:                                for(int i=0; i<method.locals_names->size(); i++) {
                     81:                                        // speedup: not checking for clash with "result" name
1.12      parser     82:                                        Value *value=NEW VVoid(pool());
1.1       paf        83:                                        const String& name=*method.locals_names->get_string(i);
1.18    ! paf        84:                                        set_my_variable(name, value);
1.1       paf        85:                                }
                     86:                        }
                     87:                        { // always there is one local: $result
1.15      parser     88:                                fresult_initial_void=NEW VVoid(pool());
1.18    ! paf        89:                                set_my_variable(*result_var_name, fresult_initial_void);
1.1       paf        90:                        }
                     91:                }
                     92:        }
                     93: 
                     94:        void set_self(Value& aself) { fself=&aself; }
                     95:        Value *self() { return fself; }
                     96: 
                     97:        void store_param(const String& actual_method_name, Value *value) {
                     98:                const Method& method=*junction.method;
                     99:                int max_params=
                    100:                        method.max_numbered_params_count?method.max_numbered_params_count:
                    101:                        method.params_names?method.params_names->size():
                    102:                        0;
                    103:                if(store_param_index==max_params)
1.17      parser    104:                        throw Exception(0,0,
1.1       paf       105:                                &actual_method_name,
1.7       paf       106:                                "method of %s (%s) accepts maximum %d parameter(s)", 
1.1       paf       107:                                        junction.self.name().cstr(),
                    108:                                        junction.self.type(),
                    109:                                        max_params);
                    110:                
                    111:                if(method.max_numbered_params_count) { // are this method params numbered?
                    112:                        *fnumbered_params+=value;
                    113:                } else { // named param
                    114:                        // speedup: not checking for clash with "result" name
                    115:                        const String& name=*method.params_names->get_string(store_param_index);
1.18    ! paf       116:                        set_my_variable(name, value);
1.1       paf       117:                }
                    118:                store_param_index++;
                    119:        }
                    120:        void fill_unspecified_params() {
                    121:                const Method &method=*junction.method;
                    122:                if(method.params_names) // there are any named parameters might need filling?
                    123:                        for(; store_param_index<method.params_names->size(); store_param_index++) {
1.12      parser    124:                                Value *value=NEW VVoid(pool());
1.1       paf       125:                                const String& name=*method.params_names->get_string(store_param_index);
                    126:                                my->put(name, value);
                    127:                                value->set_name(name);
                    128:                        }
                    129:        }
                    130: 
1.3       paf       131:        MethodParams *numbered_params() { return fnumbered_params; }
1.18    ! paf       132: 
        !           133: private:
        !           134: 
        !           135:        void set_my_variable(const String& name, Value *value) {
        !           136:                my->put(name, value); // remember param
        !           137:                value->set_name(name); // set param's 'name'
        !           138:        }
1.1       paf       139: 
                    140: public:
                    141:        
                    142:        const Junction& junction;
                    143: 
                    144: private:
                    145:        int store_param_index;
1.3       paf       146:        Hash *my;/*OR*/MethodParams *fnumbered_params;
1.1       paf       147:        Value *fself;
1.15      parser    148: 
                    149: private:
                    150:        Value *fresult_initial_void;
1.1       paf       151: 
                    152: };
                    153: 
                    154: #endif

E-mail: