代入の実�
This commit is contained in:
@@ -43,6 +43,7 @@ enum CodeType
|
|||||||
Goto,
|
Goto,
|
||||||
Gosub,
|
Gosub,
|
||||||
Print,
|
Print,
|
||||||
|
PopG,
|
||||||
}
|
}
|
||||||
abstract class Code
|
abstract class Code
|
||||||
{
|
{
|
||||||
@@ -108,6 +109,19 @@ class PushG : Code
|
|||||||
vm.push(vm.global[var]);
|
vm.push(vm.global[var]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class PopG : Code
|
||||||
|
{
|
||||||
|
int var;
|
||||||
|
this(int var)
|
||||||
|
{
|
||||||
|
this.type = CodeType.PopG;
|
||||||
|
this.var = var;
|
||||||
|
}
|
||||||
|
override void execute(VM vm)
|
||||||
|
{
|
||||||
|
vm.pop(vm.global[var]);
|
||||||
|
}
|
||||||
|
}
|
||||||
class Operate : Code
|
class Operate : Code
|
||||||
{
|
{
|
||||||
TokenType operator;
|
TokenType operator;
|
||||||
|
|||||||
@@ -24,10 +24,38 @@ class Compiler
|
|||||||
{
|
{
|
||||||
code ~= new PushG(ind);
|
code ~= new PushG(ind);
|
||||||
}
|
}
|
||||||
|
void genCodePopGlobal(int ind)
|
||||||
|
{
|
||||||
|
code ~= new PopG(ind);
|
||||||
|
}
|
||||||
void genCodeOP(TokenType op)
|
void genCodeOP(TokenType op)
|
||||||
{
|
{
|
||||||
code ~= new Operate(op);
|
code ~= new Operate(op);
|
||||||
}
|
}
|
||||||
|
int defineGlobalVarIndex(wstring name)
|
||||||
|
{
|
||||||
|
int global = this.global.get(name, 0);
|
||||||
|
if(global == 0)
|
||||||
|
{
|
||||||
|
this.global[name] = ++globalIndex = global;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//error:二重定義
|
||||||
|
}
|
||||||
|
return global;
|
||||||
|
}
|
||||||
|
int getGlobalVarIndex(wstring name)
|
||||||
|
{
|
||||||
|
int global = this.global.get(name, 0);
|
||||||
|
if(global == 0)
|
||||||
|
{
|
||||||
|
//local変数をあたる
|
||||||
|
//それでもだめならOPTION STRICTならエラー
|
||||||
|
this.global[name] = ++globalIndex = global;
|
||||||
|
}
|
||||||
|
return global;
|
||||||
|
}
|
||||||
void compileExpression(Expression exp)
|
void compileExpression(Expression exp)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -46,14 +74,7 @@ class Compiler
|
|||||||
break;
|
break;
|
||||||
case NodeType.Variable:
|
case NodeType.Variable:
|
||||||
auto var = cast(Variable)exp;
|
auto var = cast(Variable)exp;
|
||||||
int global = this.global.get(var.name, 0);
|
genCodePushGlobal(getGlobalVarIndex(var.name));
|
||||||
if(global == 0)
|
|
||||||
{
|
|
||||||
//local変数をあたる
|
|
||||||
//それでもだめならOPTION STRICTならエラー
|
|
||||||
this.global[var.name] = ++globalIndex = global;
|
|
||||||
}
|
|
||||||
genCodePushGlobal(global);
|
|
||||||
break;
|
break;
|
||||||
case NodeType.CallFunction:
|
case NodeType.CallFunction:
|
||||||
{
|
{
|
||||||
@@ -100,6 +121,13 @@ class Compiler
|
|||||||
code ~= new PrintCode(print.args.length);
|
code ~= new PrintCode(print.args.length);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case NodeType.Assign:
|
||||||
|
{
|
||||||
|
auto assign = cast(Assign)i;
|
||||||
|
compileExpression(assign.expression);
|
||||||
|
genCodePopGlobal(getGlobalVarIndex(assign.name));
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
stderr.writeln("Compile:NotImpl ", i.type);
|
stderr.writeln("Compile:NotImpl ", i.type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ int main(string[] argv)
|
|||||||
writeln(parser.calc());
|
writeln(parser.calc());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parser = new Parser("A=1\nPRINT 1+1,2+3;10-5,A");
|
auto parser = new Parser("A=1+2+3+4\nPRINT 1+1,2+3;10-5,A");
|
||||||
auto vm = parser.compile();
|
auto vm = parser.compile();
|
||||||
vm.run();
|
vm.run();
|
||||||
readln();
|
readln();
|
||||||
|
|||||||
@@ -163,11 +163,11 @@ class Print : Statement
|
|||||||
class Assign : Statement
|
class Assign : Statement
|
||||||
{
|
{
|
||||||
wstring name;
|
wstring name;
|
||||||
Expression expr;
|
Expression expression;
|
||||||
this(wstring name, Expression expr)
|
this(wstring name, Expression expr)
|
||||||
{
|
{
|
||||||
this.type = NodeType.Assign;
|
this.type = NodeType.Assign;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.expr = expr;
|
this.expression = expr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user