From a05c1558fa2a4058f91fa4ccab985b8076dbc68c Mon Sep 17 00:00:00 2001 From: otya128 Date: Fri, 23 Dec 2016 19:25:55 +0900 Subject: [PATCH] Implement EXEC --- SMILEBASIC/VM.d | 41 ++++++++++++++++++++++++++++++++++++++ SMILEBASIC/compiler.d | 7 +++++++ SMILEBASIC/error.d | 5 +++++ SMILEBASIC/petitcomputer.d | 26 ++++++++++++++---------- 4 files changed, 68 insertions(+), 11 deletions(-) diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index 7762a6b..745155d 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -2187,8 +2187,49 @@ class Exec : Code { override void execute(VM vm) { + import otya.smilebasic.project; Value arg; vm.pop(arg); + int slot; + if (arg.isString) + { + auto file = Projects.parseFileName(arg.castDString); + if (file.resource != Resource.program && file.resource == Resource.none) + { + throw new IllegalFunctionCall(); + } + if (file.hasResourceNumber && file.resourceNumber >= 4/*?*/) + { + throw new IllegalFunctionCall(); + } + if (!file.hasResourceNumber) + { + file.resourceNumber = vm.currentSlotNumber; + } + else + { + slot = file.resourceNumber; + } + wstring content; + if (vm.petitcomputer.project.loadFile(file.project, "TXT", file.name, content)) + vm.petitcomputer.slot[slot].load(content); + else + throw new LoadFailed();//TODO:DIALOG? + } + else if (arg.isNumber) + { + slot = arg.castInteger; + } + else + { + throw new TypeMismatch(); + } + import otya.smilebasic.parser; + auto parser = new Parser(cast(immutable)vm.petitcomputer.slot[slot].text); + auto compiler = parser.compiler; + compiler.compile(vm, slot); + vm.setCurrentSlot(slot); + vm.pc = 0 - 1; } } diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index 821778a..4f778e6 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -1336,6 +1336,13 @@ class Compiler registerSystemVariable(vm); return vm; } + void compile(VM vm, int slot) + { + isDirectMode = false; + this.vm = vm; + compileProgram(); + vm.loadSlot(slot, code, globalIndex + 1, global, functions, globalScope.data, globalLabel, debugInfo); + } } unittest diff --git a/SMILEBASIC/error.d b/SMILEBASIC/error.d index 8484dc8..80d37c6 100644 --- a/SMILEBASIC/error.d +++ b/SMILEBASIC/error.d @@ -50,6 +50,11 @@ class SyntaxError : SmileBasicError } class IllegalFunctionCall : SmileBasicError { + this() + { + this.errnum = 4; + super("Illegal function call"); + } this(string func) { this.errnum = 4; diff --git a/SMILEBASIC/petitcomputer.d b/SMILEBASIC/petitcomputer.d index b20f3e9..6a69767 100644 --- a/SMILEBASIC/petitcomputer.d +++ b/SMILEBASIC/petitcomputer.d @@ -164,6 +164,20 @@ struct Slot program.insertBack(l ~ '\n'); } } + wchar[] text() + { + import std.algorithm.iteration, std.outbuffer; + auto buffer = new OutBuffer(); + buffer.reserve(program.opSlice.map!"(a.length + 1) * 2".sum); + + foreach(line; program) + { + buffer.write(line); + } + ubyte[] progbuff = buffer.toBytes; + wchar[] progbuff2 = (cast(wchar*)progbuff.ptr)[0..progbuff.length / 2]; + return progbuff2; + } } struct Size { @@ -1046,17 +1060,7 @@ class PetitComputer int oldpc; void runSlot(int lot) { - import std.algorithm.iteration, std.outbuffer; - auto buffer = new OutBuffer(); - buffer.reserve(slot[lot].program.opSlice.map!"(a.length + 1) * 2".sum); - - foreach(line; slot[lot].program) - { - buffer.write(line); - } - ubyte[] progbuff = buffer.toBytes; - wchar[] progbuff2 = (cast(wchar*)progbuff.ptr)[0..progbuff.length / 2]; - parser = new Parser(cast(wstring)progbuff2); + parser = new Parser(cast(wstring)slot[lot].text); try { vm = parser.compile();