1
0

GOTO expr,GOSUB expr実装

This commit is contained in:
otya128
2015-08-29 13:38:03 +09:00
parent cc3f18ee9a
commit d05166a3b9
5 changed files with 87 additions and 10 deletions

View File

@@ -40,9 +40,11 @@ class VM
Value[] global;
VMVariable[wstring] globalTable;
Function[wstring] functions;
int[wstring] globalLabel;
int bp;
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.stack = new Value[16384];
@@ -55,6 +57,7 @@ class VM
}
this.functions = functions;
this.globalDataTable = gdt;
this.globalLabel = globalLabel;
}
Code getCurrent()
{
@@ -638,6 +641,27 @@ class GotoFalse : Code
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
{
int address;
@@ -671,6 +695,28 @@ class GosubS : Code
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
{
this()

View File

@@ -737,7 +737,16 @@ class Compiler
break;
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;
case NodeType.If:
@@ -749,7 +758,15 @@ class Compiler
case NodeType.Gosub:
{
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;
case NodeType.Return:
@@ -969,7 +986,7 @@ class Compiler
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);
}
}

View File

@@ -222,6 +222,12 @@ class Goto : Statement
this.type = NodeType.Goto;
this.label = name;
}
Expression labelexpr;
this(Expression expr)
{
this.type = NodeType.Goto;
this.labelexpr = expr;
}
}
class If : Statement
{
@@ -271,6 +277,12 @@ class Gosub : Statement
this.type = NodeType.Gosub;
this.label = name;
}
Expression labelexpr;
this(Expression expr)
{
this.type = NodeType.Gosub;
this.labelexpr = expr;
}
}
class Return : Statement
{

View File

@@ -825,8 +825,10 @@ class Parser
node = new Goto(token.value.stringValue);
else
{
writeln("NotImpl");
syntaxError();
auto e = expression();
if(!e)
syntaxError();
node = new Goto(e);
}
break;
case TokenType.Gosub:
@@ -836,8 +838,10 @@ class Parser
node = new Gosub(token.value.stringValue);
else
{
writeln("NotImpl");
syntaxError();
auto e = expression();
if(!e)
syntaxError();
node = new Gosub(e);
}
break;
case TokenType.If:

View File

@@ -172,8 +172,6 @@ struct SpriteCollision
return true;
if(x <= x2 && y <= y2 + h2 && x + w >= x2 && y + h >= y2 + h2)
return true;
//if(x2 <= x && y2 <= y && x2 + (data.w * data.scalex) >= x && y + (data.h * data.scaley) >= y)
// return true;
return false;
}
}