GOTO expr,GOSUB expr実装
This commit is contained in:
@@ -40,9 +40,11 @@ class VM
|
|||||||
Value[] global;
|
Value[] global;
|
||||||
VMVariable[wstring] globalTable;
|
VMVariable[wstring] globalTable;
|
||||||
Function[wstring] functions;
|
Function[wstring] functions;
|
||||||
|
int[wstring] globalLabel;
|
||||||
int bp;
|
int bp;
|
||||||
PetitComputer petitcomputer;
|
PetitComputer petitcomputer;
|
||||||
this(Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/)
|
this(Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/,
|
||||||
|
int[wstring] globalLabel)
|
||||||
{
|
{
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.stack = new Value[16384];
|
this.stack = new Value[16384];
|
||||||
@@ -55,6 +57,7 @@ class VM
|
|||||||
}
|
}
|
||||||
this.functions = functions;
|
this.functions = functions;
|
||||||
this.globalDataTable = gdt;
|
this.globalDataTable = gdt;
|
||||||
|
this.globalLabel = globalLabel;
|
||||||
}
|
}
|
||||||
Code getCurrent()
|
Code getCurrent()
|
||||||
{
|
{
|
||||||
@@ -638,6 +641,27 @@ class GotoFalse : Code
|
|||||||
return "gotofalse " ~ address.to!string(16);
|
return "gotofalse " ~ address.to!string(16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class GotoExpr : Code
|
||||||
|
{
|
||||||
|
Scope sc;
|
||||||
|
this(Scope sc)
|
||||||
|
{
|
||||||
|
this.sc = sc;
|
||||||
|
}
|
||||||
|
override void execute(VM vm)
|
||||||
|
{
|
||||||
|
Value label;
|
||||||
|
vm.pop(label);
|
||||||
|
if(!label.isString)
|
||||||
|
{
|
||||||
|
vm.pc = vm.globalLabel[label.castString] - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
class GosubAddr : Code
|
class GosubAddr : Code
|
||||||
{
|
{
|
||||||
int address;
|
int address;
|
||||||
@@ -671,6 +695,28 @@ class GosubS : Code
|
|||||||
stderr.writeln("can't execute (compiler bug?)");
|
stderr.writeln("can't execute (compiler bug?)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class GosubExpr : Code
|
||||||
|
{
|
||||||
|
Scope sc;
|
||||||
|
this(Scope sc)
|
||||||
|
{
|
||||||
|
this.sc = sc;
|
||||||
|
}
|
||||||
|
override void execute(VM vm)
|
||||||
|
{
|
||||||
|
Value label;
|
||||||
|
vm.pop(label);
|
||||||
|
if(!label.isString)
|
||||||
|
{
|
||||||
|
vm.push(Value(vm.pc));
|
||||||
|
vm.pc = vm.globalLabel[label.castString] - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
class ReturnSubroutine : Code
|
class ReturnSubroutine : Code
|
||||||
{
|
{
|
||||||
this()
|
this()
|
||||||
|
|||||||
@@ -737,7 +737,16 @@ class Compiler
|
|||||||
break;
|
break;
|
||||||
case NodeType.Goto:
|
case NodeType.Goto:
|
||||||
{
|
{
|
||||||
genCodeGoto((cast(Goto)i).label, s);
|
auto gotou = cast(Goto)i;
|
||||||
|
if(!gotou.label)
|
||||||
|
{
|
||||||
|
compileExpression(gotou.labelexpr, s);
|
||||||
|
genCode(new GotoExpr(s));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
genCodeGoto(gotou.label, s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NodeType.If:
|
case NodeType.If:
|
||||||
@@ -749,7 +758,15 @@ class Compiler
|
|||||||
case NodeType.Gosub:
|
case NodeType.Gosub:
|
||||||
{
|
{
|
||||||
auto gosub = cast(Gosub)i;
|
auto gosub = cast(Gosub)i;
|
||||||
genCodeGosub(gosub.label, s);
|
if(gosub.label)
|
||||||
|
{
|
||||||
|
genCodeGosub(gosub.label, s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
compileExpression(gosub.labelexpr, s);
|
||||||
|
genCode(new GosubExpr(s));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NodeType.Return:
|
case NodeType.Return:
|
||||||
@@ -969,7 +986,7 @@ class Compiler
|
|||||||
code[i] = new RestoreCode(s.data.label[restore.label], s.data);
|
code[i] = new RestoreCode(s.data.label[restore.label], s.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new VM(code, globalIndex + 1, global, functions, s.data);
|
return new VM(code, globalIndex + 1, global, functions, s.data, globalLabel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -222,6 +222,12 @@ class Goto : Statement
|
|||||||
this.type = NodeType.Goto;
|
this.type = NodeType.Goto;
|
||||||
this.label = name;
|
this.label = name;
|
||||||
}
|
}
|
||||||
|
Expression labelexpr;
|
||||||
|
this(Expression expr)
|
||||||
|
{
|
||||||
|
this.type = NodeType.Goto;
|
||||||
|
this.labelexpr = expr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
class If : Statement
|
class If : Statement
|
||||||
{
|
{
|
||||||
@@ -271,6 +277,12 @@ class Gosub : Statement
|
|||||||
this.type = NodeType.Gosub;
|
this.type = NodeType.Gosub;
|
||||||
this.label = name;
|
this.label = name;
|
||||||
}
|
}
|
||||||
|
Expression labelexpr;
|
||||||
|
this(Expression expr)
|
||||||
|
{
|
||||||
|
this.type = NodeType.Gosub;
|
||||||
|
this.labelexpr = expr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
class Return : Statement
|
class Return : Statement
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -825,8 +825,10 @@ class Parser
|
|||||||
node = new Goto(token.value.stringValue);
|
node = new Goto(token.value.stringValue);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writeln("NotImpl");
|
auto e = expression();
|
||||||
syntaxError();
|
if(!e)
|
||||||
|
syntaxError();
|
||||||
|
node = new Goto(e);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TokenType.Gosub:
|
case TokenType.Gosub:
|
||||||
@@ -836,8 +838,10 @@ class Parser
|
|||||||
node = new Gosub(token.value.stringValue);
|
node = new Gosub(token.value.stringValue);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writeln("NotImpl");
|
auto e = expression();
|
||||||
syntaxError();
|
if(!e)
|
||||||
|
syntaxError();
|
||||||
|
node = new Gosub(e);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TokenType.If:
|
case TokenType.If:
|
||||||
|
|||||||
@@ -172,8 +172,6 @@ struct SpriteCollision
|
|||||||
return true;
|
return true;
|
||||||
if(x <= x2 && y <= y2 + h2 && x + w >= x2 && y + h >= y2 + h2)
|
if(x <= x2 && y <= y2 + h2 && x + w >= x2 && y + h >= y2 + h2)
|
||||||
return true;
|
return true;
|
||||||
//if(x2 <= x && y2 <= y && x2 + (data.w * data.scalex) >= x && y + (data.h * data.scaley) >= y)
|
|
||||||
// return true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user