|
|
| version 1.1, 2001/02/11 19:35:39 | version 1.42, 2001/03/06 10:49:24 |
|---|---|
| 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_wwrapper.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, | char *file="Y:\\parser3\\src\\test.p"; |
| StringIterator& iter, char char_to_stop_before) { | String RUN(pool()); RUN.APPEND_CONST(NAME_RUN); |
| use(file, &RUN); | |
| // $name.field.subfield -- read | |
| // $name.field.subfield(constructor code) -- construct | char *result=execute_MAIN(); |
| // $name.field.subfield[usage code & if none existed autoconstructed as VHash] -- use OR auto-VHash construct | printf("result-----------------\n%sEOF----------------\n", result); |
| } | |
| Array/*<String&>*/ names(pool); // what.they.refer.to left-to-right list | CATCH(e) { |
| char names_ended_before; // the char after long name | printf("\nERROR: "); |
| get_names( | const String *problem_source=e.problem_source(); |
| iter, " ([", | if(problem_source) { |
| &names, &names_ended_before); // must return count()>0 | const Origin& origin=problem_source->origin(); |
| if(origin.file) | |
| bool read_mode=name_ended_before==' '; | printf("%s(%d): ", |
| Value *context=read_mode?rcontext:wcontext; | origin.file, 1+origin.line); |
| printf("'%s' ", | |
| if(read_mode) { | problem_source->cstr()); |
| 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); | |
| } else { // write mode | |
| iter++; // skip '(' '[' | |
| bool construct_mode=names_ended_before=='('; | |
| int steps=names.count(); | |
| if(construct_mode) | |
| steps--; | |
| 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; | |
| } | } |
| printf("%s", e.comment()); | |
| if(construct_mode) { | const String *type=e.type(); |
| // pure side effect, no wcontext.write here | if(type) { |
| String& name=static_cast<String&>(names.get[steps]); | printf(" type: %s", type->cstr()); |
| WContext local_wcontext(pool /* empty */); | const String *code=e.code(); |
| process(pool, rcontext, local_wcontext, iter, ')'); | if(code) |
| context->put_element(name, local_wcontext.value()); | printf(", code: %s", code->cstr()); |
| } else { // =='[' | |
| WContext local_context(pool, context); | |
| process(pool, local_context, local_context, iter, ']'); | |
| wcontext.write(local_context); | |
| } | } |
| printf("\n"); | |
| iter++; // skip ')' ']' | |
| } | } |
| END_CATCH | |
| } | } |
| void process_bird(Pool& pool, | void Request::use(char *file, String *alias) { |
| Value& self, | // TODO: обнаружить|решить cyclic dependences |
| RContext& rcontext, WContext& wcontext, | char *source=file_read(pool(), file); |
| StringIterator& iter, char char_to_stop_before) { | if(!source) |
| THROW(0,0, | |
| // ^name.field.subfield.method[..] -- plain call | 0, |
| // ^name.field.subfield.method_ref[..] -- method ref call, when .get_method()!=0 | "use: can not read '%s' file", file); |
| Array/*<String&>*/ names(pool); // what.they.refer.to left-to-right list | VClass& vclass=COMPILE(source, alias, file); |
| char names_ended_before; // the char after long name | String& vclass_name=vclass.name(); |
| get_names( | //TODO: обнаружить, что грузят не объект, а операторы. |
| iter, "[", | // загрузить операторы |
| &names, &names_ended_before); // must return count()>0 | classes_array()+=&vclass; |
| classes().put(vclass_name, &vclass); | |
| Value *context=rcontext; | if(alias) |
| iter++; // skip '[' | classes().put(*alias, &vclass); |
| } | |
| Value *local_self=context; | |
| int steps=names.count()-1; | char *Request::execute_MAIN() { |
| for(int i=0; i<steps; i++) { | // locate class with @main & it's code |
| String& name=static_cast<String&>(names.get[i]); | String name_main(pool()); |
| context=(local_self=context)->get_element(name); | name_main.APPEND_CONST(MAIN_METHOD_NAME); |
| if(!context) // no such object field, sad story: can't call method of void | |
| pool.exception().raise(name, "call: to void.method"); | // looking for latest known @main |
| for(int i=classes_array().size(); --i>=0;) { | |
| VClass *vclass=static_cast<VClass *>(classes_array().get(i)); | |
| Value *main=vclass->get_element(name_main); | |
| if(main) { // found some 'main' element | |
| Junction *junction=main->get_junction(); | |
| if(junction) {// it even has junction! | |
| const Method *method=junction->method; | |
| if(method) { // and junction is method-junction! call it | |
| // initialize contexts | |
| root=rcontext=self=vclass; | |
| wcontext=NEW WWrapper(pool(), vclass, false /* not constructing */); | |
| // execute! | |
| execute(method->code); | |
| // return chars | |
| return wcontext->get_string()->cstr(); | |
| } | |
| } | |
| } | |
| } | } |
| 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(); | |
| } | |
| 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); | |
| } | |
| THROW(0,0, | |
| 0, | |
| "'"MAIN_METHOD_NAME"' method not found"); | |
| return 0; | |
| } |