|
|
| version 1.81.2.6, 2003/01/31 16:05:58 | version 1.81.2.13.2.10, 2003/03/24 14:53:56 |
|---|---|
| Line 57 | Line 57 |
| -#: 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 82 static int yylex(YYSTYPE *lvalp, void *p | Line 82 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 |
| #ifndef YYSTYPE | #ifndef YYSTYPE |
| #define YYSTYPE int | #define YYSTYPE int |
| Line 1034 yyreduce: | Line 1034 yyreduce: |
| case 1: | case 1: |
| #line 116 "compile.y" | #line 116 "compile.y" |
| { | { |
| 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*/, |
| yyvsp[0]/*parser_code*/, 0/*native_code*/)); | yyvsp[0]/*parser_code*/, 0/*native_code*/); |
| PC.cclass->add_method(main_method_name, method); | PC.cclass->add_method(main_method_name, method); |
| ; | ; |
| break;} | break;} |
| case 8: | case 8: |
| #line 131 "compile.y" | #line 131 "compile.y" |
| { | { |
| StringPtr command=LA2S(*yyvsp[-2]); | const String& command=*LA2S(*yyvsp[-2]); |
| YYSTYPE strings_code=yyvsp[0]; | YYSTYPE strings_code=yyvsp[0]; |
| 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 1093 case 8: | Line 1093 case 8: |
| } | } |
| 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 1108 case 8: | Line 1108 case 8: |
| } | } |
| } 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 1122 case 12: | Line 1122 case 12: |
| case 16: | case 16: |
| #line 208 "compile.y" | #line 208 "compile.y" |
| { | { |
| StringPtr name=LA2S(*yyvsp[-5]); | const String& name=*LA2S(*yyvsp[-5]); |
| YYSTYPE params_names_code=yyvsp[-4]; | YYSTYPE params_names_code=yyvsp[-4]; |
| 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=yyvsp[-3]; | YYSTYPE locals_names_code=yyvsp[-3]; |
| 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, |
| yyvsp[0], 0)); | yyvsp[0], 0); |
| PC.cclass->add_method(name, method); | PC.cclass->add_method(name, method); |
| ; | ; |
| break;} | break;} |
| Line 1183 case 42: | Line 1183 case 42: |
| #line 266 "compile.y" | #line 266 "compile.y" |
| { | { |
| yyval=N(); | yyval=N(); |
| ArrayOperationPtr diving_code=yyvsp[0]; | ArrayOperation* diving_code=yyvsp[0]; |
| 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 1223 case 50: | Line 1223 case 50: |
| #line 301 "compile.y" | #line 301 "compile.y" |
| { | { |
| yyval=N(); | yyval=N(); |
| ArrayOperationPtr diving_code=yyvsp[0]; | ArrayOperation* diving_code=yyvsp[0]; |
| 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 1318 case 69: | Line 1318 case 69: |
| YYSTYPE params_code=yyvsp[-1]; | YYSTYPE params_code=yyvsp[-1]; |
| 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(*yyval, OP_CALL, params_code); // method_frame=make frame(pop junction); ncontext=pop; call(ncontext,method_frame) stack: value | OA(*yyval, OP_CALL, params_code); // method_frame=make frame(pop junction); ncontext=pop; call(ncontext,method_frame) stack: value |
| Line 1421 case 104: | Line 1421 case 104: |
| case 105: | case 105: |
| #line 469 "compile.y" | #line 469 "compile.y" |
| { | { |
| ArrayOperationPtr code; | ArrayOperation* code; |
| { | { |
| change_string_literal_to_write_string_literal(*(code=yyvsp[-1])); | change_string_literal_to_write_string_literal(*(code=yyvsp[-1])); |
| P(*code, *yyvsp[0]); | P(*code, *yyvsp[0]); |
| Line 1662 case 158: | Line 1662 case 158: |
| break;} | break;} |
| case 159: | case 159: |
| #line 588 "compile.y" | #line 588 "compile.y" |
| { yyval=VL(ValuePtr(new VVoid())) ; | { yyval=VL(new VVoid()) ; |
| break;} | break;} |
| case 160: | case 160: |
| #line 589 "compile.y" | #line 589 "compile.y" |
| Line 1979 default: | Line 1979 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 1993 default: | Line 1993 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 2025 default: | Line 2024 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 2168 default: | Line 2167 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 2600 break2: | Line 2599 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!=CORD_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; |
| } | } |