IF文を実�
This commit is contained in:
@@ -37,6 +37,24 @@ class Compiler
|
|||||||
{
|
{
|
||||||
code ~= new GotoS(label);
|
code ~= new GotoS(label);
|
||||||
}
|
}
|
||||||
|
GotoAddr genCodeGoto()
|
||||||
|
{
|
||||||
|
auto c = new GotoAddr(-1);
|
||||||
|
code ~= c;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
GotoTrue genCodeGotoTrue()
|
||||||
|
{
|
||||||
|
auto c = new GotoTrue(-1);
|
||||||
|
code ~= c;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
GotoFalse genCodeGotoFalse()
|
||||||
|
{
|
||||||
|
auto c = new GotoFalse(-1);
|
||||||
|
code ~= c;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
int defineGlobalVarIndex(wstring name)
|
int defineGlobalVarIndex(wstring name)
|
||||||
{
|
{
|
||||||
int global = this.global.get(name, 0);
|
int global = this.global.get(name, 0);
|
||||||
@@ -98,9 +116,36 @@ class Compiler
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VM compile()
|
void compileIf(If node)
|
||||||
{
|
{
|
||||||
foreach(Statement i ; statements.statements)
|
compileExpression(node.condition);
|
||||||
|
//条件式がfalseならendif or elseに飛ぶ
|
||||||
|
auto else_ = genCodeGotoFalse();
|
||||||
|
compileStatements(node.then);
|
||||||
|
//もしelseもあるのならば、endifに飛ぶ
|
||||||
|
GotoAddr then;
|
||||||
|
if(node.hasElse)
|
||||||
|
{
|
||||||
|
then = genCodeGoto();
|
||||||
|
else_.address = code.length;
|
||||||
|
compileStatements(node.else_);
|
||||||
|
then.address = code.length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//endifに飛ばす
|
||||||
|
else_.address = code.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void compileStatements(Statements statements)
|
||||||
|
{
|
||||||
|
foreach(Statement s ; statements.statements)
|
||||||
|
{
|
||||||
|
compileStatement(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void compileStatement(Statement i)
|
||||||
{
|
{
|
||||||
switch(i.type)
|
switch(i.type)
|
||||||
{
|
{
|
||||||
@@ -145,10 +190,19 @@ class Compiler
|
|||||||
genCodeGoto((cast(Goto)i).label);
|
genCodeGoto((cast(Goto)i).label);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case NodeType.If:
|
||||||
|
compileIf(cast(If)i);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
stderr.writeln("Compile:NotImpl ", i.type);
|
stderr.writeln("Compile:NotImpl ", i.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
VM compile()
|
||||||
|
{
|
||||||
|
foreach(Statement i ; statements.statements)
|
||||||
|
{
|
||||||
|
compileStatement(i);
|
||||||
|
}
|
||||||
foreach(int i, Code c; code)
|
foreach(int i, Code c; code)
|
||||||
{
|
{
|
||||||
if(c.type == CodeType.GotoS)
|
if(c.type == CodeType.GotoS)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ int main(string[] argv)
|
|||||||
auto parser = new Parser(
|
auto parser = new Parser(
|
||||||
"@A\nA=1+2+3+4\nPRINT 1+1,2+3;10-5,A:A=A*2:PRINT A
|
"@A\nA=1+2+3+4\nPRINT 1+1,2+3;10-5,A:A=A*2:PRINT A
|
||||||
IF 1 THEN PRINT 2
|
IF 1 THEN PRINT 2
|
||||||
IF 3 THEN PRINT 4 ELSE PRINT 5
|
IF 0 THEN PRINT 4 ELSE PRINT 5
|
||||||
");
|
");
|
||||||
auto vm = parser.compile();
|
auto vm = parser.compile();
|
||||||
vm.run();
|
vm.run();
|
||||||
|
|||||||
@@ -204,4 +204,8 @@ class If : Statement
|
|||||||
this.then = t;
|
this.then = t;
|
||||||
this.else_ = e;
|
this.else_ = e;
|
||||||
}
|
}
|
||||||
|
bool hasElse()
|
||||||
|
{
|
||||||
|
return !(else_ is null) && else_.statements.length != 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user