Annotation of parser3/src/main/compile.C, revision 1.91

1.32      paf         1: /** @file
1.33      paf         2:        Parser: compiler part of request class.
                      3: 
1.90      moko        4:        Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com)
1.88      moko        5:        Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>
1.64      paf         6: */
1.33      paf         7: 
1.91    ! moko        8: volatile const char * IDENT_COMPILE_C="$Id: compile.C,v 1.90 2026/04/25 13:38:46 moko Exp $";
1.1       paf         9: 
1.10      paf        10: #include "pa_request.h"
1.1       paf        11: #include "compile_tools.h"
1.91    ! moko       12: #include "pa_vclass.h"
1.1       paf        13: 
                     14: extern int yydebug;
1.83      moko       15: extern int yyparse (Parse_control *);
1.1       paf        16: 
1.91    ! moko       17: ArrayClass& Request::compile(VStateless_class* aclass, const char* source, const String* main_alias, uint file_no, int line_no_offset, Code_cache* code) {
1.7       paf        18:        // prepare to parse
1.73      paf        19:        Parse_control pc(*this, aclass, source, main_alias, file_no, line_no_offset);
1.91    ! moko       20: #ifdef CODE_CACHE
        !            21:        if(code)
        !            22:                code->file_no=file_no;
        !            23:        pc.code_cache=code;
        !            24: #endif
1.10      paf        25: 
1.12      paf        26:        // parse=compile! 
1.60      paf        27:        //yydebug=1;
1.10      paf        28:        if(yyparse(&pc)) { // error?
1.70      paf        29:                pc.pos_prev_c();
1.75      paf        30:                if(!pc.explicit_result)
                     31:                        if(pc.pos.col==0) // expecting something after EOL means they've expected it BEFORE
                     32:                                pc.pos_prev_c();
1.70      paf        33: 
1.84      moko       34:                exception_trace.push(Trace(0, Operation::Origin::create(file_no, pc.pos.line, pc.pos.col)));
                     35:                throw Exception("parser.compile", 0, "%s", pc.error);
1.8       paf        36:        }
1.7       paf        37: 
1.91    ! moko       38: #ifdef CODE_CACHE
        !            39:        if(code)
        !            40:                Code_cache_manager::put(*code);
        !            41: #endif
        !            42: 
1.7       paf        43:        // result
1.79      misha      44:        return *pc.cclasses;
1.1       paf        45: }
1.91    ! moko       46: 
        !            47: #ifdef CODE_CACHE
        !            48: 
        !            49: #define CLASS_ADD if(!pc.class_add()) \
        !            50:        throw Exception("parser.compile", 0, "%s - class is already defined", pc.cclass->type());
        !            51: 
        !            52: /// replays the compilation using the cached methods, mirrors control_method and code_method in compile.y
        !            53: ArrayClass& Code_cache::replay(Request& r, VStateless_class& aclass) {
        !            54:        Parse_control pc(r, &aclass, "", 0 /*main_alias: only ^process has one*/, file_no, 0);
        !            55:        const String* filespec=r.get_used_filespec(file_no);
        !            56: 
        !            57:        for(Array<Action>::Iterator i(actions); i; ) {
        !            58:                Action action=i.next();
        !            59:                switch(action.kind) {
        !            60:                        case CLASS:
        !            61:                                CLASS_ADD;
        !            62:                                pc.cclass_new=new VClass(action.name->cstr(), filespec);
        !            63:                                pc.append=false;
        !            64:                                break;
        !            65:                        case USE:
        !            66:                                CLASS_ADD;
        !            67:                                r.use_file(*action.name, filespec, action.origin);
        !            68:                                break;
        !            69:                        case BASE:
        !            70:                                CLASS_ADD;
        !            71:                                if(VStateless_class* base_class=r.get_class(*action.name))
        !            72:                                        pc.cclass->get_class()->set_base(base_class);
        !            73:                                else
        !            74:                                        throw Exception("parser.compile", 0, "'%s': undefined class in @BASE", action.name->cstr());
        !            75:                                break;
        !            76:                        case OPTION:
        !            77:                                if(*action.name==Symbols::LOCALS_SYMBOL)
        !            78:                                        pc.set_all_vars_local();
        !            79:                                else if(*action.name==Symbols::PARTIAL_SYMBOL) {
        !            80:                                        if(VStateless_class* existed=pc.get_existed_class(pc.cclass_new)) {
        !            81:                                                if(!pc.reuse_existed_class(existed))
        !            82:                                                        throw Exception("parser.compile", 0, "can't append methods to '%s' - the class wasn't marked as partial", pc.cclass_new->type());
        !            83:                                        } else
        !            84:                                                pc.cclass_new->set_partial();
        !            85:                                } else if(*action.name==Symbols::STATIC_SYMBOL)
        !            86:                                        pc.set_methods_call_type(Method::CT_STATIC);
        !            87:                                else if(*action.name==Symbols::DYNAMIC_SYMBOL)
        !            88:                                        pc.set_methods_call_type(Method::CT_DYNAMIC);
        !            89:                                break;
        !            90:                        case METHOD:
        !            91:                                CLASS_ADD;
        !            92:                                pc.cclass->set_method(*action.name, action.method);
        !            93:                                break;
        !            94:                        case MAIN:
        !            95:                                pc.cclass->set_method(*action.name, action.method);
        !            96:                                break;
        !            97:                }
        !            98:        }
        !            99: 
        !           100:        return *pc.cclasses;
        !           101: }
        !           102: #endif

E-mail: