Annotation of parser3/src/types/pa_vmethod_frame.C, revision 1.52

1.2       paf         1: /**    @file
                      2:        Parser: method frame class.
                      3: 
1.48      moko        4:        Copyright (c) 2001-2024 Art. Lebedev Studio (http://www.artlebedev.com)
1.44      moko        5:        Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>\
1.2       paf         6: */
                      7: 
                      8: #include "pa_vmethod_frame.h"
1.36      moko        9: #include "pa_vcaller_wrapper.h"
1.2       paf        10: #include "pa_request.h"
1.51      moko       11: #include "pa_vfile.h"
1.2       paf        12: 
1.52    ! moko       13: volatile const char * IDENT_PA_VMETHOD_FRAME_C="$Id: pa_vmethod_frame.C,v 1.51 2024/12/11 00:37:04 moko Exp $" IDENT_PA_VMETHOD_FRAME_H IDENT_PA_VCALLER_WRAPPER_H;
1.2       paf        14: 
                     15: // MethodParams: methods
                     16: 
1.39      moko       17: const char *skip_name[]={
                     18:        "",
                     19:        "continue",
                     20:        "break",
                     21:        "return"
                     22: };
                     23: 
1.32      moko       24: Value& MethodParams::get_processed(Value& value, const char* msg, int index, Request& r) {
                     25:        if(!value.get_junction())
                     26:                throw Exception(PARSER_RUNTIME, 0, "%s (parameter #%d)", msg, 1+index);
1.39      moko       27:        Value& result=r.process(value);
1.40      moko       28:        if(r.get_skip()){
                     29:                const char *skip=skip_name[r.get_skip()];
                     30:                r.set_skip(Request::SKIP_NOTHING);
                     31:                throw Exception(PARSER_RUNTIME, 0, "%s is not allowed in expression passed to native method (parameter #%d)", skip, 1+index);
                     32:        }
1.39      moko       33:        return result;
1.2       paf        34: }
                     35: 
1.37      moko       36: // Should be synced with Value::as_hash
1.21      misha      37: HashStringValue* MethodParams::as_hash(int index, const char* name) {
1.34      moko       38:        Value& value=get(index);
1.33      moko       39:        if(value.get_junction())
                     40:                throw Exception(PARSER_RUNTIME, 0, "%s param must not be code (parameter #%d)", name ? name : "options", 1+index);
                     41:        if(!value.is_defined()) // empty hash is not defined, but we don't need it anyway
                     42:                return 0;
                     43:        if(HashStringValue* result=value.get_hash())
                     44:                return result;
                     45:        if(value.is_string() && value.get_string()->trim().is_empty())
                     46:                return 0;
1.32      moko       47:        throw Exception(PARSER_RUNTIME, 0, "%s must have hash representation (parameter #%d)", name ? name : "options", 1+index);
1.21      misha      48: }
                     49: 
                     50: Table* MethodParams::as_table(int index, const char* name) {
1.34      moko       51:        Value& value=get(index);
1.33      moko       52:        if(value.get_junction())
                     53:                throw Exception(PARSER_RUNTIME, 0, "%s param must not be code (parameter #%d)", name ? name : "options", 1+index);
                     54:        if(Table* result=value.get_table())
                     55:                return result;
1.43      moko       56:        if(value.is_string() && value.get_string()->trim().is_empty())
                     57:                return 0;
1.30      moko       58:        throw Exception(PARSER_RUNTIME, 0, "%s param must have table representation (parameter #%d)", name ? name : "options", 1+index);
1.23      moko       59: }
1.21      misha      60: 
1.51      moko       61: const String& MethodParams::as_file_name(int index) {
1.52    ! moko       62:        const String* result=get(index).get_string();
        !            63:        if(result && !result->is_empty())
        !            64:                return *result;
        !            65:        throw Exception(PARSER_RUNTIME, 0, "%s (parameter #%d)", FILE_NAME_MUST_BE_NE_STRING, 1+index);
1.51      moko       66: }
                     67: 
                     68: const String& MethodParams::as_file_spec(int index) {
                     69:        if(VFile* vfile=dynamic_cast<VFile *>(&get(index)))
                     70:                return vfile->get_element(name_name)->as_string();
                     71:        return as_string(index, FILE_NAME_MUST_BE_STRING_OR_FILE);
                     72: }
                     73: 
1.2       paf        74: // VMethodFrame: methods
                     75: 
1.35      moko       76: void VNativeMethodFrame::call(Request &r){
                     77:        check_call_type();
                     78:        method.native_code(r, fnumbered_params);
                     79: }
                     80: 
                     81: void VParserMethodFrame::call(Request &r){
                     82:        check_call_type();
1.47      moko       83:        r.recursion_checked_execute(*method.parser_code);
1.38      moko       84:        r.check_skip_return();
1.35      moko       85: }
                     86: 
1.50      moko       87: VParserMethodFrame::VParserMethodFrame(const Method& amethod, VMethodFrame *acaller, Value& aself) : VMethodFrame(amethod, acaller, aself), my_result(NULL) {
1.35      moko       88:        if(method.locals_names) { // are there any local var names?
1.50      moko       89:                // remember them, those are flags that fname is local == to be looked up in 'my'
1.46      moko       90:                for(ArrayString::Iterator i(*method.locals_names); i; ) {
1.50      moko       91:                        // "result" excluded from local variables during compilation, no need to call set_my_variable
                     92:                        my.put(*i.next(), VString::empty());
1.2       paf        93:                }
1.35      moko       94:        }
1.2       paf        95: }
1.36      moko       96: 
                     97: Value* VParserMethodFrame::get_caller_wrapper(){
                     98:        static VCallerWrapper *caller_wrapper_template=0;
                     99:        if(!caller())
                    100:                return 0;
                    101:        if(caller_wrapper_template && &caller_wrapper_template->caller() == caller())
                    102:                return caller_wrapper_template;
                    103:        return caller_wrapper_template=new VCallerWrapper(*caller());
                    104: }

E-mail: