diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index 3b614a8..8a6f819 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -888,3 +888,79 @@ class CallBuiltinFunction : Code vm.stacki -= func.argments.length - outcount; } } +class IncCodeG : Code +{ + int var; + this(int var) + { + this.var = var; + } + //TODO:文字列INCの挙動 + override void execute(VM vm) + { + Value v; + Value g = vm.global[var]; + vm.pop(v); + if(!g.isNumber() && g.type != ValueType.String) + { + throw new TypeMismatch(); + } + if((!g.isNumber() || !v.isNumber()) && g.type != v.type) + { + throw new TypeMismatch(); + } + if(g.isNumber()) + { + double l = g.castDouble; + double r = v.castDouble; + if(v.type == ValueType.Double) + vm.global[var] = Value(l + r); + else + vm.global[var] = Value(cast(int)(l + r)); + } + else + { + wstring l = g.stringValue; + wstring r = v.stringValue; + vm.global[var] = Value(l ~ r); + } + } +} +class IncCodeL : Code +{ + int var; + this(int var) + { + this.var = var; + } + //TODO:文字列INCの挙動 + override void execute(VM vm) + { + Value v; + Value* g = &vm.stack[vm.bp + var]; + vm.pop(v); + if(!g.isNumber() && g.type != ValueType.String) + { + throw new TypeMismatch(); + } + if((!g.isNumber() || !v.isNumber()) && g.type != v.type) + { + throw new TypeMismatch(); + } + if(g.isNumber()) + { + double l = g.castDouble; + double r = v.castDouble; + if(v.type == ValueType.Double) + *g = Value(l + r); + else + *g = Value(cast(int)(l + r)); + } + else + { + wstring l = g.stringValue; + wstring r = v.stringValue; + *g = Value(l ~ r); + } + } +} diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index 45497a9..9bdd643 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -277,8 +277,6 @@ class Compiler { if(sc.func) { - int global = hasGlobalVarIndex(name); - if(global) return global; int local = sc.func.getLocalVarIndex(name, this); return local; } @@ -477,6 +475,19 @@ class Compiler } } } + void compileInc(Inc node, Scope sc) + { + compileExpression(node.expression, sc); + int index = sc.func ? sc.func.hasLocalVarIndex(node.name) : 0; + if(index) + { + genCode(new IncCodeL(index)); + } + else + { + genCode(new IncCodeG(this.getGlobalVarIndex(node.name))); + } + } void compileStatements(Statements statements, Scope sc) { foreach(Statement s ; statements.statements) @@ -652,6 +663,9 @@ class Compiler case NodeType.While: compileWhile(cast(While)i, s); break; + case NodeType.Inc: + compileInc(cast(Inc)i, s); + break; default: stderr.writeln("Compile:NotImpl ", i.type); } diff --git a/SMILEBASIC/node.d b/SMILEBASIC/node.d index cd3874f..53f71d8 100644 --- a/SMILEBASIC/node.d +++ b/SMILEBASIC/node.d @@ -427,6 +427,7 @@ class Inc : Statement Expression expression; this(wstring name, Expression expr) { + this.type = NodeType.Inc; this.name = name; this.expression = expr; } diff --git a/SMILEBASIC/petitcomputer.d b/SMILEBASIC/petitcomputer.d index 45ec910..637086c 100644 --- a/SMILEBASIC/petitcomputer.d +++ b/SMILEBASIC/petitcomputer.d @@ -360,8 +360,8 @@ DEF FACT(N) END"*/ `CLS : CL=0 : Z=0 WHILE 1 -Z=Z+1 -?Z; +INC Z +?Z, WEND WHILE 1 INC Z : IF Z>200 THEN Z=0