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

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: 
1.26    ! paf         7:        $Id: pa_vmethod_frame.h,v 1.25 2002/04/18 10:51:02 paf 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.20      paf        25: 
                     26:        /// VMethodFrame: $result | parent get_string(=accumulated fstring)
                     27:        const String *get_string() { 
                     28:                // check the $result value
                     29:                Value *result=get_result_variable();
                     30:                // if we have one, return it's string value, else return as usual: accumulated fstring or fvalue
                     31:                return result ? result->get_string() : WContext::get_string();
                     32:        }
                     33:        
1.4       paf        34:        /// VMethodFrame: my or self_transparent
1.25      paf        35:        Value *get_element(const String& fname) { 
                     36:                if(junction.method->max_numbered_params_count==0) {
                     37:                        Value *result=static_cast<Value *>(my.get(fname));
1.1       paf        38:                        if(result)
                     39:                                return result;
                     40:                }
1.25      paf        41:                return fself->get_element(fname); 
1.1       paf        42:        }
1.4       paf        43:        /// VMethodFrame: my or self_transparent
1.25      paf        44:        void put_element(const String& fname, Value *value){ 
                     45:                if(!(junction.method->max_numbered_params_count==0 && my.put_replace(fname, value)))
                     46:                        fself->put_element(fname, value);
1.1       paf        47:        }
                     48: 
1.4       paf        49:        /// VMethodFrame: self_transparent
1.1       paf        50:        VStateless_class* get_class() { return fself->get_class(); }
                     51: 
1.4       paf        52:        /// VMethodFrame: self_transparent
1.1       paf        53:        VAliased *get_aliased() { return fself->get_aliased(); }
                     54: 
                     55: public: // wcontext
                     56: 
1.24      paf        57:        StringOrValue result() {
1.1       paf        58:                // check the $result value
1.24      paf        59:                Value *result_value=get_result_variable();
1.1       paf        60:                // if we have one, return it, else return as usual: accumulated fstring or fvalue
1.24      paf        61:                return result_value ? StringOrValue(0, result_value) : WContext::result();
1.1       paf        62:        }
                     63: 
                     64: public: // usage
                     65: 
                     66:        VMethodFrame(Pool& apool, 
1.25      paf        67:                const String& aname,
1.13      parser     68:                const Junction& ajunction/*info: always method-junction*/) : 
1.14      parser     69:                WContext(apool, 0 /* empty */),
1.1       paf        70: 
1.25      paf        71:                fname(aname),
1.1       paf        72:                junction(ajunction),
                     73:                store_param_index(0),
1.25      paf        74: 
                     75:                my(apool),
                     76:                fnumbered_params(apool, aname),
                     77: 
1.15      parser     78:                fself(0),
                     79:                fresult_initial_void(0) {
1.1       paf        80: 
1.25      paf        81:                if(has_my()) { // this method uses named params?
                     82:                        const Method &method=*junction.method;
1.1       paf        83:                        if(method.locals_names) { // are there any local var names?
                     84:                                // remember them
1.25      paf        85:                                // those are flags that fname is local == to be looked up in 'my'
1.1       paf        86:                                for(int i=0; i<method.locals_names->size(); i++) {
1.25      paf        87:                                        // speedup: not checking for clash with "result" fname
1.12      parser     88:                                        Value *value=NEW VVoid(pool());
1.25      paf        89:                                        const String& fname=*method.locals_names->get_string(i);
                     90:                                        set_my_variable(fname, value);
1.1       paf        91:                                }
                     92:                        }
                     93:                        { // always there is one local: $result
1.15      parser     94:                                fresult_initial_void=NEW VVoid(pool());
1.18      paf        95:                                set_my_variable(*result_var_name, fresult_initial_void);
1.1       paf        96:                        }
                     97:                }
                     98:        }
                     99: 
1.25      paf       100:        const String& name() { return fname; }
                    101: 
1.1       paf       102:        void set_self(Value& aself) { fself=&aself; }
                    103:        Value *self() { return fself; }
                    104: 
1.26    ! paf       105:        void store_param(Value *value) {
1.1       paf       106:                const Method& method=*junction.method;
                    107:                int max_params=
                    108:                        method.max_numbered_params_count?method.max_numbered_params_count:
                    109:                        method.params_names?method.params_names->size():
                    110:                        0;
                    111:                if(store_param_index==max_params)
1.23      paf       112:                        throw Exception("parser.runtime",
1.26    ! paf       113:                                &name(),
1.7       paf       114:                                "method of %s (%s) accepts maximum %d parameter(s)", 
1.25      paf       115:                                        junction.self.get_class()->name_cstr(),
1.1       paf       116:                                        junction.self.type(),
                    117:                                        max_params);
                    118:                
                    119:                if(method.max_numbered_params_count) { // are this method params numbered?
1.25      paf       120:                        fnumbered_params+=value;
1.1       paf       121:                } else { // named param
1.25      paf       122:                        // speedup: not checking for clash with "result" fname
                    123:                        const String& fname=*method.params_names->get_string(store_param_index);
                    124:                        set_my_variable(fname, value);
1.1       paf       125:                }
                    126:                store_param_index++;
                    127:        }
                    128:        void fill_unspecified_params() {
                    129:                const Method &method=*junction.method;
                    130:                if(method.params_names) // there are any named parameters might need filling?
                    131:                        for(; store_param_index<method.params_names->size(); store_param_index++) {
1.25      paf       132:                                const String& fname=*method.params_names->get_string(store_param_index);
                    133:                                my.put(fname, NEW VVoid(pool()));
1.1       paf       134:                        }
                    135:        }
                    136: 
1.25      paf       137:        MethodParams *numbered_params() { return &fnumbered_params; }
1.18      paf       138: 
                    139: private:
                    140: 
1.25      paf       141:        bool has_my() {
                    142:                return junction.method->max_numbered_params_count==0;
                    143:        }
                    144: 
                    145:        void set_my_variable(const String& fname, Value *value) {
                    146:                my.put(fname, value); // remember param
1.20      paf       147:        }
                    148: 
                    149:        Value *get_result_variable() {
1.25      paf       150:                Value *result=has_my()?static_cast<Value*>(my.get(*result_var_name)):0;
1.20      paf       151:                return result && result!=fresult_initial_void ? result : 0;
1.18      paf       152:        }
1.1       paf       153: 
                    154: public:
                    155:        
                    156:        const Junction& junction;
                    157: 
                    158: private:
1.25      paf       159:        const String& fname;
                    160: 
1.1       paf       161:        int store_param_index;
1.25      paf       162:        Hash my;/*OR*/MethodParams fnumbered_params;
1.1       paf       163:        Value *fself;
1.15      parser    164: 
                    165: private:
                    166:        Value *fresult_initial_void;
1.1       paf       167: 
                    168: };
                    169: 
                    170: #endif

E-mail: