Changeset 332


Ignore:
Timestamp:
02/28/15 03:42:40 (10 years ago)
Author:
Maciej Komosinski
Message:
  • use source/code mapping for line number and file information in vm error messages
  • mandatory parentheses in typeof()
  • int() float() string() added
  • typeof() returns plain names of core types instead of numeric constants
short-circuit evaluation of && and
  • fixed switch/case fall through (previously each case not ending with break jumped to default: (when present))
  • case labels do not have to be constant
Location:
cpp/frams/vm
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/vm/framscript.l

    r224 r332  
    3333\"\"\"             {trctx.tmp=""; trctx.multilimit='\"'; BEGIN multiline;}
    3434"'''"              {trctx.tmp=""; trctx.multilimit='\''; BEGIN multiline;}
    35 "@line "[0-9]+\n   {trctx.line=atol(yytext+6);}
    36 "@file "[^\n\t\r]+\n {trctx.srcname=SString(yytext+6,yyleng-7);}
     35"@line "[0-9]+\n   {trctx.line=atol(yytext+6);trctx.linechanged=true;}
     36"@file "[^\n\t\r]+\n {trctx.srcname=SString(yytext+6,yyleng-7);trctx.namechanged=true;}
    3737
    3838[a-zA-Z_][a-zA-Z0-9_]* { int t=lookupToken(yytext);
     
    6565">>"                return RSHIFT;
    6666
    67 <INITIAL,asmcode,asmcode2>\/\/.*\n         {trctx.line++;} // komentarz jednoliniowy
     67<INITIAL,asmcode,asmcode2>\/\/.*\n         {trctx.line++;trctx.linechanged=true;} // komentarz jednoliniowy
    6868<INITIAL,asmcode,asmcode2>\/\/[^\n]*       ;               // komentarz ale nie ma potem \n
    6969
    7070<INITIAL>\/\*       BEGIN comment;
    71 <comment>\n         {trctx.line++;}
     71<comment>\n         {trctx.line++;trctx.linechanged=true;}
    7272<comment>\*\/       BEGIN 0;
    7373<comment>.          ;
     
    8585                       trctx.tmp+=SString(yytext,yyleng);
    8686                    }
    87 <multiline>\n       {trctx.line++; trctx.tmp+="\n";}
     87<multiline>\n       {trctx.line++; trctx.linechanged=true; trctx.tmp+="\n";}
    8888[ \t\r\f]           ;
    89 \n                  {trctx.line++;}
     89\n                  {trctx.line++; trctx.linechanged=true;}
    9090.                   return yytext[0];
    9191
     
    9494                    char *t=yytext;
    9595                    while(t=strchr(t+1,'\n')) trctx.line++;
     96                    trctx.linechanged=true;
    9697                    return ASM;
    9798                    }
    9899<asmcode>.*\n {
    99100              char *t=yytext;
    100               trctx.line++;
     101              trctx.line++; trctx.linechanged=true;
    101102              while ((*t==' ')||(*t=='\t')) t++;
    102103              if (*t=='}') {yyless((t-yytext)+1); BEGIN 0; return '}';}
  • cpp/frams/vm/framscript.y

    r286 r332  
    1515static void yyprint (FILE *file,int type,YYSTYPE value);
    1616void handleTwoArg(YYSTYPE& result,const YYSTYPE& arg1,const YYSTYPE& arg2,
    17                   int optoken,const char* opname, bool logic, bool negarg2, bool uniq);
    18 void handleCompare(YYSTYPE& result,const YYSTYPE& arg1,const YYSTYPE& arg2,
    19                    int optoken,const char* opname);
     17                  int optoken,const char* opname, bool negarg2, bool uniq);
     18bool handleCompare(YYSTYPE& result,const YYSTYPE& arg1,const YYSTYPE& arg2,
     19                   ExtValue::CmpOperator,const char* opname);
    2020bool handleAssignOp(YYSTYPE& result,const YYSTYPE& var,const YYSTYPE& arg,const char* opname);
    2121bool handleAssignOp2(YYSTYPE& result,const char *var,const YYSTYPE& arg,const char* opname,int stackpos,bool push);
     
    4646%left NEG     /* negation--unary minus */
    4747%left TYPEOF
     48%left INT
     49%left FLOAT
     50%left STRING
    4851
    4952%token IDENT
     
    6568
    6669%token TYPEOF    "typeof"
     70%token INT       "int"
     71%token FLOAT     "float"
     72%token STRING    "string"
    6773
    6874%token ASM     
     
    111117      | GLOBAL globaldeflist ';'
    112118      | IDENT ':'     {trctx.out->printf(":%s\n",str($1));}
    113       | expr ';'      {if (!$1.constant) { trctx.out->printf("inc m0\n"); trstack.adjust(+1); } }
     119      | expr ';'      {if (!$1.constant) { trctx.out->printf("inc m0\n"); trstack.adjust(+1); } trctx.emitLine(); }
    114120      | functiondef
    115121      | blok
     
    138144 {
    139145#ifdef FRAMSCRIPT_GOTO
    140 trctx.out->printf("jump :%s\n",str($2)); FMprintf("FramScriptCompiler","translate",FMLV_WARN,"goto is not recommended (%s line %d)",(const char*)trctx.srcname,trctx.line);
     146trctx.out->printf("jump :%s\n",str($2)); FMprintf("FramScriptCompiler","translate",FMLV_WARN,"goto is not recommended (%s line %d)",(const char*)trctx.srcname,trctx.line); trctx.emitLine();
    141147#else
    142148trctx.err->printf("goto is not supported\n");return 1;
     
    183189else
    184190        offset=trctx.functionstackpos-trstack.currentPos();
     191trctx.emitLine();
    185192if (!offset)
    186193        trctx.out->printf("move invalid,s0\nreturn\n");
     
    194201;
    195202
    196 vardef: IDENT               {trstack.addVariable($1.getString()); trctx.out->printf("push invalid\n");}
    197       | IDENT '=' stackexpr {trstack.adjust(1); trstack.addVariable($1.getString());}
     203vardef: IDENT               { trctx.emitLine(); trstack.addVariable($1.getString()); trctx.out->printf("push invalid\n");}
     204      | IDENT '=' stackexpr { trctx.emitLine(); trstack.adjust(1); trstack.addVariable($1.getString());}
    198205;
    199206
     
    220227functiondef:                FUNCTION funnamelist
    221228{
     229trctx.emitLine();
    222230int pos=trstack.currentPos();
    223231$$.setInt(pos);
     
    236244trctx.out->printf(":_skipfun_%d\n",trctx.functiontmplabel);
    237245trctx.functiontmplabel=-1;
     246trctx.emitLine();
    238247};
    239248
     
    241250               | BREAK expr ';'
    242251{
     252trctx.emitLine();
    243253if (!$2.constant)
    244254        {trctx.err->printf("break level must be a constant expression\n");return 1;}
     
    247257        {trctx.err->printf("break level must be a positive integer\n");return 1;}
    248258if (!doBreak(level)) return 1;
     259trctx.emitLine();
    249260};
    250261
     
    258269        {trctx.err->printf("continue level must be a positive integer\n");return 1;}
    259270if (!doContinue(level)) return 1;
     271trctx.emitLine();
    260272};
    261273
    262274while_statement: WHILE '('
    263 { int c=trctx.labelcounter++; $$.setInt(c);
     275{
     276int c=trctx.labelcounter++; $$.setInt(c);
    264277$$.stack=trstack.currentPos();
    265278trstack.loops.addLoop(c,$$.stack);
     
    273286else
    274287        {
    275         trctx.out->printf("if m[m0++],==,0,:_loop_end_%d\n",c,c);
     288        trctx.out->printf("if ~=,m[m0++],:_loop_end_%d\n",c,c);
    276289        trstack.adjust(+1);
    277290        }
    278291}
    279292                 pseudoblok_statement
    280 {trctx.out->printf("jump :_loop_%d\n:_loop_end_%d\n",$3.getInt(),$3.getInt());
     293{
     294trctx.out->printf("jump :_loop_%d\n:_loop_end_%d\n",$3.getInt(),$3.getInt());
    281295trstack.adjust($3.stack-trstack.currentPos());
    282296trstack.loops.drop();
     
    285299
    286300dowhile_statement: DO
    287 { int c=trctx.labelcounter++; $$.setInt(c);
     301{
     302trctx.emitLine();
     303int c=trctx.labelcounter++; $$.setInt(c);
    288304$$.stack=trstack.currentPos();
    289305trstack.loops.addLoop(c,$$.stack);
     
    299315else
    300316        {
    301         trctx.out->printf("if !=,m[m0++],:_loop_%d\n",c);
     317        trctx.out->printf("if !~,m[m0++],:_loop_%d\n",c);
    302318        trstack.adjust(+1);
    303319        }
     
    305321trstack.adjust($2.stack-trstack.currentPos());
    306322trstack.loops.drop();
     323trctx.emitLine();
    307324}
    308325;
    309326
    310327switch_statement: SWITCH '('
    311 {int c=trctx.labelcounter++; $1.setInt(c);
     328{
     329int c=trctx.labelcounter++; $1.setInt(c);
    312330trstack.loops.addLoop(c,trstack.currentPos());}
    313331       stackexpr ')'
    314 {trctx.out->printf("dec m0\n");trstack.adjust(-1);}
     332{trctx.emitLine(); trctx.out->printf("dec m0\n"); trstack.adjust(-1);}
    315333 '{' inside_switch '}'
    316 {int c=$1.getInt(); trctx.out->printf("add 2,m0\n:_loop_end_%d\n",c); trstack.adjust(+2);
    317 trstack.loops.drop();}
     334{
     335trctx.emitLine();
     336LoopInfo *li=trstack.loops.getLoop(0);
     337trctx.out->printf(":_case_after_%d_%d\n"
     338                  "add 2,m0\n"
     339                  ":_loop_end_%d\n",
     340                  li->id,li->casecounter,
     341                  li->id);
     342trstack.adjust(+2);
     343trstack.loops.drop();
     344}
    318345;
    319346
     
    324351
    325352case_label: CASE expr ':'
    326 {if (!$2.constant) {trctx.err->printf("case label must be a constant expression\n");return 1;}
    327 int c=trctx.labelcounter++; $1.setInt(c);
    328 trctx.out->printf("if s1,!=,%s,:_skip_%d\n",litstr($2),c);
     353{
     354LoopInfo *li=trstack.loops.getLoop(0);
     355if ($2.constant)
     356        trctx.out->printf("if s1,!=,%s,:_case_before_%d_%d\n",
     357                          litstr($2),
     358                          li->id,li->casecounter+1);
     359else
     360        {
     361        trctx.out->printf("if s2,!=,m[m0++],:_case_before_%d_%d\n",
     362                          li->id,li->casecounter+1);
     363        trstack.adjust(+1);
     364        }
     365trctx.out->printf(":_case_after_%d_%d\n",
     366                  li->id,li->casecounter);
    329367int pos=trstack.currentPos(); $$.setInt(pos);
    330368}
    331369 recurcode
    332370{
     371trctx.emitLine();
     372LoopInfo *li=trstack.loops.getLoop(0);
    333373int pos=$4.getInt();
    334374if (pos!=trstack.currentPos()) trctx.out->printf("add %d,m0\n",pos-trstack.currentPos());
    335375trstack.dropToPos(pos);
    336 trctx.out->printf(":_skip_%d\n",$1.getInt());
    337 }
    338       |  DEFAULT ':' recurcode
     376li->casecounter++;
     377trctx.out->printf("jump :_case_after_%d_%d\n"
     378                  ":_case_before_%d_%d\n",
     379                  li->id,li->casecounter,
     380                  li->id,li->casecounter);
     381}
     382      |  DEFAULT ':'
     383  {
     384  LoopInfo *li=trstack.loops.getLoop(0);
     385  trctx.out->printf(":_case_after_%d_%d\n",li->id,li->casecounter);
     386  }
     387  recurcode
     388  {
     389  LoopInfo *li=trstack.loops.getLoop(0);
     390  li->casecounter++;
     391  }
    339392;
    340393
     
    409462           expr_or_objname ')'
    410463           {//6
     464           trctx.emitLine();
    411465           if ($4.constant)
    412466                   {trctx.err->printf("%s can't be iterated\n",str($4)); return 1;}
     
    439493           for_statement_begin ';'
    440494           { //3
     495           trctx.emitLine();
    441496           //trctx.out->printf("# for_statement_begin pos=%d ident=%d var=%d\n",trstack.currentPos(),$1.ident,$1.var);
    442497           if ((!$1.var) && ($1.ident))
     
    460515           expr_or_empty ';'
    461516           { //6
     517           trctx.emitLine();
    462518           int c=$1.counter;
    463519           warnTruthValue($4);
     
    475531           expr_or_empty ')'
    476532           { //9
     533           trctx.emitLine();
    477534           if (!$7.constant) { trctx.out->printf("inc m0\n"); trstack.adjust(+1); }
    478535           trctx.restoreOut();
     
    498555
    499556pseudoblok_statement:
    500 {int pos=trstack.currentPos(); $$.setInt(pos);
    501 }
     557{trctx.emitLine(); int pos=trstack.currentPos(); $$.setInt(pos);}
    502558  statement
    503559{
     
    505561if (pos!=trstack.currentPos()) trctx.out->printf("add %d,m0\n",pos-trstack.currentPos());
    506562trstack.dropToPos(pos);
     563trctx.emitLine();
    507564};
    508565
     
    535592
    536593if_condition: IF
    537 {$$.stack=trstack.currentPos();}
     594{$$.stack=trstack.currentPos();trctx.emitLine();}
    538595
    539596 '(' expr ')'
    540597{
     598trctx.emitLine();
    541599int c=trctx.labelcounter++;
    542600$$.setInt(c);
     
    548606else
    549607        {
    550         trctx.out->printf("if m[m0++],==,0,:_if_else_%d\n",c);
     608        trctx.out->printf("if ~=,m[m0++],:_if_else_%d\n",c);
    551609        trstack.adjust(+1);
    552610        }
     
    585643  else
    586644          {$$=$1; $$.ident=false;}
     645  trctx.emitLine();
    587646  }
    588647;
     
    606665       | plusminus IDENT
    607666{
     667trctx.emitLine();
    608668$$.ident=0;
    609669int loc; if (variableOk($$,$2,loc))
     
    619679       | IDENT plusminus
    620680{
     681trctx.emitLine();
    621682$$.ident=0;
    622683int loc; if (variableOk($$,$1,loc))
     
    630691}
    631692
    632        | IDENT assign_op expr { $$.ident=0;
     693       | IDENT assign_op expr { trctx.emitLine(); $$.ident=0;
    633694                                if (!handleAssignOp($$,$1,$3,assign_op_names[$2.getInt()]))
    634695                                if (globalOk($1)) {SString t="@"; t+=$1.getString();
     
    637698                              }
    638699
    639        | TYPEOF expr { $$.ident=0;
    640                        if ($2.constant)
    641                              {$$.constant=1; $$=$2.getExtType();}
     700       | TYPEOF '(' expr ')' { trctx.emitLine(); $$.ident=0;
     701                       if ($3.constant)
     702                             {$$.constant=1; $$=$3.getExtType();}
    642703                       else
    643704                             {trctx.out->printf("type s0,s0\n");}
    644705                     }
    645 
    646        | expr '+' expr { handleTwoArg($$,$1,$3,'+',"add",0,0,1); }
    647        | expr '-' expr { handleTwoArg($$,$1,$3,'-',"sub",0,0,0); }
    648        | expr '*' expr { handleTwoArg($$,$1,$3,'*',"mul",0,0,1); }
    649        | expr '/' expr { handleTwoArg($$,$1,$3,'/',"div",0,0,0); }
    650        | expr '&' expr { handleTwoArg($$,$1,$3,'&',"and",0,0,0); }
    651        | expr '|' expr { handleTwoArg($$,$1,$3,'|',"or",0,0,0); }
    652        | expr '%' expr { handleTwoArg($$,$1,$3,'%',"mod",0,0,0); }
    653        | expr LOGIC_AND expr { handleTwoArg($$,$1,$3,LOGIC_AND,"and",1,0,0); }
    654        | expr LOGIC_OR expr { handleTwoArg($$,$1,$3,LOGIC_OR,"or",1,0,0); }
    655        | expr LSHIFT expr { handleTwoArg($$,$1,$3,LSHIFT,"shift",0,0,0); }
    656        | expr RSHIFT expr { handleTwoArg($$,$1,$3,RSHIFT,"shift",0,1,0); }
    657        | expr EQUAL expr     { handleCompare($$,$1,$3,EQUAL,"=="); }
    658        | expr NOT_EQUAL expr { handleCompare($$,$1,$3,NOT_EQUAL,"!="); }
    659        | expr GEQUAL expr    { handleCompare($$,$1,$3,GEQUAL,">="); }
    660        | expr LEQUAL expr    { handleCompare($$,$1,$3,LEQUAL,"<="); }
    661        | expr '>' expr       { handleCompare($$,$1,$3,'>',">"); }
    662        | expr '<' expr       { handleCompare($$,$1,$3,'<',"<"); }
     706       | INT '(' expr ')' { trctx.emitLine(); $$.ident=0;
     707                       if ($3.constant)
     708                             {$$.constant=1; $$=ExtValue($3.getInt());}
     709                       else
     710                             {trctx.out->printf("conv 1,s0\n");}
     711                     }
     712       | FLOAT '(' expr ')' { trctx.emitLine(); $$.ident=0;
     713                       if ($3.constant)
     714                             {$$.constant=1; $$=ExtValue($3.getDouble());}
     715                       else
     716                             {trctx.out->printf("conv 2,s0\n");}
     717                     }
     718       | STRING '(' expr ')' { trctx.emitLine(); $$.ident=0;
     719                       if ($3.constant)
     720                             {$$.constant=1; $$=ExtValue($3.getString());}
     721                       else
     722                             {trctx.out->printf("conv 3,s0\n");}
     723                     }
     724
     725       | expr '+' expr { handleTwoArg($$,$1,$3,'+',"add",0,1); }
     726       | expr '-' expr { handleTwoArg($$,$1,$3,'-',"sub",0,0); }
     727       | expr '*' expr { handleTwoArg($$,$1,$3,'*',"mul",0,1); }
     728       | expr '/' expr { handleTwoArg($$,$1,$3,'/',"div",0,0); }
     729       | expr '&' expr { handleTwoArg($$,$1,$3,'&',"and",0,0); }
     730       | expr '|' expr { handleTwoArg($$,$1,$3,'|',"or",0,0); }
     731       | expr '%' expr { handleTwoArg($$,$1,$3,'%',"mod",0,0); }
     732
     733       | expr LOGIC_AND
     734 {
     735 // a && b:
     736 //   push a
     737 //   if (a)
     738 //     pop; goto and_b
     739 //   else
     740 //     pop; push 0; goto and_end
     741 // and_b:
     742 //   push b
     743 // and_end:
     744 trctx.emitLine();
     745// trctx.out->printf("\n####### logic AND\n");
     746 int c=trctx.labelcounter++;
     747 $$.setInt(c);
     748 if ($1.constant)
     749         {
     750         int cond=$1.compare(ExtValue::zero());
     751         if ((cond==0)||(cond==2))
     752                 {
     753                 $1.counter=0;
     754                 // no stack adjust - next tokens are processed in a different context
     755                 trctx.out->printf("push 0\njump :_and_end_%d\n",c);
     756                 }
     757         else
     758                 $1.counter=1;
     759         }
     760 else
     761         {
     762         trstack.adjust(+1); // stack as if (a==true), b expr is processed
     763         trctx.out->printf("if !~,m[m0++],:_and_b_%d\n"
     764                           "push 0\n"
     765                           "jump :_and_end_%d\n"
     766                           ":_and_b_%d\n"
     767                           ,c,c,c);
     768         }
     769 }
     770         expr
     771 {
     772 $$.ident=false;
     773 $$.constant=0;
     774 if ($4.constant)
     775         {
     776         if (!($1.constant && $1.counter==0))
     777                 {
     778                 int cond=$4.compare(ExtValue::zero());
     779                 bool value=!((cond==0)||(cond==2));
     780                 trstack.adjust(-1);
     781                 trctx.out->printf("push %d\n",value);
     782                 }
     783         }
     784 trctx.out->printf(":_and_end_%d\n",$3.getInt());
     785// trctx.out->printf("#################\n\n");
     786 }
     787
     788       | expr LOGIC_OR
     789 {
     790 // a || b:
     791 //   push a
     792 //   if (!a)
     793 //     pop; goto and_b
     794 //   else
     795 //     pop; push 1; goto and_end
     796 // and_b:
     797 //   push b
     798 // and_end:
     799 trctx.emitLine();
     800// trctx.out->printf("\n####### logic AND\n");
     801 int c=trctx.labelcounter++;
     802 $$.setInt(c);
     803 if ($1.constant)
     804         {
     805         int cond=$1.compare(ExtValue::zero());
     806         if (!((cond==0)||(cond==2)))
     807                 {
     808                 $1.counter=1;
     809                 // no stack adjust - next tokens are processed in a different context
     810                 trctx.out->printf("push 1\njump :_or_end_%d\n",c);
     811                 }
     812         else
     813                 $1.counter=0;
     814         }
     815 else
     816         {
     817         trstack.adjust(+1); // stack for (a==false)
     818         trctx.out->printf("if ~=,m[m0++],:_or_b_%d\n"
     819                           "push 1\n"
     820                           "jump :_or_end_%d\n"
     821                           ":_or_b_%d\n"
     822                           ,c,c,c);
     823         }
     824 }
     825         expr
     826 {
     827 $$.ident=false;
     828 $$.constant=0;
     829 if ($4.constant)
     830         {
     831         if (!($1.constant && $1.counter==1))
     832                 {
     833                 int cond=$4.compare(ExtValue::zero());
     834                 bool value=!((cond==0)||(cond==2));
     835                 trstack.adjust(-1);
     836                 trctx.out->printf("push %d\n",value);
     837                 }
     838         }
     839 trctx.out->printf(":_or_end_%d\n",$3.getInt());
     840// trctx.out->printf("#################\n\n");
     841 }
     842
     843
     844       | expr LSHIFT expr { handleTwoArg($$,$1,$3,LSHIFT,"shift",0,0); }
     845       | expr RSHIFT expr { handleTwoArg($$,$1,$3,RSHIFT,"shift",1,0); }
     846       | expr EQUAL expr     { if (!handleCompare($$,$1,$3,ExtValue::CmpEQ,"==")) return 1; }
     847       | expr NOT_EQUAL expr { if (!handleCompare($$,$1,$3,ExtValue::CmpNE,"!=")) return 1; }
     848       | expr GEQUAL expr    { if (!handleCompare($$,$1,$3,ExtValue::CmpGE,">=")) return 1; }
     849       | expr LEQUAL expr    { if (!handleCompare($$,$1,$3,ExtValue::CmpLE,"<=")) return 1; }
     850       | expr '>' expr       { if (!handleCompare($$,$1,$3,ExtValue::CmpGT,">")) return 1; }
     851       | expr '<' expr       { if (!handleCompare($$,$1,$3,ExtValue::CmpLT,"<")) return 1; }
    663852
    664853       | '!' expr        {
    665                          $$.assign=$2.assign; $$.parens=0; $$.ident=0;
     854                         trctx.emitLine(); $$.assign=$2.assign; $$.parens=0; $$.ident=0;
    666855                         if ($2.constant)
    667                                 {$$.constant=1; $$.setInt(!$2.getInt());}
     856                                 {$$.constant=1; int res=$2.compare(ExtValue((paInt)0)); $$.setInt((res==0)||(res==2));}
    668857                         else
    669                                 {trctx.out->printf("setif ==,s0,s0\n");}
     858                                {trctx.out->printf("setif ~=,s0,s0\n");}
    670859                         }
    671860
    672861     | '-' expr %prec NEG {
    673                           $$.assign=$2.assign; $$.parens=0; $$.ident=0;
     862                          trctx.emitLine(); $$.assign=$2.assign; $$.parens=0; $$.ident=0;
    674863                          if ($2.constant)
    675864                                  { $$.constant=$2.constant;
     
    685874                          }
    686875
    687      | '(' expr ')'    { $$ = $2; $$.assign=$2.assign?(!$2.parens):0; $$.parens=1; $$.ident=0; }
     876     | '(' expr ')'    { trctx.emitLine(); $$ = $2; $$.assign=$2.assign?(!$2.parens):0; $$.parens=1; $$.ident=0; }
    688877
    689878     | OBJNAME '.' member {
    690                         $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
     879                        trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
    691880                        if ($3.constant)
    692881                                {
     
    700889
    701890     | OBJNAME '.' member assign_op expr
    702                   { $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
     891                  { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
    703892                  if ($3.constant)
    704893                          {
     
    716905
    717906     | plusminus OBJNAME '.' member {
    718                         $$.constant=0; $$.ident=0; SString t=$2.getString(); t+="."; t+=$4.getString(); $$.setString(t);
     907                        trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$2.getString(); t+="."; t+=$4.getString(); $$.setString(t);
    719908                        if ($4.constant)
    720909                                {
     
    731920
    732921     | OBJNAME '.' member plusminus {
    733                         $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
     922                        trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
    734923                        if ($3.constant)
    735924                                {
     
    746935
    747936     | OBJNAME '.' '*'    {
    748                         $$.constant=0; $$.ident=0; SString t=$1.getString(); t+=".*"; $$.setString(t);
     937                        trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$1.getString(); t+=".*"; $$.setString(t);
    749938                        trctx.out->printf("push %s.*\n",str($1)); trstack.adjust(-1);
    750939                        }
     
    752941
    753942     | OBJNAME '.' member '=' expr {
    754                         $$=$5; $$.assign=1; $$.parens=0; $$.ident=0;
     943                        trctx.emitLine(); $$=$5; $$.assign=1; $$.parens=0; $$.ident=0;
    755944                        if ($3.constant)
    756945                                {
     
    779968     | OBJNAME '.' member '(' arguments ')'
    780969                        {
    781                         $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
     970                        trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
    782971                        int adj=0,adj2=0;
    783972                        if ($5.getInt()==0)
     
    799988
    800989     | CALL expr '(' arguments ')'
    801              { $$.constant=0; $$.ident=0; $$.setString($2.getString());
     990             { trctx.emitLine(); $$.constant=0; $$.ident=0; $$.setString($2.getString());
    802991             short adj=0;
    803992             if ($4.getInt()==0)
     
    8151004
    8161005     | FUNCTION IDENT
    817              { $$.constant=0; $$.ident=0; SString t=":"; t+=$1.getString(); $$.setString(t);
     1006             { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=":"; t+=$1.getString(); $$.setString(t);
    8181007             trctx.out->printf("push :%s\n",(const char*)$2.getString());
    8191008             trstack.adjust(-1);
     
    8211010
    8221011     | expr '.' member
    823              { $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
     1012             { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
    8241013             if ($3.constant)
    8251014                     trctx.out->printf("move s0,m1\nmove [m1].%s,s0\n",str($3));
     
    8301019
    8311020     | plusminus expr '.' member
    832              { $$.constant=0; $$.ident=0; SString t=$2.getString(); t+="."; t+=$4.getString(); $$.setString(t);
     1021             { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$2.getString(); t+="."; t+=$4.getString(); $$.setString(t);
    8331022             if ($4.constant)
    8341023                     trctx.out->printf("move s0,m1\n%s [m1].%s\nmove [m1].%s,s0\n",
     
    8411030
    8421031     | expr '.' member plusminus
    843              { $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
     1032             { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
    8441033             if ($3.constant)
    8451034                     trctx.out->printf("move s0,m1\nmove [m1].%s,s0\n%s [m1].%s\n",
     
    8521041
    8531042     | expr '.' member assign_op expr
    854              { $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
     1043             { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
    8551044             if ($3.constant)
    8561045                     {
     
    8801069
    8811070     | expr '.' member '=' stackexpr
    882              { $$=$5; $$.assign=1; $$.parens=0; $$.ident=0;
     1071             { trctx.emitLine(); $$=$5; $$.assign=1; $$.parens=0; $$.ident=0;
    8831072             if ($3.constant)
    8841073                     {
     
    8941083
    8951084     | expr '.' member '(' arguments ')'
    896              { $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
     1085             { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="."; t+=$3.getString(); $$.setString(t);
    8971086             int adj=0;
    8981087             if ($5.getInt()==0)
     
    9171106
    9181107      | expr '[' expr ']' '=' expr    // shortcut: expr.set(expr,expr)
    919              { $$=$6; $$.assign=1; $$.parens=0; $$.ident=0;
     1108             { trctx.emitLine(); $$=$6; $$.assign=1; $$.parens=0; $$.ident=0;
    9201109             if ($3.constant)
    9211110                     {
     
    9351124
    9361125      | expr '[' expr ']'    /* shortcut: expr.get(expr) */
    937              { $$.constant=0; $$.ident=0; SString t=$1.getString(); t+=".get"; $$.setString(t);
     1126             { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$1.getString(); t+=".get"; $$.setString(t);
    9381127             if ($3.constant)
    9391128                     {
     
    9471136             }
    9481137
    949      | IDENT '=' expr { $$=$3; $$.assign=1; $$.ident=0;
     1138     | IDENT '=' expr { trctx.emitLine(); $$=$3; $$.assign=1; $$.ident=0;
    9501139                        int loc=trstack.getVariableLocation($1.getString());
    9511140                        if (loc!=TranslatorStack::NOTFOUND)
     
    9631152
    9641153      | OBJNAME '[' expr ']'    /* shortcut: OBJNAME.get(expr) */
    965              { $$.constant=0; $$.ident=0; SString t=$1.getString(); t+=".get"; $$.setString(t);
     1154             { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$1.getString(); t+=".get"; $$.setString(t);
    9661155             if ($3.constant)
    9671156                     {
     
    9771166      | IDENT '(' arguments ')'
    9781167{
    979 $$.constant=0; $$.ident=0; $$.setString("function call");
     1168trctx.emitLine(); $$.constant=0; $$.ident=0; $$.setString("function call");
    9801169if ($3.getInt()==0)
    9811170        {trctx.out->printf("dec m0\n");trstack.adjust(-1);}
     
    9881177}
    9891178
    990 | '[' {$$.ident=0; trctx.out->printf("add -2,m0\ncall Vector.new\nmove s0,s1\n");trstack.adjust(-2);} // s1=vector, s0=nieuzywane ale zarezerwowane zeby nie przesuwac stosu przy kazdym elemencie (trafia tu wartosc zwracana przez add/set)
     1179| '[' {trctx.emitLine(); $$.ident=0; trctx.out->printf("add -2,m0\ncall Vector.new\nmove s0,s1\n");trstack.adjust(-2);} // s1=vector, s0=nieuzywane ale zarezerwowane zeby nie przesuwac stosu przy kazdym elemencie (trafia tu wartosc zwracana przez add/set)
    9911180        v_elements ']'
    9921181        {$$.constant=0; trctx.out->printf("inc m0\n");trstack.adjust(1);}
    9931182
    994 | '{' {$$.ident=0; trctx.out->printf("add -2,m0\ncall Dictionary.new\nmove s0,s1\n");trstack.adjust(-2);} // s1=dict, s0=nieuzywane ale zarezerwowane zeby nie przesuwac stosu przy kazdym elemencie (trafia tu wartosc zwracana przez add/set)
     1183| '{' {trctx.emitLine(); $$.ident=0; trctx.out->printf("add -2,m0\ncall Dictionary.new\nmove s0,s1\n");trstack.adjust(-2);} // s1=dict, s0=nieuzywane ale zarezerwowane zeby nie przesuwac stosu przy kazdym elemencie (trafia tu wartosc zwracana przez add/set)
    9951184        d_elements '}'
    9961185        {$$.constant=0; trctx.out->printf("inc m0\n"); trstack.adjust(1);}
     
    9991188
    10001189      | '&' IDENT {
    1001         $$.ident=0;
     1190        trctx.emitLine(); $$.ident=0;
    10021191        int loc=trstack.getVariableLocation($2.getString());
    10031192        if (loc!=TranslatorStack::NOTFOUND)
     
    10141203
    10151204      | '&' OBJNAME '.' member {
    1016       $$.ident=0;
     1205      trctx.emitLine(); $$.ident=0;
    10171206      if ($4.constant)
    10181207              {
     
    10271216
    10281217      | '&' '(' stackexpr ')' '.' member {
    1029       $$.ident=0;
     1218      trctx.emitLine(); $$.ident=0;
    10301219      if ($6.constant)
    10311220              {
     
    10401229
    10411230      | '(' stackexpr ',' stackexpr ',' stackexpr ')' {
    1042       $$.ident=0;
     1231      trctx.emitLine(); $$.ident=0;
    10431232      trctx.out->printf("call XYZ.new\nadd 2,m0\nmove s-2,s0\n");trstack.adjust(2);}
    10441233;
     
    11331322
    11341323void handleTwoArg(YYSTYPE& result,const YYSTYPE& arg1,const YYSTYPE& arg2,
    1135                   int optoken,const char* opname,bool logic,bool negarg2,bool uniq)
    1136 {
     1324                  int optoken,const char* opname,bool negarg2,bool uniq)
     1325{
     1326trctx.emitLine();
    11371327result.ident=false;
    11381328if (arg1.constant && arg2.constant)
     
    11501340                case LSHIFT: result.setInt(arg1.getInt() << arg2.getInt()); break;
    11511341                case RSHIFT: result.setInt(arg1.getInt() >> arg2.getInt()); break;
    1152                 case LOGIC_AND: result.setInt(arg1.getInt() && arg2.getInt()); break;
    1153                 case LOGIC_OR: result.setInt(arg1.getInt() || arg2.getInt()); break;
    11541342                }
    11551343        }
     
    11641352        result.setString(opname);
    11651353        if (arg1.constant)
    1166                 trctx.out->printf("move %s,m1\n%s%s%s s0,m1\nmove m1,s0\n",litstr(arg1),
    1167                                   (logic?"setif !=,m1,m1\nsetif !=,s0,s0\n":""),
     1354                trctx.out->printf("move %s,m1\n%s%s s0,m1\nmove m1,s0\n",litstr(arg1),
    11681355                                  negarg2?"neg s0\n":"",
    11691356                                  opname);
    11701357        else if (arg2.constant)
    11711358                {
    1172                 if (logic)
    1173                         trctx.out->printf("move %s,m1\nsetif !=,m1,m1\nsetif !=,s0,s0\n%s m1,s0\n",
    1174                                           litstr(arg2),opname);
     1359                if (negarg2)
     1360                        trctx.out->printf("%s %d,s0\n",opname,-arg2.getInt());
    11751361                else
    1176                         {
    1177                         if (negarg2)
    1178                                 trctx.out->printf("%s %d,s0\n",opname,-arg2.getInt());
    1179                         else
    1180                                 trctx.out->printf("%s%s %s,s0\n",(uniq?"uniq s0\n":""),opname,litstr(arg2));
    1181                         }
     1362                        trctx.out->printf("%s%s %s,s0\n",(uniq?"uniq s0\n":""),opname,litstr(arg2));
    11821363                }
    11831364        else
    11841365                {
    11851366                trctx.out->printf("%s%s%s s0,s1\ninc m0\n",
    1186                                   (logic?"setif !=,s0,s0\nsetif !=,s1,s1\n":(uniq?"uniq s1\n":"")),
     1367                                  uniq?"uniq s1\n":"",
    11871368                                  negarg2?"neg s0\n":"",
    11881369                                  opname);
     
    12271408}
    12281409
    1229 void handleCompare(YYSTYPE& result,const YYSTYPE& arg1,const YYSTYPE& arg2,int optoken,const char* opname)
    1230 {
     1410class FramscriptCmpMessageHandler: public ExtValue::CmpMessageHandler
     1411{
     1412  public:
     1413void cmpMessage(SString& msg)
     1414  {
     1415  FMprintf("FramScriptCompiler","translate",FMLV_WARN,"%s (%s line %d)",(const char*)msg,(const char*)trctx.srcname,trctx.line);
     1416  //trctx.err->printf("%s",(const char*)msg);
     1417  }
     1418};
     1419
     1420static FramscriptCmpMessageHandler framscript_cmp_messages;
     1421
     1422bool handleCompare(YYSTYPE& result,const YYSTYPE& arg1,const YYSTYPE& arg2,ExtValue::CmpOperator op,const char* opname)
     1423{
     1424trctx.emitLine();
    12311425result.ident=0;
    12321426if (arg1.constant && arg2.constant)
    12331427        {
    12341428        result.constant=1;
    1235         switch(optoken)
    1236                 {
    1237                 case '>': result.setInt(arg1.compare(arg2) > 0); break;
    1238                 case '<': result.setInt(arg1.compare(arg2) < 0); break;
    1239                 case EQUAL: result.setInt(arg1.compare(arg2) == 0); break;
    1240                 case NOT_EQUAL: result.setInt(arg1.compare(arg2) != 0); break;
    1241                 case GEQUAL: result.setInt(arg1.compare(arg2) >= 0); break;
    1242                 case LEQUAL: result.setInt(arg1.compare(arg2) <= 0); break;
    1243                 }
     1429        int cmp=arg1.compare(arg2);
     1430        ExtValue::CmpContext context;
     1431        context.v1=&arg1;
     1432        context.v2=&arg2;
     1433        context.handler=&framscript_cmp_messages;
     1434        int ret=ExtValue::interpretCompare(op,cmp,&context);
     1435        if (ret<0)
     1436                result.setEmpty();//return false;
     1437        else
     1438                result.setInt(ret);
     1439        return true;
    12441440        }
    12451441else
     
    12581454                trstack.adjust(+1);
    12591455                }
     1456        return true;
    12601457        }
    12611458}
Note: See TracChangeset for help on using the changeset viewer.