diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index f3cf3ff..da684c0 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -31,6 +31,11 @@ struct VMVariable } class VMSlot { + int index; + this(int index) + { + this.index = index; + } bool isUsed; DataTable globalDataTable; //2MBらしい @@ -64,7 +69,7 @@ class VM this.backTraceStack = new Trace[16384]; for(int i = 0; i < slots.length; i++) { - slots[i] = new VMSlot(); + slots[i] = new VMSlot(i); } } int currentSlotNumber() @@ -102,6 +107,7 @@ class VM { if (f.isCommon) { + f.isDead = true; commonFunctions.remove(f.name); } } @@ -123,6 +129,7 @@ class VM if (f.name in commonFunctions) throw new DuplicateFunction(slot, dinfo.getLocationByAddress(f.address)); commonFunctions[f.name] = f; + f.slot = s; } } s.globalDataTable = gdt; @@ -209,8 +216,9 @@ class VM void pushpc() { Value value; - value.type = ValueType.InternalAddress; - value.integerValue = pc; + value.type = ValueType.InternalSlotAddress; + value.internalAddress.address = pc; + value.internalAddress.slot = cast(byte)currentSlotNumber; push(value); } void push(ref Value value) @@ -1374,6 +1382,8 @@ class CallFunctionCode : Code void resolve(VM vm) { func = vm.currentSlot.functions.get(name, null); + if (!func) + func = vm.commonFunctions.get(name, null); if (!func) throw new SyntaxError(name); } @@ -1384,6 +1394,10 @@ class CallFunctionCode : Code //楽だし実行時に解決させる resolve(vm); } + if (func.isDead) + { + resolve(vm); + } if(func.argCount != this.argCount) { throw new IllegalFunctionCall(name.to!string); @@ -1392,6 +1406,10 @@ class CallFunctionCode : Code { throw new IllegalFunctionCall(name.to!string); } + if (func.isCommon) + { + vm.setCurrentSlot(func.slot.index); + } vm.pushBackTrace(name); //TODO:args auto bp = vm.stacki; @@ -1477,6 +1495,10 @@ class CallFunctionS : Code vm.stack[bp + v.index] = Value(v.type); } } + if (func.isCommon) + { + vm.setCurrentSlot(func.slot.index); + } } override void execute(VM vm) { @@ -1488,6 +1510,10 @@ class CallFunctionS : Code } auto name = vname.castDString.toUpper; Function func = vm.currentSlot.functions.get(name, null); + if (!func) + { + func = vm.commonFunctions.get(name, null); + } if(!func) { auto bfuncs = otya.smilebasic.builtinfunctions.BuiltinFunction.builtinFunctions.get(name, null); diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index 0cfec47..602cb8c 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -104,6 +104,8 @@ class Function bool returnExpr; int outArgCount; bool isCommon; + VMSlot slot;/*common function*/ + bool isDead;/*common function*/ /** 0:bp 1:pc diff --git a/SMILEBASIC/type.d b/SMILEBASIC/type.d index 6b36007..510475c 100644 --- a/SMILEBASIC/type.d +++ b/SMILEBASIC/type.d @@ -213,6 +213,8 @@ struct Value case ValueType.StringArray: return format("doublearray[%s]", length); case ValueType.InternalAddress: + return format("internal address address=0x%x", integerValue); + case ValueType.InternalSlotAddress: return format("internal address slot=%d, address=0x%x", internalAddress.slot, internalAddress.address); default: return type.to!string;