- Timestamp:
- 03/22/16 01:17:03 (9 years ago)
- Location:
- cpp/frams/vm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/vm/framscript.l
r468 r477 45 45 } 46 46 } 47 48 "->" return ARROW; 47 49 "==" return EQUAL; 48 50 "<>" return NOT_EQUAL; -
cpp/frams/vm/framscript.y
r468 r477 12 12 #define YYERROR_VERBOSE 13 13 #define YYPRINT(file,type,value) yyprint (file,type,value) 14 15 enum NameKind { NameNotFound, VariableName, GlobalName, ConstName }; 16 static const char* name_kind_names[]={"","var","global","const"}; 14 17 15 18 static void yyprint (FILE *file,int type,YYSTYPE value); … … 20 23 bool handleAssignOp(YYSTYPE& result,const YYSTYPE& var,const YYSTYPE& arg,const char* opname); 21 24 bool handleAssignOp2(YYSTYPE& result,const char *var,const YYSTYPE& arg,const char* opname,int stackpos,bool push); 25 bool canAddName(const SString &name,NameKind kind); 22 26 bool variableOk(TokenValue &tok, const TokenValue& var,int &loc); 27 int variableNameOk(const SString &name); 23 28 bool globalOk(const TokenValue& var); 29 bool globalNameOk(const SString& name); 24 30 void badVariable(TokenValue &tok, const TokenValue &var); 25 31 bool evalVariable(TokenValue &tok, const TokenValue &var); … … 78 84 79 85 %token VAR "var" 86 %token CONSTDEF "const" 80 87 %token GLOBAL "global" 81 88 %token FUNCTION "function" 82 89 83 90 %token CALL "call" 91 92 %token ARROW 84 93 85 94 %token ASSIGN … … 117 126 statement: ';' 118 127 | VAR vardeflist ';' 128 | CONSTDEF constdeflist ';' 119 129 | GLOBAL globaldeflist ';' 120 130 | IDENT ':' {trctx.out->printf(":%s\n",str($1));} … … 203 213 ; 204 214 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());} 215 vardef: 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 219 constdeflist: constdef 220 | constdeflist ',' constdef 221 ; 222 223 constdef: 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); } 207 224 ; 208 225 … … 211 228 ; 212 229 213 globaldef: IDENT {trstack.globals.add($1.getString(),0); 214 trctx.out->printf("global %s\n",str($1));} 230 globaldef: IDENT { if (!canAddName($1.getString(),GlobalName)) return 1; trstack.globals.add($1.getString(),0); trctx.out->printf("global %s\n",str($1));} 215 231 ; 216 232 … … 468 484 trctx.emitLine(); 469 485 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()); 471 492 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()); 473 494 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); 476 496 // s0=iterator s1=obj (=obj.iterator) 477 trstack.loops.addLoop($1.counter,trstack.currentPos());478 497 trctx.out->printf(":_loop1_%d\n",$1.counter); 479 498 trctx.out->printf(":_loop_%d\n",$1.counter); … … 662 681 expr_special_ident: CONSTANT { $$=$1; $$.constant=1; $$.ident=0; } 663 682 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 } 665 690 666 691 | OBJNAME ':' IDENT {$$.constant=0; $$.ident=0; … … 1024 1049 } 1025 1050 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 1026 1094 | plusminus stackexpr '.' member 1027 1095 { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=$2.getString(); t+="."; t+=$4.getString(); $$.setString(t); … … 1127 1195 {trctx.out->printf("move s2,m1\ncall [m1].\"set\"\nadd 2,m0\nmove s-2,s0\n"); trstack.adjust(+2);} 1128 1196 } 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);} 1129 1279 } 1130 1280 … … 1454 1604 } 1455 1605 1456 bool variableOk(TokenValue &tok, const TokenValue& var,int &loc) 1457 { 1458 loc=trstack.getVariableLocation(var.getString()); 1606 bool canAddName(const SString &name,NameKind kind) 1607 { 1608 ExtValue dummy; 1609 NameKind found=NameNotFound; 1610 if (globalNameOk(name)) found=GlobalName; 1611 else if (trstack.getConstant(name,dummy)) found=ConstName; 1612 else if (kind!=VariableName) { if (variableNameOk(name)!=TranslatorStack::NOTFOUND) found=VariableName; } 1613 if (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; } 1615 return true; 1616 } 1617 1618 int variableNameOk(const SString &name) 1619 { 1620 int loc=trstack.getVariableLocation(name); 1459 1621 if (loc != TranslatorStack::NOTFOUND) 1460 1622 { 1461 1623 if ((trctx.functionstackpos!=TranslatorContext::NOT_IN_FUNCTION) 1462 1624 && (loc>=trctx.beforefunctionstackpos)) 1463 return 0; 1625 return TranslatorStack::NOTFOUND; 1626 return loc; 1627 } 1628 return TranslatorStack::NOTFOUND; 1629 } 1630 1631 bool variableOk(TokenValue &tok, const TokenValue& var,int &loc) 1632 { 1633 loc=variableNameOk(var.getString()); 1634 if (loc != TranslatorStack::NOTFOUND) 1635 { 1464 1636 tok.setInt(loc); tok.constant=0; 1465 return 1;1466 } 1467 return 0;1637 return true; 1638 } 1639 return false; 1468 1640 } 1469 1641 1470 1642 bool globalOk(const TokenValue& var) 1471 1643 { 1472 SymTabEntry* found=trstack.globals.find(var.getString()); 1644 return globalNameOk(var.getString()); 1645 } 1646 1647 bool globalNameOk(const SString& name) 1648 { 1649 SymTabEntry* found=trstack.globals.find(name); 1473 1650 if (found) return true; 1474 return framscriptIsGlobalName( var.getString().c_str());1651 return framscriptIsGlobalName(name.c_str()); 1475 1652 } 1476 1653
Note: See TracChangeset
for help on using the changeset viewer.