Annotation of parser3/src/types/pa_vmframe.h, revision 1.12

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

E-mail: