|
|
| version 1.1, 2001/02/11 19:35:39 | version 1.28, 2001/02/23 14:18:27 |
|---|---|
| Line 1 | Line 1 |
| void process(Pool& pool, | /* |
| Value& self, | $Id$ |
| RContext& rcontext, WContext& wcontext, | */ |
| StringIterator& code, char char_to_stop_before) { | |
| #include "pa_request.h" | |
| // $ on code? | #include "pa_wcontext.h" |
| process_dollar(pool, rcontext, wcontext, code, char_to_stop_before); | #include "pa_common.h" |
| #include "pa_vclass.h" | |
| // ^ on code? | |
| process_bird(pool, rcontext, wcontext, code, char_to_stop_before); | #include <stdio.h> |
| void core() { | |
| Pool pool; | |
| Request request(pool); | |
| request.core(); | |
| } | } |
| void process_dollar(Pool& pool, | void Request::core() { |
| Value& THIS, | TRY { |
| RContext& rcontext, WContext& wcontext, | String name_RUN(pool()); name_RUN.APPEND_CONST("RUN"); |
| StringIterator& iter, char char_to_stop_before) { | char *result=execute_MAIN(construct_class(name_RUN, load_and_compile_RUN())); |
| printf("-----------------\n%s\n----------------\n", result); | |
| // $name.field.subfield -- read | } |
| // $name.field.subfield(constructor code) -- construct | CATCH(e) { |
| // $name.field.subfield[usage code & if none existed autoconstructed as VHash] -- use OR auto-VHash construct | printf("error occured: %s\n", e.comment()); |
| const String *type=e.type(); | |
| Array/*<String&>*/ names(pool); // what.they.refer.to left-to-right list | if(type) { |
| char names_ended_before; // the char after long name | printf(" type: %s", type->cstr()); |
| get_names( | const String *code=e.code(); |
| iter, " ([", | if(code) |
| &names, &names_ended_before); // must return count()>0 | printf(", code: %s", code->cstr()); |
| printf("\n"); | |
| bool read_mode=name_ended_before==' '; | |
| Value *context=read_mode?rcontext:wcontext; | |
| if(read_mode) { | |
| for(int i=0; i<names.count(); i++) { | |
| context=context->get_element(static_cast<Value *>(names.get[i])); | |
| if(!context) // no such object field, nothing bad, just ignore that | |
| return; | |
| } | } |
| wcontext.write(context); | const String *problem_source=e.problem_source(); |
| } else { // write mode | if(problem_source) { |
| iter++; // skip '(' '[' | const Origin& origin=problem_source->origin(); |
| printf(" '%s'\n", | |
| bool construct_mode=names_ended_before=='('; | problem_source->cstr()); |
| if(origin.file) | |
| int steps=names.count(); | printf(" [%s:%d]", |
| if(construct_mode) | origin.file, 1+origin.line); |
| steps--; | printf("\n"); |
| for(int i=0; i<steps; i++) { | |
| String& name=static_cast<String&>(names.get[i]); | |
| Value *next_current=context->get_element(name); | |
| if(next_current) | |
| next_current=context->put_element(name, new(pool) VHash(pool)); | |
| context=new_current; | |
| } | } |
| } | |
| END_CATCH | |
| } | |
| if(construct_mode) { | Array& Request::load_and_compile_RUN() { |
| // pure side effect, no wcontext.write here | char *file="Y:\\parser3\\src\\test.p"; |
| String& name=static_cast<String&>(names.get[steps]); | char *source=file_read(pool(), file); |
| WContext local_wcontext(pool /* empty */); | Array& compiled_methods=COMPILE(source, file); |
| process(pool, rcontext, local_wcontext, iter, ')'); | return compiled_methods; |
| context->put_element(name, local_wcontext.value()); | } |
| } else { // =='[' | |
| WContext local_context(pool, context); | VClass *Request::construct_class(String& name, Array& compiled_methods) { |
| process(pool, local_context, local_context, iter, ']'); | // create new 'name' vclass, add it to request's classes |
| wcontext.write(local_context); | Array immediate_parents(pool()); |
| } | // TODO: immediate_parents=@PARENTS |
| VClass *result=NEW VClass(pool(), name, immediate_parents); | |
| result->set_name(name); | |
| classes().put(name, result); | |
| iter++; // skip ')' ']' | for(int i=0; i<compiled_methods.size(); i++) { |
| // TODO: filter out @PARENTS & @CLASS & ?co? | |
| Method &method=*static_cast<Method *>(compiled_methods.quick_get(i)); | |
| result->add_method(method.name, method); | |
| } | } |
| return result; | |
| } | } |
| void process_bird(Pool& pool, | char *Request::execute_MAIN(VClass *class_RUN) { |
| Value& self, | // initialize contexts |
| RContext& rcontext, WContext& wcontext, | root=self=rcontext=class_RUN; |
| StringIterator& iter, char char_to_stop_before) { | wcontext=NEW WContext(pool(), class_RUN); |
| // ^name.field.subfield.method[..] -- plain call | // locate @main code |
| // ^name.field.subfield.method_ref[..] -- method ref call, when .get_method()!=0 | String name_main(pool()); |
| name_main.APPEND_CONST(MAIN_METHOD_NAME); | |
| Array/*<String&>*/ names(pool); // what.they.refer.to left-to-right list | |
| char names_ended_before; // the char after long name | Method *method_main=class_RUN->get_method(name_main); |
| get_names( | if(!method_main) |
| iter, "[", | THROW(0,0, |
| &names, &names_ended_before); // must return count()>0 | &class_RUN->name(), |
| "no '"MAIN_METHOD_NAME"' method in class"); | |
| Value *context=rcontext; | |
| iter++; // skip '[' | |
| Value *local_self=context; | |
| int steps=names.count()-1; | |
| for(int i=0; i<steps; i++) { | |
| String& name=static_cast<String&>(names.get[i]); | |
| context=(local_self=context)->get_element(name); | |
| if(!context) // no such object field, sad story: can't call method of void | |
| pool.exception().raise(name, "call: to void.method"); | |
| } | |
| String& name=static_cast<String&>(names.get[steps]); | |
| // first we're trying to locate method with that 'name' | |
| Method *method=context.get_method(name); | |
| if(!method) { // no such method: try to locate method ref field | |
| Value *value=context.get_element(name); | |
| if(!value) // failed: no element of that 'name' | |
| pool.exception().raise(name, "call: no method field found"); | |
| method=value->get_method(); | |
| if(!method) // failed: that field wasn't method_ref | |
| pool.exception().raise(name, "call: this field is not a method reference"); | |
| local_self=value->get_self(); | |
| } | |
| // execute! | |
| execute(method_main->code); | |
| Array/*<String&>*/ param_values(pool); | |
| get_params( | |
| iter, "]", | |
| ¶m_values); | |
| iter++; // skip ']' | |
| Method_this_n_params local_rcontext(pool, | |
| local_self, | |
| method->param_names, param_values); | |
| WContext local_wcontext(pool /* empty */); | |
| process(pool, local_rcontext, local_wcontext, iter, ']'); | |
| wcontext.write(local_wcontext); | |
| } | |
| // return chars | |
| return wcontext->get_string()->cstr(); | |
| } |