--- parser3/src/main/Attic/core.C 2001/02/13 15:10:46 1.8 +++ parser3/src/main/Attic/core.C 2001/03/13 20:02:10 1.68 @@ -1,177 +1,77 @@ -void process(method_self_n_params_n_locals& root, Value& self, - arcontext& arcontext, WContext& awcontext, - String_iterator& code, char char_to_stop_before) { - - // $ on code? - process_dollar(root, self, arcontext, awcontext, code, char_to_stop_before); - - // ^ on code? - process_bird(root, self, arcontext, awcontext, code, char_to_stop_before); - - // TODO - // 2. вызовы статических методов +/* + Parser + Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) + Author: Alexander Petrosyan (http://design.ru/paf) + + $Id: core.C,v 1.68 2001/03/13 20:02:10 paf Exp $ +*/ + +#include "core.h" +#include "_string.h" +#include "_double.h" +#include "_int.h" +#include "_table.h" +#include "_form.h" +#include "_env.h" + +String *exception_method_name; + +String *unnamed_name; +String *empty_string; + +String *auto_method_name; +String *main_method_name; + +String *root_class_name; +String *main_class_name; +String *env_class_name; +String *table_class_name; +String *form_class_name; + +Hash *untaint_lang_name2enum; + + +void core(Pool& pool) { + #define NEW_STRING(name, value) name=new(pool) String(pool); name->APPEND_CONST(value) + #define LOCAL_STRING(name, value) String name(pool); name.APPEND_CONST(value) + + // names + NEW_STRING(exception_method_name, EXCEPTION_METHOD_NAME); + + NEW_STRING(unnamed_name, UNNAMED_NAME); + empty_string=new(pool) String(pool); + + NEW_STRING(auto_method_name, AUTO_METHOD_NAME); + NEW_STRING(main_method_name, MAIN_METHOD_NAME); + + NEW_STRING(root_class_name, ROOT_CLASS_NAME); + NEW_STRING(main_class_name, MAIN_CLASS_NAME); + NEW_STRING(table_class_name, TABLE_CLASS_NAME); + NEW_STRING(env_class_name, ENV_CLASS_NAME); + NEW_STRING(form_class_name, FORM_CLASS_NAME); + + // hashes + untaint_lang_name2enum=new(pool) Hash(pool); + LOCAL_STRING(as_is, "as-is"); + untaint_lang_name2enum->put(as_is, (int)String::Untaint_lang::AS_IS); + LOCAL_STRING(table, "table"); + untaint_lang_name2enum->put(table, (int)String::Untaint_lang::TABLE); + LOCAL_STRING(sql, "sql"); + untaint_lang_name2enum->put(sql, (int)String::Untaint_lang::SQL); + LOCAL_STRING(js, "js"); + untaint_lang_name2enum->put(js, (int)String::Untaint_lang::JS); + LOCAL_STRING(html, "html"); + untaint_lang_name2enum->put(html, (int)String::Untaint_lang::HTML); + LOCAL_STRING(html_typo, "html-typo"); + untaint_lang_name2enum->put(html_typo, (int)String::Untaint_lang::HTML_TYPO); + + // read-only stateless classes + initialize_string_class(pool, *(string_class=new(pool) VStateless_class(pool))); string_class->freeze(); + initialize_double_class(pool, *(double_class=new(pool) VStateless_class(pool))); double_class->freeze(); + initialize_int_class(pool, *(int_class=new(pool) VStateless_class(pool))); int_class->freeze(); + initialize_table_class(pool, *(table_class=new(pool) VStateless_class(pool))); table_class->freeze(); + + // read-only stateless base classes + initialize_env_base_class(pool, *(env_base_class=new(pool) VStateless_class(pool))); env_base_class->set_name(*env_class_name); env_base_class->freeze(); + initialize_form_base_class(pool, *(form_base_class=new(pool) VStateless_class(pool))); form_base_class->set_name(*form_class_name); form_base_class->freeze(); } - -void process_dollar(method_self_n_params_n_locals& root, Value& self, - arcontext& arcontext, WContext& awcontext, - String_iterator& iter, char char_to_stop_before) { - - // $name.field.subfield -- read - // $name.field.subfield(constructor code) -- construct - // $name.field.subfield[usage code & if none existed autoconstructed as VHash] -- use OR auto-VHash construct - - Array/**/ names(pool); // what.they.refer.to left-to-right list - char names_ended_before; // the char after long name - Prefix prefix; - get_names( - iter, " ([", - &prefix, &names, &names_ended_before); // can return count()=0 when $self alone - - bool read_mode=name_ended_before==' '; - Value *context= - prefix? - prefix==ROOT_PREFIX?root:self: - read_mode?arcontext:awcontext; - - if(read_mode) { - // 'context' dive into dotted path - for(int i=0; iget_element(static_cast(names.get[i])); - if(!context) // no such object field, nothing bad, just ignore that - return; - } - awcontext.write(context); - } else { // write mode - iter++; // skip '(' '[' - - bool construct_mode=names_ended_before=='('; - - // 'context' dive into dotted path, - int steps=names.count(); - // if constructing then "excluding last .name" - if(construct_mode) - if(!steps--) // bad: "$self("; now we can safely do ".get[steps]" below - pool.exception().raise("self re-construction prohibited"); - for(int i=0; i(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) { - // .name(construct-code), processing on arcontext in empty temp awcontext - // pure side effect, no awcontext.write here - // last .name - String& name=static_cast(names.get[steps]); - WContext local_wcontext(pool /* empty */); - process(root, self, arcontext, local_wcontext, iter, ')'); - context->put_element(name, local_wcontext.value()); - } else { // =='[' - // .name[with-code], processing on 'context' - WContext local_context(pool, context); - process(root, self, local_context, local_context, iter, ']'); - awcontext.write(local_context); - } - - iter++; // skip ')' ']' - } -} - -void process_bird(method_self_n_params_n_locals& root, Value& self, - arcontext& arcontext, WContext& awcontext, - String_iterator& iter, char char_to_stop_before) { - - // ^name.field.subfield.method[..] -- plain call - // ^name.field.subfield.method_ref[..] -- method ref call, when .get_method()!=0 - // ^class:method[..] -- no dotted path allowed before/after - // 1: wcontext.object_class == 0? -- constructor - // 2: wcontext.object_class.has_parent('class')? -- dynamic call - // 3: not -------------------------------------? -- static call - - Array/**/ names(pool); // what.they.refer.to left-to-right list - char names_ended_before; // the char after long name - Prefix prefix; - get_names( - iter, "[", - &prefix, &names, &names_ended_before); // can return count()=0 when ^self alone - - Value *context= - prefix? - prefix==ROOT_PREFIX?root:self: - arcontext; - iter++; // skip '[' - - // 'context' dive into dotted path, excluding last .name - int steps=names.count()-1; - if(steps<0) // bad: "^self["; now we can safely do ".get[steps]" below - pool.exception().raise("call: calling method named 'self'"); - for(int i=0; i(names.get[i]); - context=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"); - } - - // last .name - String& name=static_cast(names.get[steps]); - if(steps==0) { // the sole name on path, maybe ^class:method[ call - String_iterator ni(name); - if(ni.skip_to(':')) { // it is - ni++; // skip ':' - String method_name(pool); method_name.append(ni, 0); - name=method_name; // trim "class:" prefix from the name - - String cn(pool); cn.append(0, ni); - Class *right_class=classes.get(cn); - if(!oc) // bad: no such class - pool.exception().raise(cn, "call: undefined class"); - Class *left_class=awcontext.get_class(); - if(left_class) { - if(left_class.has_parent(right_class)) // dynamic call - ; - else // static call - context=right_class; - } else { // constructor: $some(^class:method[..]) call - context=new(pool) VClass(pool, right_class); - awcontext.write(context); - } - } - } - // 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) { // good: we have some element of that 'name' - Method_ref *method_ref=value->get_method_ref(); - if(!method_ref) // bad: that field wasn't method_ref - pool.exception().raise(name, "call: this field is not a method reference"); - method=method_ref->method; - context=method_ref->self; - } else { // no element of that 'name', that must be operator then - method=operators.get(name); - if(!method) // bad: that 'name' is neither method nor field nor operator - pool.exception().raise(name, "call: neither method nor field nor operator"); - } - } - - - Array/**/ param_values(pool); - get_params( - iter, - awcontext, - ¶m_values); - iter++; // skip ']' - - method_self_n_params_n_locals local_rcontext(pool, - context, - method->param_names, param_values, - method->local_names); - WContext local_wcontext(pool, local_self); - process( - context, local_rcontext, - local_rcontext, local_wcontext, - iter, ']'); - awcontext.write(local_wcontext); -} \ No newline at end of file