|
|
| version 1.1, 2001/02/11 19:35:39 | version 1.58, 2001/03/11 12:04:44 |
|---|---|
| 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> (http://design.ru/paf) |
| // $ 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 "_string.h" |
| } | #include "_double.h" |
| #include "_int.h" | |
| void process_dollar(Pool& pool, | #include "pa_request.h" |
| Value& THIS, | |
| RContext& rcontext, WContext& wcontext, | #define GLOBAL_STRING(name, value) name=new(pool) String(pool); name->APPEND_CONST(value) |
| StringIterator& iter, char char_to_stop_before) { | #define LOCAL_STRING(name, value) String name(pool); name.APPEND_CONST(value) |
| // $name.field.subfield -- read | String *unnamed_name; |
| // $name.field.subfield(constructor code) -- construct | String *empty_string; |
| // $name.field.subfield[usage code & if none existed autoconstructed as VHash] -- use OR auto-VHash construct | |
| String *auto_method_name; | |
| Array/*<String&>*/ names(pool); // what.they.refer.to left-to-right list | String *main_method_name; |
| char names_ended_before; // the char after long name | |
| get_names( | String *main_class_name; |
| iter, " ([", | String *root_class_name; |
| &names, &names_ended_before); // must return count()>0 | String *env_class_name; |
| bool read_mode=name_ended_before==' '; | Hash *untaint_lang_name_to_value; |
| Value *context=read_mode?rcontext:wcontext; | |
| if(read_mode) { | void core() { |
| for(int i=0; i<names.count(); i++) { | Pool pool; |
| context=context->get_element(static_cast<Value *>(names.get[i])); | |
| if(!context) // no such object field, nothing bad, just ignore that | // names |
| return; | GLOBAL_STRING(unnamed_name, "unnamed"); |
| } | empty_string=new(pool) String(pool); |
| wcontext.write(context); | |
| } else { // write mode | GLOBAL_STRING(auto_method_name, AUTO_METHOD_NAME); |
| iter++; // skip '(' '[' | GLOBAL_STRING(main_method_name, MAIN_METHOD_NAME); |
| bool construct_mode=names_ended_before=='('; | GLOBAL_STRING(main_class_name, MAIN_CLASS_NAME); |
| GLOBAL_STRING(root_class_name, ROOT_CLASS_NAME); | |
| int steps=names.count(); | GLOBAL_STRING(env_class_name, ENV_CLASS_NAME); |
| if(construct_mode) | |
| steps--; | // hashes |
| for(int i=0; i<steps; i++) { | untaint_lang_name_to_value=new(pool) Hash(pool); |
| String& name=static_cast<String&>(names.get[i]); | LOCAL_STRING(as_is, "as-is"); |
| Value *next_current=context->get_element(name); | untaint_lang_name_to_value->put(as_is, |
| if(next_current) | static_cast<int>(String::Untaint_lang::AS_IS)); |
| next_current=context->put_element(name, new(pool) VHash(pool)); | LOCAL_STRING(sql, "sql"); |
| context=new_current; | untaint_lang_name_to_value->put(sql, |
| } | static_cast<int>(String::Untaint_lang::SQL)); |
| LOCAL_STRING(js, "js"); | |
| if(construct_mode) { | untaint_lang_name_to_value->put(js, |
| // pure side effect, no wcontext.write here | static_cast<int>(String::Untaint_lang::JS)); |
| String& name=static_cast<String&>(names.get[steps]); | LOCAL_STRING(html, "html"); |
| WContext local_wcontext(pool /* empty */); | untaint_lang_name_to_value->put(html, |
| process(pool, rcontext, local_wcontext, iter, ')'); | static_cast<int>(String::Untaint_lang::HTML)); |
| context->put_element(name, local_wcontext.value()); | LOCAL_STRING(html_typo, "html-typo"); |
| } else { // =='[' | untaint_lang_name_to_value->put(html_typo, |
| WContext local_context(pool, context); | static_cast<int>(String::Untaint_lang::HTML_TYPO)); |
| process(pool, local_context, local_context, iter, ']'); | |
| wcontext.write(local_context); | // classes |
| } | initialize_string_class(pool, *(string_class=new(pool) VClass(pool))); |
| initialize_double_class(pool, *(double_class=new(pool) VClass(pool))); | |
| iter++; // skip ')' ']' | initialize_int_class(pool, *(int_class=new(pool) VClass(pool))); |
| } | |
| // request | |
| Request request(pool); | |
| request.core(); | |
| } | } |
| 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); | |
| } | |