From 58cf9048a5884fe12ec7e3ac7ef857a22a16ef94 Mon Sep 17 00:00:00 2001 From: otya128 Date: Fri, 23 Dec 2016 22:08:46 +0900 Subject: [PATCH] Fix DATA --- SMILEBASIC/VM.d | 39 ++++++++++++++++++++++++++------------- SMILEBASIC/compiler.d | 13 ++----------- SMILEBASIC/parser.d | 4 ++-- SMILEBASIC/type.d | 21 +++++++++++++++++++++ 4 files changed, 51 insertions(+), 26 deletions(-) diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index a602b82..5db310b 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -37,7 +37,7 @@ class VMSlot this.index = index; } bool isUsed; - DataTable globalDataTable; + otya.smilebasic.type.Data globalData; //2MBらしい //Code code[2 * 1024 * 1024 / Code.sizeof]; Code[] code; @@ -132,7 +132,7 @@ class VM f.slot = s; } } - s.globalDataTable = gdt; + s.globalData = otya.smilebasic.type.Data(gdt, 0); s.globalLabel = globalLabel; s.debugInfo = dinfo; } @@ -162,6 +162,7 @@ class VM this.petitcomputer = petitcomputer; traceI = 0; bp = 0;//globalを実行なのでbaseは0(グローバル変数をスタックに取るようにしない限り)(挙動的にスタックに確保していなさそう) + currentData = this.currentSlot.globalData; } void processBreakPoint() { @@ -274,24 +275,25 @@ class VM } return "undefined variable"; } + otya.smilebasic.type.Data currentData;//DATAの位置は全スロット共通 Value readData() { Value value; - this.currentSlot.globalDataTable.read(value, this); + currentData.read(value, this); return value; } void restoreData(wstring label) { - this.currentSlot.globalDataTable.dataIndex = this.currentSlot.globalDataTable.label[label]; + currentData.index = currentData.table.label[label]; } int olddti; void pushDataIndex() { - olddti = this.currentSlot.globalDataTable.dataIndex; + olddti = this.currentSlot.globalData.index; } void popDataIndex() { - this.currentSlot.globalDataTable.dataIndex = olddti; + this.currentSlot.globalData.index = olddti; } void pushBackTrace(wstring name) { @@ -1339,6 +1341,14 @@ class ReturnFunction : Code vm.pop(bp); Value hae; vm.pop(hae); + if (hae.type != ValueType.Data) + { + throw new TypeMismatch(); + } + else + { + vm.currentData = hae.data; + } vm.stacki -= func.argCount; if(func.returnExpr) { @@ -1409,7 +1419,7 @@ class CallFunctionCode : Code vm.pushBackTrace(name); //TODO:args auto bp = vm.stacki; - vm.push(Value()); + vm.push(Value(vm.currentData)); vm.push(Value(vm.bp)); vm.pushpc;//vm.push(Value(vm.pc)); vm.bp = bp; @@ -1482,7 +1492,7 @@ class CallFunctionS : Code } //TODO:args auto bp = vm.stacki; - vm.push(Value()); + vm.push(Value(vm.currentData)); vm.push(Value(vm.bp)); vm.pushpc;//vm.push(Value(vm.pc)); vm.bp = bp; @@ -1765,7 +1775,7 @@ class ReadCode : Code for(int i = 0; i < count; i++) { Value data; - vm.currentSlot.globalDataTable.read(data, vm); + vm.currentData.read(data, vm); vm.push(data); } } @@ -1800,7 +1810,8 @@ class RestoreCode : Code } override void execute(VM vm) { - datatable.dataIndex = label; + vm.currentData.table = datatable; + vm.currentData.index = label; } override string toString(VM vm) { @@ -1838,11 +1849,13 @@ class RestoreExprCode : Code throw new TypeMismatch(); if (label.castDString in datatable.label) { - datatable.dataIndex = datatable.label[label.castDString]; + vm.currentData.table = datatable; + vm.currentData.index = datatable.label[label.castDString]; } - else if (label.castDString in vm.currentSlot.globalDataTable.label) + else if (label.castDString in vm.currentSlot.globalData.table.label) { - datatable.dataIndex = vm.currentSlot.globalDataTable.label[label.castDString]; + vm.currentData.table = vm.currentSlot.globalData.table; + vm.currentData.index = vm.currentSlot.globalData.table.label[label.castDString]; } else { diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index 65ecfb6..778cc47 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -73,8 +73,6 @@ class DataTable { Value[] data; int[wstring] label; - //dataIndexは関数ごとに別じゃないといけない - int dataIndex; void addData(Value data) { this.data ~= data; @@ -83,13 +81,6 @@ class DataTable { this.label[label] = cast(int)data.length; } - void read(out Value value, VM vm) - { - if(dataIndex >= data.length) - throw new OutOfDATA(); - value = data[dataIndex]; - dataIndex++; - } } class Function { @@ -1153,7 +1144,7 @@ class Compiler break; case NodeType.Data: { - auto data = cast(Data)i; + auto data = cast(otya.smilebasic.node.Data)i; foreach(j; data.data) s.data.addData(j.toSBImm); } @@ -1309,7 +1300,7 @@ class Compiler } else { - code[i] = new RestoreCode(label, s.data); + code[i] = new RestoreCode(label, restore.scope_.data); } } } diff --git a/SMILEBASIC/parser.d b/SMILEBASIC/parser.d index 7a317be..c0fafc3 100644 --- a/SMILEBASIC/parser.d +++ b/SMILEBASIC/parser.d @@ -1272,9 +1272,9 @@ class Parser } while(token.type == TokenType.Comma); return on; } - Data dataStatement() + otya.smilebasic.node.Data dataStatement() { - Data data = new Data(lex.location); + otya.smilebasic.node.Data data = new otya.smilebasic.node.Data(lex.location); lex.popFront(); auto token = lex.front(); while(true) diff --git a/SMILEBASIC/type.d b/SMILEBASIC/type.d index 510475c..0f0d63d 100644 --- a/SMILEBASIC/type.d +++ b/SMILEBASIC/type.d @@ -17,6 +17,21 @@ enum ValueType : byte DoubleReference, StringReference, StringArrayReference, + Data, +} +import otya.smilebasic.compiler; +import otya.smilebasic.vm; +struct Data +{ + DataTable table; + int index; + void read(out Value value, VM vm) + { + if(index >= table.data.length) + throw new OutOfDATA(); + value = table.data[index]; + index++; + } } struct VMAddress { @@ -40,6 +55,7 @@ struct Value ArrayReference!double doubleReference; ArrayReference!wchar stringReference; ArrayReference!(Array!wchar) stringArrayReference; + Data data; } this(int value) { @@ -108,6 +124,11 @@ struct Value this.type = ValueType.StringArrayReference; stringArrayReference = r; } + this(Data data) + { + this.type = ValueType.Data; + this.data = data; + } void castOp(ValueType type) { switch(type)