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

1.1     ! paf         1: /*
        !             2:        Parser
        !             3:        Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
        !             4:        Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
        !             5: 
        !             6:        $Id: pa_vmframe.h,v 1.12 2001/04/05 19:35:18 paf Exp $
        !             7: */
        !             8: 
        !             9: #ifndef PA_VMETHOD_FRAME_H
        !            10: #define PA_VMETHOD_FRAME_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
        !            37:        VStateless_class* get_class() { return fself->get_class(); }
        !            38: 
        !            39:        // methodframe: self_transparent
        !            40:        VAliased *get_aliased() { return fself->get_aliased(); }
        !            41: 
        !            42: public: // wcontext
        !            43: 
        !            44:        Value *result() {
        !            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
        !            48:                return result && result->is_defined()?result:WContext::result();
        !            49:        }
        !            50: 
        !            51: public: // usage
        !            52: 
        !            53:        VMethodFrame(Pool& apool, 
        !            54:                const Junction& ajunction/*info: always method-junction*/, 
        !            55:                bool ais_constructor) : 
        !            56:                WContext(apool, 0 /* empty */, false /* not constructing */),
        !            57: 
        !            58:                junction(ajunction),
        !            59:                is_constructor(ais_constructor),
        !            60:                store_param_index(0),
        !            61:                my(0), fnumbered_params(0),
        !            62:                fself(0) {
        !            63: 
        !            64:                const Method &method=*junction.method;
        !            65: 
        !            66:                if(method.max_numbered_params_count) // are this method params numbered?
        !            67:                        fnumbered_params=NEW Array(pool()); // create storage
        !            68:                else { // named params
        !            69:                        my=NEW Hash(pool()); // create storage
        !            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);
        !            86:                        }
        !            87:                }
        !            88:        }
        !            89: 
        !            90:        void set_self(Value& aself) { fself=&aself; }
        !            91:        Value *self() { return fself; }
        !            92: 
        !            93:        void store_param(const String& actual_method_name, Value *value) {
        !            94:                const Method& method=*junction.method;
        !            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,
        !           101:                                &actual_method_name,
        !           102:                                "method of %s (%s) accepts maximum %d parameter(s)", 
        !           103:                                        junction.self.name().cstr(),
        !           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
        !           110:                        // speedup: not checking for clash with "result" name
        !           111:                        const String& name=*method.params_names->get_string(store_param_index);
        !           112:                        my->put(name, value); // remember param
        !           113:                        value->set_name(name); // set param's 'name'
        !           114:                }
        !           115:                store_param_index++;
        !           116:        }
        !           117:        void fill_unspecified_params() {
        !           118:                const Method &method=*junction.method;
        !           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());
        !           122:                                const String& name=*method.params_names->get_string(store_param_index);
        !           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;
        !           133:        bool is_constructor;
        !           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: