From 4c7487bb31d150c6c9305ee1dd514e8a37d5089a Mon Sep 17 00:00:00 2001 From: otya128 Date: Wed, 19 Aug 2015 13:02:02 +0900 Subject: [PATCH] =?UTF-8?q?DATA,READ=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/TEST.txt | 11 +++++++++-- SMILEBASIC/VM.d | 21 ++++++++++++++++++++- SMILEBASIC/compiler.d | 21 ++++++++++++++++++++- SMILEBASIC/error.d | 8 ++++++++ SMILEBASIC/node.d | 21 +++++++++++++++++++++ SMILEBASIC/parser.d | 34 +++++++++++++++++++++++++++++++++- 6 files changed, 111 insertions(+), 5 deletions(-) diff --git a/SMILEBASIC/TEST.txt b/SMILEBASIC/TEST.txt index 0d80b75..8fa3d34 100644 --- a/SMILEBASIC/TEST.txt +++ b/SMILEBASIC/TEST.txt @@ -79,11 +79,18 @@ DEF ONGOSUBTEST RETURN @4 END +@DATA_1 +DATA "A",1,2,3,4 +READ DATA$,_1,_2 +READ _3,_4 +ASSERT__ DATA$=="A", "DATA" +ASSERT__ _1==1, "DATA" +ASSERT__ _2==2, "DATA" +ASSERT__ _3==3, "DATA" +ASSERT__ _4==4, "DATA" INPUT$="HELLO" INPUT INPUT$,IN ?INPUT$,IN -@DATA_1 -DATA "A",1,2,3,4 LOCATE 10, COLOR 1,15 PRINT "テスト正常終了" \ No newline at end of file diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index 8b420d3..af5bd36 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -20,6 +20,7 @@ struct VMVariable } class VM { + DataTable globalDataTable; Code[] code; int stacki; int pc; @@ -29,7 +30,7 @@ class VM Function[wstring] functions; int bp; PetitComputer petitcomputer; - this(Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions) + this(Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/) { this.code = code; this.stack = new Value[16384]; @@ -40,6 +41,7 @@ class VM this.global[v.index] = Value(v.type); } this.functions = functions; + this.globalDataTable = gdt; } void run() { @@ -1120,3 +1122,20 @@ class InputCode : Code } while(error); } } +class ReadCode : Code +{ + int count; + this(int count) + { + this.count = count; + } + override void execute(VM vm) + { + for(int i = 0; i < count; i++) + { + Value data; + vm.globalDataTable.read(data, vm); + vm.push(data); + } + } +} diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index b6affb3..1f82eff 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -32,6 +32,7 @@ class DataTable { Value[] data; int[wstring] label; + int dataIndex; void addData(Value data) { this.data ~= data; @@ -40,6 +41,13 @@ class DataTable { this.label[label] = data.length; } + void read(out Value value, VM vm) + { + if(dataIndex >= data.length) + throw new OutOfDATA(); + value = data[dataIndex]; + dataIndex++; + } } class Function { @@ -618,6 +626,14 @@ class Compiler compilePopVar(i, sc); } } + void compileRead(Read read, Scope sc) + { + genCode(new ReadCode(read.variables.length)); + foreach_reverse(i; read.variables) + { + compilePopVar(i, sc); + } + } void compileStatement(Statement i, Scope s) { switch(i.type) @@ -781,6 +797,9 @@ class Compiler s.data.addData(j); } break; + case NodeType.Read: + compileRead(cast(Read)i, s); + break; case NodeType.On: compileOn(cast(On)i, s); break; @@ -854,7 +873,7 @@ class Compiler } } } - return new VM(code, globalIndex + 1, global, functions); + return new VM(code, globalIndex + 1, global, functions, s.data); } } diff --git a/SMILEBASIC/error.d b/SMILEBASIC/error.d index 212ce7f..2901aa5 100644 --- a/SMILEBASIC/error.d +++ b/SMILEBASIC/error.d @@ -43,6 +43,14 @@ class TypeMismatch : SmileBasicError super("Type mismatch"); } } +class OutOfDATA : SmileBasicError +{ + this() + { + this.errnum = 13; + super("Out of DATA"); + } +} class DuplicateVariable : SmileBasicError { this() diff --git a/SMILEBASIC/node.d b/SMILEBASIC/node.d index b33df16..c6885f8 100644 --- a/SMILEBASIC/node.d +++ b/SMILEBASIC/node.d @@ -450,6 +450,27 @@ class Data : Statement data ~= v; } } +class Read : Statement +{ + Expression[] variables; + this() + { + this.type = NodeType.Read; + } + void addVariable(Expression lvalue) + { + variables ~= lvalue; + } +} +class Restore : Statement +{ + Expression label; + this(Expression label) + { + this.label = label; + this.type = NodeType.Restore; + } +} class On : Statement { Expression condition; diff --git a/SMILEBASIC/parser.d b/SMILEBASIC/parser.d index 0f03189..1c34387 100644 --- a/SMILEBASIC/parser.d +++ b/SMILEBASIC/parser.d @@ -118,7 +118,7 @@ class Lexical token = Token(TokenType.Integer, Value(num)); break; } - if(c.isAlpha()) + if(c.isAlpha() || c == '_') { wstring iden; for(;i < code.length;i++) @@ -787,6 +787,10 @@ class Parser return incStatement(); case TokenType.Data: return dataStatement(); + case TokenType.Read: + return readStatement(); + case TokenType.Restore: + return restoreStatement(); case TokenType.On: node = onStatement(); break; @@ -925,6 +929,34 @@ class Parser } return data; } + Read readStatement() + { + Read read = new Read(); + Token token; + do + { + lex.popFront(); + auto expr = expression(); + if(!expr || !isLValue(expr)) + { + syntaxError(); + } + read.addVariable(expr); + token = lex.front(); + } while(token.type == TokenType.Comma); + return read; + } + Restore restoreStatement() + { + lex.popFront(); + auto label = expression(); + if(!label) + { + syntaxError(); + return null; + } + return new Restore(label); + } Inc incStatement() { auto token = lex.front();