From 5f0078a8f976673a7f64a98939288726d53e6826 Mon Sep 17 00:00:00 2001 From: otya128 Date: Mon, 22 Feb 2016 23:08:54 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=80=E3=82=A4=E3=83=AC=E3=82=AF=E3=83=88?= =?UTF-8?q?=E3=83=A2=E3=83=BC=E3=83=89=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SMILEBASIC/VM.d | 20 ++++++++++++++++--- SMILEBASIC/compiler.d | 10 +++++++++- SMILEBASIC/error.d | 10 ++++++++++ SMILEBASIC/petitcomputer.d | 39 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 73 insertions(+), 6 deletions(-) diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index 71cee2e..628d40e 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -27,6 +27,8 @@ class VMSlot { bool isUsed; DataTable globalDataTable; + //2MBらしい + //Code code[2 * 1024 * 1024 / Code.sizeof]; Code[] code; SourceLocation[] location; Value[] global; @@ -34,6 +36,7 @@ class VMSlot Function[wstring] functions; int[wstring] globalLabel; DebugInfo debugInfo; + Value[wstring] directModeVariable; } class VM { @@ -57,11 +60,22 @@ class VM { currentSlot = slots[slot]; } - void directSlot(Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/, + void directSlot(int start, Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/, int[wstring] globalLabel, DebugInfo dinfo) { - this.pc = currentSlot.code.length; - this.currentSlot.code ~= code; + this.pc = start; + auto c = this.currentSlot; + c.globalTable = globalTable; + c.code = code; + sizediff_t oldlen = c.global.length; + sizediff_t addedvarcount = len - oldlen; + for(sizediff_t i = 0; i < addedvarcount; i++) + c.global ~= Value(ValueType.Void); + foreach(wstring k, VMVariable v ; globalTable) + { + if(v.index >= 0 && v.index >= oldlen) + c.global[v.index] = Value(v.type); + } } void loadSlot(int slot, Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/, int[wstring] globalLabel, DebugInfo dinfo) diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index 3585ba1..be11a00 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -690,6 +690,10 @@ class Compiler } void compileDefineFunction(DefineFunction node) { + if(isDirectMode) + { + throw new CantUseFromDirectMode(); + } auto skip = genCodeGoto(); Function func = new Function(cast(int)this.code.length, node.name, node.returnExpr, cast(int)node.arguments.length); Scope sc = new Scope(func); @@ -1054,8 +1058,12 @@ class Compiler void compileDirectMode(VM vm) { isDirectMode = true; + global = vm.currentSlot.globalTable; + auto start = vm.currentSlot.code.length; + this.code = vm.currentSlot.code; + globalIndex = vm.currentSlot.global.length; compileProgram(); - vm.directSlot(code, globalIndex + 1, global, functions, globalScope.data, globalLabel, debugInfo); + vm.directSlot(start, code, globalIndex + 1, global, functions, globalScope.data, globalLabel, debugInfo); } VM compile() { diff --git a/SMILEBASIC/error.d b/SMILEBASIC/error.d index 5e3d9b7..bc4eabe 100644 --- a/SMILEBASIC/error.d +++ b/SMILEBASIC/error.d @@ -104,4 +104,14 @@ class SubscriptOutOfRange : SmileBasicError super("Subscript out of range"); } } +class CantUseFromDirectMode : SmileBasicError +{ + this() + { + this.errnum = 43; + this.errprg = 0;//always 0 + this.errline = 0; + super("Can't use from direct mode"); + } +} diff --git a/SMILEBASIC/petitcomputer.d b/SMILEBASIC/petitcomputer.d index 16af248..4fdb59c 100644 --- a/SMILEBASIC/petitcomputer.d +++ b/SMILEBASIC/petitcomputer.d @@ -1185,8 +1185,43 @@ class PetitComputer } auto prg = input("", true); parser = new Parser(prg); - auto cc = parser.compiler; - cc.compileDirectMode(vm); + try + { + auto cc = parser.compiler; + cc.compileDirectMode(vm); + } + catch(SmileBasicError sbe) + { + try + { + printConsole(sbe.getErrorMessage, "\n"); + printConsole(sbe.getErrorMessage2, "\n"); + //printConsole(sbe.to!string); + writeln(sbe.to!string); + writeln(sbe.getErrorMessage2); + auto loc = vm.currentLocation; + printConsole(loc.line, ":", loc.pos, ":", parser.getLine(loc)); + } + catch(Throwable t) + { + writeln(t); + } + continue; + } + catch(Throwable t) + { + try + { + printConsole(t.to!string); + writeln(t); + printConsole(parser.getLine(vm.currentLocation)); + } + catch(Throwable t) + { + writeln(t); + } + continue; + } vm.dump(); running = true; }