Changeset 477 for cpp/frams


Ignore:
Timestamp:
03/22/16 01:17:03 (6 years ago)
Author:
Maciej Komosinski
Message:

"const" keyword, detecting variable name clashes, error on iterating null, "->" notation for dictionaries

Location:
cpp/frams/vm
Files:
2 edited

Legend:

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

    r468 r477  
    4545                            }
    4646                       }
     47
     48"->"               return ARROW;
    4749"=="               return EQUAL;
    4850"<>"               return NOT_EQUAL;
  • cpp/frams/vm/framscript.y

    r468 r477  
    1212#define YYERROR_VERBOSE
    1313#define YYPRINT(file,type,value) yyprint (file,type,value)
     14
     15enum NameKind { NameNotFound, VariableName, GlobalName, ConstName };
     16static const char* name_kind_names[]={"","var","global","const"};
    1417
    1518static void yyprint (FILE *file,int type,YYSTYPE value);
     
    2023bool handleAssignOp(YYSTYPE& result,const YYSTYPE& var,const YYSTYPE& arg,const char* opname);
    2124bool handleAssignOp2(YYSTYPE& result,const char *var,const YYSTYPE& arg,const char* opname,int stackpos,bool push);
     25bool canAddName(const SString &name,NameKind kind);
    2226bool variableOk(TokenValue &tok, const TokenValue& var,int &loc);
     27int variableNameOk(const SString &name);
    2328bool globalOk(const TokenValue& var);
     29bool globalNameOk(const SString& name);
    2430void badVariable(TokenValue &tok, const TokenValue &var);
    2531bool evalVariable(TokenValue &tok, const TokenValue &var);
     
    7884             
    7985%token VAR      "var"
     86%token CONSTDEF "const"
    8087%token GLOBAL   "global"
    8188%token FUNCTION "function"
    8289
    8390%token CALL    "call"
     91
     92%token ARROW
    8493
    8594%token ASSIGN
     
    117126statement: ';'
    118127      | VAR vardeflist ';'
     128      | CONSTDEF constdeflist ';'
    119129      | GLOBAL globaldeflist ';'
    120130      | IDENT ':'     {trctx.out->printf(":%s\n",str($1));}
     
    203213;
    204214
    205 vardef: IDENT               { trctx.emitLine(); trstack.addVariable($1.getString()); trctx.out->printf("push invalid\n");}
    206       | IDENT '=' stackexpr { trctx.emitLine(); trstack.adjust(1); trstack.addVariable($1.getString());}
     215vardef: IDENT               { trctx.emitLine(); if (!canAddName($1.getString(),VariableName)) return 1; trstack.addVariable($1.getString()); trctx.out->printf("push invalid\n"); }
     216      | IDENT '=' stackexpr { trctx.emitLine(); if (!canAddName($1.getString(),VariableName)) return 1; trstack.adjust(1); trstack.addVariable($1.getString());}
     217;
     218
     219constdeflist: constdef
     220          | constdeflist ',' constdef
     221;
     222
     223constdef: IDENT '=' expr        { trctx.emitLine(); if (!canAddName($1.getString(),ConstName)) return 1; if (!$3.constant) {trctx.err->printf("const expression must be constant");return 1;} trstack.addConstant($1.getString(),$3); }
    207224;
    208225
     
    211228;
    212229
    213 globaldef: IDENT     {trstack.globals.add($1.getString(),0);
    214                       trctx.out->printf("global %s\n",str($1));}
     230globaldef: IDENT     { if (!canAddName($1.getString(),GlobalName)) return 1; trstack.globals.add($1.getString(),0); trctx.out->printf("global %s\n",str($1));}
    215231;
    216232
     
    468484           trctx.emitLine();
    469485           if ($4.constant)
    470                    {trctx.err->printf("%s can't be iterated\n",str($4)); return 1;}
     486                   {
     487                   logPrintf("", "", LOG_WARN, "%s can't be iterated",str($4));
     488                   trctx.out->printf("jump :_loop_end_%d\n",$1.counter);
     489                   }
     490           trstack.adjust(-1);
     491           trstack.loops.addLoop($1.counter,trstack.currentPos());
    471492           if ($4.objname)
    472                    trctx.out->printf("move %s.iterator,m[--m0]\n",$4.getString().c_str());
     493                   trctx.out->printf("dec m0\nmove %s.iterator,m[m0]\n",$4.getString().c_str());
    473494           else
    474                    trctx.out->printf("move s%d,m1\nmove [m1].\"iterator\",m[--m0]\n",0);
    475            trstack.adjust(-1);
     495                   trctx.out->printf("move s%d,m1\ndec m0\nif m1,==,null,:_loop_end_%d\nmove [m1].\"iterator\",m[m0]\n",0,$1.counter);
    476496           // s0=iterator s1=obj (=obj.iterator)
    477            trstack.loops.addLoop($1.counter,trstack.currentPos());
    478497           trctx.out->printf(":_loop1_%d\n",$1.counter);
    479498           trctx.out->printf(":_loop_%d\n",$1.counter);
     
    662681expr_special_ident:    CONSTANT             { $$=$1; $$.constant=1; $$.ident=0; }
    663682
    664        | IDENT                { $$.ident=true; $$.setString($1.getString()); }
     683       | IDENT                {
     684                              ExtValue c;
     685                              if (trstack.getConstant($1.getString(),c))
     686                                      { $$=c; $$.constant=1; $$.ident=0; }
     687                              else
     688                                      { $$.ident=true; $$.setString($1.getString()); }
     689                              }
    665690
    666691       | OBJNAME ':' IDENT    {$$.constant=0; $$.ident=0;
     
    10241049             }
    10251050
     1051     | stackexpr ARROW IDENT       /* shortcut: expr.get("ident") */
     1052             { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="->"; t+=$3.getString(); $$.setString(t);
     1053             trctx.out->printf("move s0,m1\ncall [m1].\"get\",%s\n",litstr($3));
     1054             }
     1055
     1056     | OBJNAME ARROW IDENT       /* shortcut: StaticObject.get("ident") */
     1057             { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$1.getString(); t+="->"; t+=$3.getString(); $$.setString(t);
     1058             trctx.out->printf("dec m0\ncall %s.\"get\",%s\n",$1.getString().c_str(),litstr($3)); trstack.adjust(-1);
     1059             }
     1060
     1061     | plusminus stackexpr ARROW IDENT       /* shortcut: expr.set("ident",expr.get("ident")+/-1) */
     1062             { trctx.emitLine(); $$.constant=0; $$.ident=0; $$.setString("");
     1063             trctx.out->printf("move s0,m1\ncall [m1].\"get\",%s\n"
     1064                               "move s0,m2\n%s m2\n"
     1065                               "call [m1].\"set\",%s,m2\nmove m2,s0\n",
     1066                               litstr($4),$1.getInt()?"inc":"dec",litstr($4));
     1067             }
     1068
     1069     | stackexpr ARROW IDENT plusminus       /* shortcut: expr.set("ident",expr.get("ident")+/-1) */
     1070             { trctx.emitLine(); $$.constant=0; $$.ident=0; $$.setString("");
     1071             trctx.out->printf("move s0,m1\ncall [m1].\"get\",%s\n"
     1072                               "move s0,m2\n%s s0\n"
     1073                               "call [m1].\"set\",%s,s0\nmove m2,s0\n",
     1074                               litstr($3),$4.getInt()?"inc":"dec",litstr($3));
     1075             }
     1076
     1077     | stackexpr ARROW IDENT assign_op expr    /* shortcut: expr1.set("ident",expr1.get("ident") +*-/ expr2) */
     1078             { trctx.emitLine(); $$.constant=0; $$.ident=0; $$.setString("");
     1079             if ($5.constant)
     1080                     trctx.out->printf("move s0,m1\ncall [m1].\"get\",%s\n"
     1081                                       "move s0,m2\n%s %s,m2\n"
     1082                                       "call [m1].\"set\",%s,m2\nmove m2,s0\n",
     1083                                       litstr($3),assign_op_names[$4.getInt()],litstr($5),litstr($3));
     1084             else
     1085                     {
     1086                     trctx.out->printf("move s0,m3\nmove s1,m1\ncall [m1].\"get\",%s\n"
     1087                                       "move s0,m2\n%s m3,m2\n"
     1088                                       "call [m1].\"set\",%s,m2\ninc m0\nmove m2,s0\n",
     1089                                       litstr($3),assign_op_names[$4.getInt()],litstr($3));
     1090                     trstack.adjust(1);
     1091                     }
     1092             }
     1093
    10261094     | plusminus stackexpr '.' member
    10271095             { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$2.getString(); t+="."; t+=$4.getString(); $$.setString(t);
     
    11271195                             {trctx.out->printf("move s2,m1\ncall [m1].\"set\"\nadd 2,m0\nmove s-2,s0\n"); trstack.adjust(+2);}
    11281196                     }
     1197             }
     1198
     1199      | plusminus stackexpr '[' expr ']'  /* shortcut: o.set(index,o.get(index)+/-1) */
     1200             { trctx.emitLine(); $$.constant=0; $$.ident=0; $$.setString("");
     1201             if ($4.constant)
     1202                     trctx.out->printf("move s0,m1\ncall [m1].\"get\",%s\n"
     1203                                       "move s0,m2\n%s m2\n"
     1204                                       "call [m1].\"set\",%s,m2\nmove m2,s0\n",
     1205                                       litstr($4),$1.getInt()?"inc":"dec",litstr($4));
     1206             else
     1207                     {
     1208                     trctx.out->printf("move s0,m3\nmove s1,m1\ncall [m1].\"get\",m3\n"
     1209                                       "move s0,m2\n%s m2\n"
     1210                                       "call [m1].\"set\",m3,m2\ninc m0\nmove m2,s0\n",
     1211                                       $1.getInt()?"inc":"dec");
     1212                     trstack.adjust(1);
     1213                     }
     1214             }
     1215
     1216      | stackexpr '[' expr ']' plusminus  /* shortcut: o.set(index,o.get(index)+/-1) */
     1217             { trctx.emitLine(); $$.constant=0; $$.ident=0; $$.setString("");
     1218             if ($3.constant)
     1219                     trctx.out->printf("move s0,m1\ncall [m1].\"get\",%s\n"
     1220                                       "move s0,m2\n%s s0\n"
     1221                                       "call [m1].\"set\",%s,s0\nmove m2,s0\n",
     1222                                       litstr($3),$5.getInt()?"inc":"dec",litstr($3));
     1223             else
     1224                     {
     1225                     trctx.out->printf("move s0,m3\nmove s1,m1\ncall [m1].\"get\",m3\n"
     1226                                       "move s0,m2\n%s s0\n"
     1227                                       "call [m1].\"set\",m3,s0\ninc m0\nmove m2,s0\n",
     1228                                       $5.getInt()?"inc":"dec");
     1229                     trstack.adjust(1);
     1230                     }
     1231             }
     1232
     1233      | stackexpr '[' expr ']' assign_op expr /* shortcut: o.set(index,o.get(index) +*-/ expr) */
     1234             { trctx.emitLine(); $$.constant=0; $$.ident=0; $$.setString("");
     1235             if ($6.constant)
     1236                     {
     1237                     if ($3.constant)
     1238                             trctx.out->printf("move s0,m1\ncall [m1].\"get\",%s\n"
     1239                                               "move s0,m2\n%s %s,m2\n"
     1240                                               "call [m1].\"set\",%s,m2\nmove m2,s0\n",
     1241                                               litstr($3),assign_op_names[$5.getInt()],litstr($6),litstr($3));
     1242                     else
     1243                             {
     1244                             trctx.out->printf("move s0,m3\nmove s1,m1\ncall [m1].\"get\",m3\n"
     1245                                               "move s0,m2\n%s %s,m2\n"
     1246                                               "call [m1].\"set\",m3,m2\ninc m0\nmove m2,s0\n",
     1247                                               assign_op_names[$5.getInt()],litstr($6));
     1248                             trstack.adjust(1);
     1249                             }
     1250                     }
     1251             else
     1252                     {
     1253                     if ($3.constant)
     1254                             {
     1255                             trctx.out->printf("move s0,m3\nmove s1,m1\ncall [m1].\"get\",%s\n"
     1256                                               "move s0,m2\n%s m3,m2\n"
     1257                                               "call [m1].\"set\",%s,m2\ninc m0\nmove m2,s0\n",
     1258                                               litstr($3),assign_op_names[$5.getInt()],litstr($3));
     1259                             trstack.adjust(1);
     1260                             }
     1261                     else
     1262                             {
     1263                             trctx.out->printf("move s0,m3\nmove s1,m4\nmove s2,m1\ncall [m1].\"get\",m4\n"
     1264                                               "move s0,m2\n%s m3,m2\n"
     1265                                               "call [m1].\"set\",m4,m2\nadd 2,m0\nmove m2,s0\n",
     1266                                               assign_op_names[$5.getInt()]);
     1267                             trstack.adjust(2);
     1268                             }
     1269                     }
     1270             }
     1271
     1272
     1273     | stackexpr ARROW IDENT '=' expr       /* shortcut: expr.set("ident",expr) */
     1274             { trctx.emitLine(); $$=$5; $$.assign=1; $$.ident=0; $$.parens=0;
     1275                     if ($5.constant)
     1276                             {trctx.out->printf("move s0,m1\ncall [m1].\"set\",%s,%s\ninc m0\n",litstr($3),litstr($5));$$=$5;trstack.adjust(+1);}
     1277                     else
     1278                             {trctx.out->printf("move s1,m1\npush s0\nmove %s,s1\ncall [m1].\"set\"\nadd 2,m0\nmove s-2,s0\n",litstr($3));trstack.adjust(+1);}
    11291279             }
    11301280
     
    14541604}
    14551605
    1456 bool variableOk(TokenValue &tok, const TokenValue& var,int &loc)
    1457 {
    1458 loc=trstack.getVariableLocation(var.getString());
     1606bool canAddName(const SString &name,NameKind kind)
     1607{
     1608ExtValue dummy;
     1609NameKind found=NameNotFound;
     1610if (globalNameOk(name)) found=GlobalName;
     1611else if (trstack.getConstant(name,dummy)) found=ConstName;
     1612else if (kind!=VariableName) { if (variableNameOk(name)!=TranslatorStack::NOTFOUND) found=VariableName; }
     1613if (found!=NameNotFound)
     1614        { trctx.err->printf("Can't define '%s %s' (previously defined as %s)",name_kind_names[kind],name.c_str(),name_kind_names[found]); return false; }
     1615return true;
     1616}
     1617
     1618int variableNameOk(const SString &name)
     1619{
     1620int loc=trstack.getVariableLocation(name);
    14591621if (loc != TranslatorStack::NOTFOUND)
    14601622        {
    14611623        if ((trctx.functionstackpos!=TranslatorContext::NOT_IN_FUNCTION)
    14621624            && (loc>=trctx.beforefunctionstackpos))
    1463                 return 0;
     1625                return TranslatorStack::NOTFOUND;
     1626        return loc;
     1627        }
     1628return TranslatorStack::NOTFOUND;
     1629}
     1630
     1631bool variableOk(TokenValue &tok, const TokenValue& var,int &loc)
     1632{
     1633loc=variableNameOk(var.getString());
     1634if (loc != TranslatorStack::NOTFOUND)
     1635        {
    14641636        tok.setInt(loc); tok.constant=0;
    1465         return 1;
    1466         }
    1467 return 0;
     1637        return true;
     1638        }
     1639return false;
    14681640}
    14691641
    14701642bool globalOk(const TokenValue& var)
    14711643{
    1472 SymTabEntry* found=trstack.globals.find(var.getString());
     1644return globalNameOk(var.getString());
     1645}
     1646
     1647bool globalNameOk(const SString& name)
     1648{
     1649SymTabEntry* found=trstack.globals.find(name);
    14731650if (found) return true;
    1474 return framscriptIsGlobalName(var.getString().c_str());
     1651return framscriptIsGlobalName(name.c_str());
    14751652}
    14761653
Note: See TracChangeset for help on using the changeset viewer.