|
|
| version 1.204.2.6, 2003/02/04 09:44:27 | version 1.204.2.8.2.4, 2003/03/26 07:45:23 |
|---|---|
| Line 19 | Line 19 |
| -#: in iis make up specialized Pool object for that | -#: in iis make up specialized Pool object for that |
| */ | */ |
| #define YYSTYPE ArrayOperationPtr | #define YYSTYPE ArrayOperation* |
| #define YYPARSE_PARAM pc | #define YYPARSE_PARAM pc |
| #define YYLEX_PARAM pc | #define YYLEX_PARAM pc |
| #define YYDEBUG 1 | #define YYDEBUG 1 |
| Line 44 static int yylex(YYSTYPE *lvalp, void *p | Line 44 static int yylex(YYSTYPE *lvalp, void *p |
| // local convinient inplace typecast & var | // local convinient inplace typecast & var |
| #undef PC | |
| #define PC (*(parse_control *)pc) | #define PC (*(parse_control *)pc) |
| #undef POOL | |
| #define POOL (*PC.pool) | #define POOL (*PC.pool) |
| #undef NEW | |
| #define NEW new(POOL) | |
| #ifndef DOXYGEN | #ifndef DOXYGEN |
| %} | %} |
| Line 114 static int yylex(YYSTYPE *lvalp, void *p | Line 114 static int yylex(YYSTYPE *lvalp, void *p |
| %% | %% |
| all: | all: |
| one_big_piece { | one_big_piece { |
| MethodPtr method(new Method(main_method_name, Method::CT_ANY, | Method& method=*new Method(/*main_method_name, */Method::CT_ANY, |
| 0, 0, /*min, max numbered_params_count*/ | 0, 0, /*min, max numbered_params_count*/ |
| ArrayStringPtr(0)/*param_names*/, ArrayStringPtr(0)/*local_names*/, | 0/*param_names*/, 0/*local_names*/, |
| $1/*parser_code*/, 0/*native_code*/)); | $1/*parser_code*/, 0/*native_code*/); |
| PC.cclass->add_method(main_method_name, method); | PC.cclass->add_method(main_method_name, method); |
| } | } |
| | methods; | | methods; |
| Line 129 method: control_method | code_method; | Line 129 method: control_method | code_method; |
| control_method: '@' STRING '\n' | control_method: '@' STRING '\n' |
| maybe_control_strings { | maybe_control_strings { |
| StringPtr command=LA2S(*$2); | const String& command=*LA2S(*$2); |
| YYSTYPE strings_code=$4; | YYSTYPE strings_code=$4; |
| if(strings_code->count()<1*2) { | if(strings_code->count()<1*2) { |
| strcpy(PC.error, "@"); | strcpy(PC.error, "@"); |
| strcat(PC.error, command->cstr()); | strcat(PC.error, command.cstr()); |
| strcat(PC.error, " is empty"); | strcat(PC.error, " is empty"); |
| YYERROR; | YYERROR; |
| } | } |
| if(*command==CLASS_NAME) { | if(command==CLASS_NAME) { |
| if(PC.cclass->base_class()) { // already changed from default? | if(PC.cclass->base_class()) { // already changed from default? |
| strcpy(PC.error, "class already have a name '"); | strcpy(PC.error, "class already have a name '"); |
| strncat(PC.error, PC.cclass->name()->cstr(), 100); | strncat(PC.error, PC.cclass->name().cstr(), 100); |
| strcat(PC.error, "'"); | strcat(PC.error, "'"); |
| YYERROR; | YYERROR; |
| } | } |
| if(strings_code->count()==1*2) { | if(strings_code->count()==1*2) { |
| // new class' name | // new class' name |
| StringPtr name=LA2S(*strings_code); | const String& name=*LA2S(*strings_code); |
| // creating the class | // creating the class |
| VStateless_classPtr cclass(new VClass); | VStateless_class* cclass=new VClass; |
| PC.cclass=cclass.get(); | PC.cclass=cclass; |
| PC.cclass->set_name(name); | PC.cclass->set_name(name); |
| // append to request's classes | // append to request's classes |
| PC.request->classes().put(name, cclass); | PC.request.classes().put(name, cclass); |
| } else { | } else { |
| strcpy(PC.error, "@"CLASS_NAME" must contain sole name"); | strcpy(PC.error, "@"CLASS_NAME" must contain sole name"); |
| YYERROR; | YYERROR; |
| } | } |
| } else if(*command==USE_CONTROL_METHOD_NAME) { | } else if(command==USE_CONTROL_METHOD_NAME) { |
| for(int i=0; i<strings_code->count(); i+=2) | for(int i=0; i<strings_code->count(); i+=2) |
| PC.request->use_file(*PC.request->main_class, LA2S(*strings_code, i)); | PC.request.use_file(PC.request.main_class, *LA2S(*strings_code, i)); |
| } else if(*command==BASE_NAME) { | } else if(command==BASE_NAME) { |
| if(PC.cclass->base_class()) { // already changed from default? | if(PC.cclass->base_class()) { // already changed from default? |
| strcpy(PC.error, "class already have a base '"); | strcpy(PC.error, "class already have a base '"); |
| strncat(PC.error, PC.cclass->base_class()->name()->cstr(), 100); | strncat(PC.error, PC.cclass->base_class()->name().cstr(), 100); |
| strcat(PC.error, "'"); | strcat(PC.error, "'"); |
| YYERROR; | YYERROR; |
| } | } |
| if(strings_code->count()==1*2) { | if(strings_code->count()==1*2) { |
| StringPtr base_name=LA2S(*strings_code); | const String& base_name=*LA2S(*strings_code); |
| if(ValuePtr base_class_value=PC.request->classes().get(base_name)) { | if(Value* base_class_value=PC.request.classes().get(base_name)) { |
| // @CLASS == @BASE sanity check | // @CLASS == @BASE sanity check |
| if(VStateless_class *base_class=base_class_value->get_class()) { | if(VStateless_class *base_class=base_class_value->get_class()) { |
| if(PC.cclass==base_class) { | if(PC.cclass==base_class) { |
| Line 178 control_method: '@' STRING '\n' | Line 178 control_method: '@' STRING '\n' |
| } | } |
| PC.cclass->get_class()->set_base(base_class); | PC.cclass->get_class()->set_base(base_class); |
| } else { // they asked to derive from a class without methods ['env' & co] | } else { // they asked to derive from a class without methods ['env' & co] |
| strcpy(PC.error, base_name->cstr()); | strcpy(PC.error, base_name.cstr()); |
| strcat(PC.error, ": you can not derive from this class in @"BASE_NAME); | strcat(PC.error, ": you can not derive from this class in @"BASE_NAME); |
| YYERROR; | YYERROR; |
| } | } |
| } else { | } else { |
| strcpy(PC.error, base_name->cstr()); | strcpy(PC.error, base_name.cstr()); |
| strcat(PC.error, ": undefined class in @"BASE_NAME); | strcat(PC.error, ": undefined class in @"BASE_NAME); |
| YYERROR; | YYERROR; |
| } | } |
| Line 193 control_method: '@' STRING '\n' | Line 193 control_method: '@' STRING '\n' |
| } | } |
| } else { | } else { |
| strcpy(PC.error, "'"); | strcpy(PC.error, "'"); |
| strncat(PC.error, command->cstr(), MAX_STRING/2); | strncat(PC.error, command.cstr(), MAX_STRING/2); |
| strcat(PC.error, "' invalid special name. valid names are " | strcat(PC.error, "' invalid special name. valid names are " |
| "'"CLASS_NAME"', '"USE_CONTROL_METHOD_NAME"' and '"BASE_NAME"'"); | "'"CLASS_NAME"', '"USE_CONTROL_METHOD_NAME"' and '"BASE_NAME"'"); |
| YYERROR; | YYERROR; |
| Line 206 maybe_string: empty | STRING; | Line 206 maybe_string: empty | STRING; |
| code_method: '@' STRING bracketed_maybe_strings maybe_bracketed_strings maybe_comment '\n' | code_method: '@' STRING bracketed_maybe_strings maybe_bracketed_strings maybe_comment '\n' |
| maybe_codes { | maybe_codes { |
| StringPtr name=LA2S(*$2); | const String& name=*LA2S(*$2); |
| YYSTYPE params_names_code=$3; | YYSTYPE params_names_code=$3; |
| ArrayStringPtr params_names; | ArrayString* params_names=0; |
| if(int size=params_names_code->count()) { | if(int size=params_names_code->count()) { |
| params_names=ArrayStringPtr(new ArrayString); | params_names=new ArrayString; |
| for(int i=0; i<size; i+=2) | for(int i=0; i<size; i+=2) |
| *params_names+=LA2S(*params_names_code, i); | *params_names+=LA2S(*params_names_code, i); |
| } | } |
| YYSTYPE locals_names_code=$4; | YYSTYPE locals_names_code=$4; |
| ArrayStringPtr locals_names; | ArrayString* locals_names=0; |
| if(int size=locals_names_code->count()) { | if(int size=locals_names_code->count()) { |
| locals_names=ArrayStringPtr(new ArrayString); | locals_names=new ArrayString; |
| for(int i=0; i<size; i+=2) | for(int i=0; i<size; i+=2) |
| *locals_names+=LA2S(*locals_names_code, i); | *locals_names+=LA2S(*locals_names_code, i); |
| } | } |
| MethodPtr method(new Method( | Method& method=*new Method( |
| name, | //name, |
| Method::CT_ANY, | Method::CT_ANY, |
| 0, 0/*min,max numbered_params_count*/, | 0, 0/*min,max numbered_params_count*/, |
| params_names, locals_names, | params_names, locals_names, |
| $7, 0)); | $7, 0); |
| PC.cclass->add_method(name, method); | PC.cclass->add_method(name, method); |
| }; | }; |
| Line 265 name_without_curly_rdive: | Line 265 name_without_curly_rdive: |
| | name_without_curly_rdive_class; | | name_without_curly_rdive_class; |
| name_without_curly_rdive_read: name_without_curly_rdive_code { | name_without_curly_rdive_read: name_without_curly_rdive_code { |
| $$=N(); | $$=N(); |
| ArrayOperationPtr diving_code=$1; | ArrayOperation* diving_code=$1; |
| StringPtr first_name=LA2S(*diving_code); | const String* first_name=LA2S(*diving_code); |
| // self.xxx... -> xxx... | // self.xxx... -> xxx... |
| // OP_VALUE+string+OP_GET_ELEMENT+... -> OP_WITH_SELF+... | // OP_VALUE+string+OP_GET_ELEMENT+... -> OP_WITH_SELF+... |
| if(first_name && *first_name==SELF_ELEMENT_NAME) { | if(first_name && *first_name==SELF_ELEMENT_NAME) { |
| Line 300 name_expr_wdive: | Line 300 name_expr_wdive: |
| | name_expr_wdive_class; | | name_expr_wdive_class; |
| name_expr_wdive_root: name_expr_dive_code { | name_expr_wdive_root: name_expr_dive_code { |
| $$=N(); | $$=N(); |
| ArrayOperationPtr diving_code=$1; | ArrayOperation* diving_code=$1; |
| StringPtr first_name=LA2S(*diving_code); | const String* first_name=LA2S(*diving_code); |
| // $self.xxx... -> $xxx... | // $self.xxx... -> $xxx... |
| // OP_VALUE+string+OP_GET_ELEMENT+... -> OP_WITH_SELF+... | // OP_VALUE+string+OP_GET_ELEMENT+... -> OP_WITH_SELF+... |
| if(first_name && *first_name==SELF_ELEMENT_NAME) { | if(first_name && *first_name==SELF_ELEMENT_NAME) { |
| Line 380 call_value: '^' { | Line 380 call_value: '^' { |
| YYSTYPE params_code=$5; | YYSTYPE params_code=$5; |
| if(params_code->count()==3) { // probably [] case. [OP_VALUE + Void + STORE_PARAM] | if(params_code->count()==3) { // probably [] case. [OP_VALUE + Void + STORE_PARAM] |
| if(ValuePtr value=LA2V(*params_code)) // it is OP_VALUE + value? | if(Value* value=LA2V(*params_code)) // it is OP_VALUE + value? |
| if(!value->is_defined()) // value is VVoid? | if(!value->is_defined()) // value is VVoid? |
| params_code=YYSTYPE(0); // ^zzz[] case. don't append lone empty param. | params_code=0; // ^zzz[] case. don't append lone empty param. |
| } | } |
| /* stack: context, method_junction */ | /* stack: context, method_junction */ |
| OA(*$$, OP_CALL, params_code); // method_frame=make frame(pop junction); ncontext=pop; call(ncontext,method_frame) stack: value | OA(*$$, OP_CALL, params_code); // method_frame=make frame(pop junction); ncontext=pop; call(ncontext,method_frame) stack: value |
| Line 467 name_expr_subvar_value: '$' subvar_ref_n | Line 467 name_expr_subvar_value: '$' subvar_ref_n |
| O(*$$, OP_GET_ELEMENT); | O(*$$, OP_GET_ELEMENT); |
| }; | }; |
| name_expr_with_subvar_value: STRING subvar_get_writes { | name_expr_with_subvar_value: STRING subvar_get_writes { |
| ArrayOperationPtr code; | ArrayOperation* code; |
| { | { |
| change_string_literal_to_write_string_literal(*(code=$1)); | change_string_literal_to_write_string_literal(*(code=$1)); |
| P(*code, *$2); | P(*code, *$2); |
| Line 585 write_string: STRING { | Line 585 write_string: STRING { |
| change_string_literal_to_write_string_literal(*($$=$1)) | change_string_literal_to_write_string_literal(*($$=$1)) |
| }; | }; |
| void_value: /* empty */ { $$=VL(ValuePtr(new VVoid())) }; | void_value: /* empty */ { $$=VL(new VVoid()) }; |
| empty: /* empty */ { $$=N() }; | empty: /* empty */ { $$=N() }; |
| %% | %% |
| Line 676 default: | Line 676 default: |
| case '"': case ':': | case '"': case ':': |
| if(end!=begin) { | if(end!=begin) { |
| // append piece till ^ | // append piece till ^ |
| PC.string->APPEND_CLEAN(begin, end-begin, PC.file, begin_line); | PC.string.append(begin, end-begin); |
| } | } |
| // reset piece 'begin' position & line | // reset piece 'begin' position & line |
| begin=PC.source; // ->punctuation | begin=PC.source; // ->punctuation |
| Line 690 default: | Line 690 default: |
| case '#': | case '#': |
| if(end!=begin) { | if(end!=begin) { |
| // append piece till ^ | // append piece till ^ |
| PC.string->APPEND_CLEAN(begin, end-begin, PC.file, begin_line); | PC.string.append(begin, end-begin); |
| } | } |
| // #HH ? | // #HH ? |
| if(PC.source[0]=='#' && PC.source[1] && PC.source[2]) { | if(PC.source[0]=='#' && PC.source[1] && PC.source[2]) { |
| char *hex=(char *)POOL.malloc(1); | char c= |
| hex[0]= | |
| hex_value[(unsigned char)PC.source[1]]*0x10+ | hex_value[(unsigned char)PC.source[1]]*0x10+ |
| hex_value[(unsigned char)PC.source[2]]; | hex_value[(unsigned char)PC.source[2]]; |
| if(hex[0]==0) { | if(c==0) { |
| result=BAD_HEX_LITERAL; | result=BAD_HEX_LITERAL; |
| goto break2; // wrong hex value[no ^#00 chars allowed]: bail out | goto break2; // wrong hex value[no ^#00 chars allowed]: bail out |
| } | } |
| // append char(hex(HH)) | // append char(hex(HH)) |
| PC.string->APPEND_CLEAN(hex, 1, PC.file, begin_line); | PC.string.append(c); |
| // skip over ^#HH | // skip over ^#HH |
| PC.source+=3; | PC.source+=3; |
| PC.col+=3; | PC.col+=3; |
| Line 722 default: | Line 721 default: |
| if(c=='#' && PC.col==1) { | if(c=='#' && PC.col==1) { |
| if(end!=begin) { | if(end!=begin) { |
| // append piece till # | // append piece till # |
| PC.string->APPEND_CLEAN(begin, end-begin, PC.file, begin_line); | PC.string.append(begin, end-begin); |
| } | } |
| // fall into COMMENT lexical state [wait for \n] | // fall into COMMENT lexical state [wait for \n] |
| push_LS(PC, LS_USER_COMMENT); | push_LS(PC, LS_USER_COMMENT); |
| Line 865 default: | Line 864 default: |
| case '#': // comment start skipping | case '#': // comment start skipping |
| if(end!=begin) { | if(end!=begin) { |
| // append piece till # | // append piece till # |
| PC.string->APPEND_CLEAN(begin, end-begin, PC.file, begin_line); | PC.string.append(begin, end-begin); |
| } | } |
| // fall into COMMENT lexical state [wait for \n] | // fall into COMMENT lexical state [wait for \n] |
| push_LS(PC, LS_EXPRESSION_COMMENT); | push_LS(PC, LS_EXPRESSION_COMMENT); |
| Line 1297 break2: | Line 1296 break2: |
| } | } |
| if(end!=begin && PC.ls!=LS_USER_COMMENT) { // last piece still alive and not comment? | if(end!=begin && PC.ls!=LS_USER_COMMENT) { // last piece still alive and not comment? |
| // append it | // append it |
| PC.string->APPEND_CLEAN(begin, end-begin, PC.file, begin_line/*, start_col*/); | PC.string.append(begin, end-begin); |
| } | } |
| } | } |
| if(PC.string->size()) { // something accumulated? | if(!PC.string.is_empty()) { // something accumulated? |
| // create STRING value: array of OP_VALUE+vstring | // create STRING value: array of OP_VALUE+vstring |
| *lvalp=VL(ValuePtr(new VString(PC.string))); | *lvalp=VL(new VString(*new String(PC.string, String::L_CLEAN))); |
| // new pieces storage | // new pieces storage |
| PC.string=StringPtr(new String); | PC.string.clear(); |
| // make current result be pending for next call, return STRING for now | // make current result be pending for next call, return STRING for now |
| PC.pending_state=result; result=STRING; | PC.pending_state=result; result=STRING; |
| } | } |
| Line 1321 static int real_yyerror(parse_control *p | Line 1320 static int real_yyerror(parse_control *p |
| static void yyprint(FILE *file, int type, YYSTYPE value) { | static void yyprint(FILE *file, int type, YYSTYPE value) { |
| if(type==STRING) | if(type==STRING) |
| fprintf(file, " \"%s\"", LA2S(*value)->cstr().get()); | fprintf(file, " \"%s\"", LA2S(*value)->cstr()); |
| } | } |