|
|
| version 1.1, 2001/02/11 19:35:39 | version 1.54, 2001/03/10 17:10:39 |
|---|---|
| Line 1 | Line 1 |
| void process(Pool& pool, | /* |
| Value& self, | Parser |
| RContext& rcontext, WContext& wcontext, | Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) |
| StringIterator& code, char char_to_stop_before) { | Author: Alexander Petrosyan <paf@design.ru> |
| // $ on code? | $Id$ |
| process_dollar(pool, rcontext, wcontext, code, char_to_stop_before); | */ |
| // ^ on code? | #include "core.h" |
| process_bird(pool, rcontext, wcontext, code, char_to_stop_before); | #include "classes/_string.h" |
| } | #include "classes/_double.h" |
| #include "classes/_int.h" | |
| void process_dollar(Pool& pool, | #include "pa_request.h" |
| Value& THIS, | |
| RContext& rcontext, WContext& wcontext, | String *unnamed_name; |
| StringIterator& iter, char char_to_stop_before) { | String *empty_string; |
| // $name.field.subfield -- read | String *auto_method_name; |
| // $name.field.subfield(constructor code) -- construct | String *main_method_name; |
| // $name.field.subfield[usage code & if none existed autoconstructed as VHash] -- use OR auto-VHash construct | |
| String *run_class_name; | |
| Array/*<String&>*/ names(pool); // what.they.refer.to left-to-right list | String *root_class_name; |
| char names_ended_before; // the char after long name | String *env_class_name; |
| get_names( | |
| iter, " ([", | void core() { |
| &names, &names_ended_before); // must return count()>0 | Pool pool; |
| bool read_mode=name_ended_before==' '; | // names |
| Value *context=read_mode?rcontext:wcontext; | unnamed_name=new(pool) String(pool); unnamed_name->APPEND_CONST("unnamed"); |
| empty_string=new(pool) String(pool); | |
| if(read_mode) { | |
| for(int i=0; i<names.count(); i++) { | auto_method_name=new(pool) String(pool); auto_method_name->APPEND_CONST(AUTO_METHOD_NAME); |
| context=context->get_element(static_cast<Value *>(names.get[i])); | main_method_name=new(pool) String(pool); main_method_name->APPEND_CONST(MAIN_METHOD_NAME); |
| if(!context) // no such object field, nothing bad, just ignore that | |
| return; | run_class_name=new(pool) String(pool); run_class_name->APPEND_CONST(RUN_CLASS_NAME); |
| } | root_class_name=new(pool) String(pool); root_class_name->APPEND_CONST(ROOT_CLASS_NAME); |
| wcontext.write(context); | env_class_name=new(pool) String(pool); env_class_name->APPEND_CONST(ENV_CLASS_NAME); |
| } else { // write mode | |
| iter++; // skip '(' '[' | // classes |
| initialize_string_class(pool, *(string_class=new(pool) VClass(pool))); | |
| bool construct_mode=names_ended_before=='('; | initialize_double_class(pool, *(double_class=new(pool) VClass(pool))); |
| initialize_int_class(pool, *(int_class=new(pool) VClass(pool))); | |
| int steps=names.count(); | |
| if(construct_mode) | // request |
| steps--; | Request request(pool); |
| for(int i=0; i<steps; i++) { | request.core(); |
| 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; | |
| } | |
| if(construct_mode) { | |
| // pure side effect, no wcontext.write here | |
| String& name=static_cast<String&>(names.get[steps]); | |
| WContext local_wcontext(pool /* empty */); | |
| process(pool, rcontext, local_wcontext, iter, ')'); | |
| context->put_element(name, local_wcontext.value()); | |
| } else { // =='[' | |
| WContext local_context(pool, context); | |
| process(pool, local_context, local_context, iter, ']'); | |
| wcontext.write(local_context); | |
| } | |
| iter++; // skip ')' ']' | |
| } | |
| } | } |
| void process_bird(Pool& pool, | |
| Value& self, | |
| RContext& rcontext, WContext& wcontext, | |
| StringIterator& iter, char char_to_stop_before) { | |
| // ^name.field.subfield.method[..] -- plain call | |
| // ^name.field.subfield.method_ref[..] -- method ref call, when .get_method()!=0 | |
| Array/*<String&>*/ names(pool); // what.they.refer.to left-to-right list | |
| char names_ended_before; // the char after long name | |
| get_names( | |
| iter, "[", | |
| &names, &names_ended_before); // must return count()>0 | |
| 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(); | |
| } | |
| 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); | |
| } | |