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: