From f1b5a3852e5103ec2e33ff79bbaae643c80753cd Mon Sep 17 00:00:00 2001 From: otya128 Date: Fri, 23 Dec 2016 19:37:33 +0900 Subject: [PATCH] Implement USE --- SMILEBASIC/VM.d | 31 +++++++++++++++++++++++++++++++ SMILEBASIC/compiler.d | 6 ++++-- SMILEBASIC/error.d | 10 ++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index 745155d..ba47de9 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -96,6 +96,15 @@ class VM void loadSlot(int slot, Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/, int[wstring] globalLabel, DebugInfo dinfo) { + //unload common function + if (slots[slot]) + foreach(f ; slots[slot].functions) + { + if (f.isCommon) + { + commonFunctions.remove(f.name); + } + } auto s = this.slots[slot]; s.isUsed = true; s.code = code; @@ -107,6 +116,15 @@ class VM s.global[v.index] = Value(v.type); } s.functions = functions; + foreach(f ; functions) + { + if (f.isCommon) + { + if (f.name in commonFunctions) + throw new DuplicateFunction(slot, dinfo.getLocationByAddress(f.address)); + commonFunctions[f.name] = f; + } + } s.globalDataTable = gdt; s.globalLabel = globalLabel; s.debugInfo = dinfo; @@ -2239,6 +2257,19 @@ class Use : Code { Value arg; vm.pop(arg); + int slot; + 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); } } diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index 4f778e6..0cfec47 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -103,6 +103,7 @@ class Function int[wstring] label; bool returnExpr; int outArgCount; + bool isCommon; /** 0:bp 1:pc @@ -110,7 +111,7 @@ class Function 3:data index 4:function pointer */ - this(int address, wstring name, bool returnExpr, int argCount) + this(int address, wstring name, bool returnExpr, int argCount, bool isCommon) { this.address = address; this.name = name; @@ -121,6 +122,7 @@ class Function { outArgCount = 1; } + this.isCommon = isCommon; } int getLocalVarIndex(wstring name, Compiler c) { @@ -866,7 +868,7 @@ class Compiler throw new CantUseFromDirectMode(); } auto skip = genCodeGoto(); - Function func = new Function(cast(int)this.code.length, node.name, node.returnExpr, cast(int)node.arguments.length); + Function func = new Function(cast(int)this.code.length, node.name, node.returnExpr, cast(int)node.arguments.length, node.isCommon); Scope sc = new Scope(func); foreach(wstring arg; node.arguments) { diff --git a/SMILEBASIC/error.d b/SMILEBASIC/error.d index 80d37c6..e2f6b91 100644 --- a/SMILEBASIC/error.d +++ b/SMILEBASIC/error.d @@ -2,6 +2,8 @@ module otya.smilebasic.error; import std.exception; import std.string; import std.conv; +import otya.smilebasic.token; + class SmileBasicError : Exception { int errnum; @@ -154,6 +156,14 @@ class DuplicateVariable : SmileBasicError super("Duplicate variable"); } } +class DuplicateFunction : SmileBasicError +{ + this(int slot, SourceLocation loc) + { + this.errnum = 19; + super(slot, loc.line, "Duplicate function"); + } +} class ReturnWithoutGosub : SmileBasicError { this()