diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index 071b162..f081e33 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -23,12 +23,6 @@ struct VMVariable this.index = index; } } -struct SourceLocation -{ - int line;//何行目 - int pos;//何文字目 - byte slot;//スロット -} class VM { DataTable globalDataTable; @@ -43,8 +37,9 @@ class VM int[wstring] globalLabel; int bp; PetitComputer petitcomputer; + DebugInfo debugInfo; this(Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/, - int[wstring] globalLabel) + int[wstring] globalLabel, DebugInfo dinfo) { this.code = code; this.stack = new Value[16384]; @@ -58,6 +53,7 @@ class VM this.functions = functions; this.globalDataTable = gdt; this.globalLabel = globalLabel; + this.debugInfo = dinfo; } Code getCurrent() { @@ -75,6 +71,10 @@ class VM stderr.writeln("CompilerBug?:stack"); } } + SourceLocation currentLocation() + { + return debugInfo.getLocationByAddress(pc); + } void init(PetitComputer petitcomputer) { this.petitcomputer = petitcomputer; diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index d1f84a7..b616a88 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -6,6 +6,26 @@ import otya.smilebasic.type; import otya.smilebasic.error; import otya.smilebasic.systemvariable; import std.stdio; +class DebugInfo +{ + int old; + std.container.Array!SourceLocation location; + this() + { + } + void addLocation(SourceLocation loc, Code[] code) + { + for(int i = 0; i < code.length - old; i++) + { + location ~= loc; + } + old = location.length; + } + SourceLocation getLocationByAddress(int addr) + { + return location[addr]; + } +} class Scope { GotoAddr breakAddr; @@ -152,8 +172,10 @@ class Compiler } } Statements statements; + DebugInfo debugInfo; this(Statements statements) { + this.debugInfo = new DebugInfo; this.statements = statements; code = new Code[0]; global["DATE$"] = VMVariable(-1); @@ -930,6 +952,7 @@ class Compiler default: stderr.writeln("Compile:NotImpl ", i.type); } + this.debugInfo.addLocation(i.location, code); } VM compile() { @@ -1007,7 +1030,7 @@ class Compiler code[i] = new RestoreCode(s.data.label[restore.label], s.data); } } - return new VM(code, globalIndex + 1, global, functions, s.data, globalLabel); + return new VM(code, globalIndex + 1, global, functions, s.data, globalLabel, debugInfo); } } diff --git a/SMILEBASIC/node.d b/SMILEBASIC/node.d index 6490540..1f98d09 100644 --- a/SMILEBASIC/node.d +++ b/SMILEBASIC/node.d @@ -45,6 +45,8 @@ enum NodeType abstract class Node { NodeType type; + //式は複数行に渡って描けないのでStatementに置くべき + SourceLocation location; } abstract class Expression : Node { @@ -52,8 +54,9 @@ abstract class Expression : Node class Constant : Expression { Value value; - this(Value v) + this(Value v, SourceLocation loc) { + super.location = loc; this.type = NodeType.Constant; this.value = v; } @@ -63,20 +66,23 @@ class BinaryOperator : Expression Expression item1; TokenType operator; Expression item2; - this(BinaryOperator bop) + this(BinaryOperator bop, SourceLocation loc) { + super.location = loc; this.type = NodeType.BinaryOperator; this.item1 = bop.item1; this.operator = bop.operator; this.item2 = bop.item2; } - this(Expression i1) + this(Expression i1, SourceLocation loc) { + super.location = loc; this.type = NodeType.BinaryOperator; this.item1 = i1; } - this(Expression i1, TokenType o, Expression i2) + this(Expression i1, TokenType o, Expression i2, SourceLocation loc) { + super.location = loc; this.type = NodeType.BinaryOperator; this.item1 = i1; this.operator = o; @@ -87,8 +93,9 @@ class UnaryOperator : Expression { TokenType operator; Expression item; - this(TokenType o, Expression i) + this(TokenType o, Expression i, SourceLocation loc) { + super.location = loc; this.type = NodeType.UnaryOperator; this.operator = o; this.item = i; @@ -97,8 +104,9 @@ class UnaryOperator : Expression class Variable : Expression { wstring name; - this(wstring n) + this(wstring n, SourceLocation loc) { + super.location = loc; this.type = NodeType.Variable; this.name = n; } @@ -107,8 +115,9 @@ class CallFunction : Expression { wstring name; Expression[] args; - this(wstring n) + this(wstring n, SourceLocation loc) { + super.location = loc; this.type = NodeType.CallFunction; this.name = n; args = new Expression[0]; @@ -120,8 +129,9 @@ class CallFunction : Expression } class VoidExpression : Expression { - this() + this(SourceLocation loc) { + super.location = loc; this.type = NodeType.VoidExpression; } } @@ -132,8 +142,9 @@ abstract class Statement : Node class Statements : Statement { Statement[] statements; - this() + this(SourceLocation loc) { + super.location = loc; this.type = NodeType.Statements; statements = new Statement[0]; } @@ -176,8 +187,9 @@ struct PrintArgument class Print : Statement { PrintArgument[] args; - this() + this(SourceLocation loc) { + super.location = loc; this.type = NodeType.Print; args = new PrintArgument[0]; } @@ -198,8 +210,9 @@ class Assign : Statement { wstring name; Expression expression; - this(wstring name, Expression expr) + this(wstring name, Expression expr, SourceLocation loc) { + super.location = loc; this.type = NodeType.Assign; this.name = name; this.expression = expr; @@ -208,8 +221,9 @@ class Assign : Statement class Label : Statement { wstring label; - this(wstring name) + this(wstring name, SourceLocation loc) { + super.location = loc; this.type = NodeType.Label; this.label = name; } @@ -217,14 +231,16 @@ class Label : Statement class Goto : Statement { wstring label; - this(wstring name) + this(wstring name, SourceLocation loc) { + super.location = loc; this.type = NodeType.Goto; this.label = name; } Expression labelexpr; - this(Expression expr) + this(Expression expr, SourceLocation loc) { + super.location = loc; this.type = NodeType.Goto; this.labelexpr = expr; } @@ -234,8 +250,9 @@ class If : Statement Expression condition; Statements then; Statements else_; - this(Expression condition, Statements t, Statements e) + this(Expression condition, Statements t, Statements e, SourceLocation loc) { + super.location = loc; this.type = NodeType.If; this.condition = condition; this.then = t; @@ -252,16 +269,18 @@ class For : Statement Expression toExpression; Expression stepExpression; Statements statements; - this(Assign assign, Expression toExpression, Expression stepExpression, Statements statements) + this(Assign assign, Expression toExpression, Expression stepExpression, Statements statements, SourceLocation loc) { + super.location = loc; this.type = NodeType.For; this.initExpression = assign; this.toExpression = toExpression; this.stepExpression = stepExpression; this.statements = statements; } - this(Assign assign, Expression toExpression, Statements statements) + this(Assign assign, Expression toExpression, Statements statements, SourceLocation loc) { + super.location = loc; this.type = NodeType.For; this.initExpression = assign; this.toExpression = toExpression; @@ -272,14 +291,16 @@ class For : Statement class Gosub : Statement { wstring label; - this(wstring name) + this(wstring name, SourceLocation loc) { + super.location = loc; this.type = NodeType.Gosub; this.label = name; } Expression labelexpr; - this(Expression expr) + this(Expression expr, SourceLocation loc) { + super.location = loc; this.type = NodeType.Gosub; this.labelexpr = expr; } @@ -287,38 +308,43 @@ class Gosub : Statement class Return : Statement { Expression expression; - this(Expression expression) + this(Expression expression, SourceLocation loc) { + super.location = loc; this.type = NodeType.Return; this.expression = expression; } } class End : Statement { - this() + this(SourceLocation loc) { + super.location = loc; this.type = NodeType.End; } } class Break : Statement { - this() + this(SourceLocation loc) { + super.location = loc; this.type = NodeType.Break; } } class Continue : Statement { - this() + this(SourceLocation loc) { + super.location = loc; this.type = NodeType.Continue; } } class Var : Statement { Statement[] define; - this() + this(SourceLocation loc) { + super.location = loc; this.type = NodeType.Var; this.define = new Statement[0]; } @@ -335,8 +361,9 @@ class DefineVariable : Statement { wstring name; Expression expression; - this(wstring name, Expression expr) + this(wstring name, Expression expr, SourceLocation loc) { + super.location = loc; this.type = NodeType.DefineVariable; this.name = name; this.expression = expr; @@ -346,8 +373,9 @@ class DefineArray : Statement { wstring name; IndexExpressions dim; - this(wstring name, IndexExpressions dim) + this(wstring name, IndexExpressions dim, SourceLocation loc) { + super.location = loc; this.type = NodeType.DefineArray; this.name = name; this.dim = dim; @@ -356,8 +384,9 @@ class DefineArray : Statement class IndexExpressions : Expression { Expression[] expressions; - this() + this(SourceLocation loc) { + super.location = loc; this.type = NodeType.IndexExpressions; this.expressions = new Expression[0]; } @@ -371,8 +400,9 @@ class ArrayAssign : Statement wstring name; IndexExpressions indexExpression; Expression assignExpression; - this(wstring name, IndexExpressions expr, Expression assign) + this(wstring name, IndexExpressions expr, Expression assign, SourceLocation loc) { + super.location = loc; this.type = NodeType.ArrayAssign; this.name = name; this.indexExpression = expr; @@ -386,14 +416,16 @@ class DefineFunction : Statement wstring name; Statements functionBody; bool returnExpr; - this(wstring name, bool returnExpr) + this(wstring name, bool returnExpr, SourceLocation loc) { + super.location = loc; this.type = NodeType.DefineFunction; this.name = name; this.returnExpr = returnExpr; } - this(wstring name) + this(wstring name, SourceLocation loc) { + super.location = loc; this.type = NodeType.DefineFunction; this.name = name; this.returnExpr = false; @@ -412,8 +444,9 @@ class CallFunctionStatement : Statement wstring name; Expression[] args; wstring[] outVariable; - this(wstring n) + this(wstring n, SourceLocation loc) { + super.location = loc; this.type = NodeType.CallFunctionStatement; this.name = n; args = new Expression[0]; @@ -431,8 +464,9 @@ class While : Statement { Expression condExpression; Statements statements; - this(Expression condExpression, Statements statements) + this(Expression condExpression, Statements statements, SourceLocation loc) { + super.location = loc; this.type = NodeType.While; this.condExpression = condExpression; this.statements = statements; @@ -442,8 +476,9 @@ class Inc : Statement { wstring name; Expression expression; - this(wstring name, Expression expr) + this(wstring name, Expression expr, SourceLocation loc) { + super.location = loc; this.type = NodeType.Inc; this.name = name; this.expression = expr; @@ -452,8 +487,9 @@ class Inc : Statement class Data : Statement { Value[] data; - this() + this(SourceLocation loc) { + super.location = loc; this.type = NodeType.Data; this.data = new Value[0]; } @@ -465,8 +501,9 @@ class Data : Statement class Read : Statement { Expression[] variables; - this() + this(SourceLocation loc) { + super.location = loc; this.type = NodeType.Read; } void addVariable(Expression lvalue) @@ -477,8 +514,9 @@ class Read : Statement class Restore : Statement { Expression label; - this(Expression label) + this(Expression label, SourceLocation loc) { + super.location = loc; this.label = label; this.type = NodeType.Restore; } @@ -488,8 +526,9 @@ class On : Statement Expression condition; bool isGosub; wstring[] labels; - this(Expression expr, bool isgosub) + this(Expression expr, bool isgosub, SourceLocation loc) { + super.location = loc; this.condition = expr; this.isGosub = isgosub; this.labels = new wstring[0]; @@ -505,8 +544,9 @@ class Input : Statement Expression message; bool question; Expression[] variables; - this(Expression message, bool question) + this(Expression message, bool question, SourceLocation loc) { + super.location = loc; this.message = message; this.question = question; this.variables = new Expression[0]; diff --git a/SMILEBASIC/parser.d b/SMILEBASIC/parser.d index 4c938ed..7e31379 100644 --- a/SMILEBASIC/parser.d +++ b/SMILEBASIC/parser.d @@ -85,7 +85,9 @@ class Lexical { return c == '$' || c == '%' || c == '#'; } + SourceLocation location; Token token; + private int pos; void popFront() { if(empty()) @@ -316,9 +318,13 @@ class Lexical i++; } } + pos = i; } break; } + this.location.pos = i - this.pos; + this.location.line = line; + this.location.pos2 = index - 1; index = i; } Token front() @@ -367,6 +373,15 @@ unittest } class Parser { + wstring getLine(SourceLocation loc) + { + import std.string; + int mae = code[0 .. loc.pos2].lastIndexOf('\n'); + mae++; + int ushiro = code[mae..$].indexOf('\n'); + if(ushiro == -1) ushiro = code.length; + return code[mae .. mae + ushiro]; + } wstring code; Lexical lex; this(wstring input) @@ -488,7 +503,7 @@ class Parser Statements parseProgram() { lex.popFront(); - auto statements = new Statements(); + auto statements = new Statements(lex.location); while(!lex.empty()) { auto token = lex.front(); @@ -539,7 +554,7 @@ class Parser syntaxError(); return null; } - DefineFunction node = new DefineFunction(token.value.stringValue); + DefineFunction node = new DefineFunction(token.value.stringValue, lex.location); lex.popFront(); token = lex.front(); if(token.type == TokenType.LParen) @@ -630,7 +645,7 @@ class Parser } Statements functionStatements() { - auto statements = new Statements(); + auto statements = new Statements(lex.location); while(true) { auto type = lex.front().type; @@ -651,7 +666,7 @@ class Parser } Statements ifStatements() { - auto statements = new Statements(); + auto statements = new Statements(lex.location); bool flag = true; while(!lex.empty()) { @@ -662,7 +677,7 @@ class Parser if(type == TokenType.Endif) break; if(type == TokenType.Label) { - statements.addStatement(new Goto(lex.front.value.stringValue)); + statements.addStatement(new Goto(lex.front.value.stringValue, lex.location)); lex.popFront; continue; } @@ -676,7 +691,7 @@ class Parser } Statements multilineIfStatements() { - auto statements = new Statements(); + auto statements = new Statements(lex.location); while(!lex.empty()) { auto type = lex.front().type; @@ -692,7 +707,7 @@ class Parser } Statements forStatements() { - auto statements = new Statements(); + auto statements = new Statements(lex.location); while(!lex.empty()) { auto type = lex.front().type; @@ -722,7 +737,7 @@ class Parser } Statements whileStatements() { - auto statements = new Statements(); + auto statements = new Statements(lex.location); while(!lex.empty()) { auto type = lex.front().type; @@ -774,7 +789,7 @@ class Parser return node; } //命令呼び出し - auto func = new CallFunctionStatement(name); + auto func = new CallFunctionStatement(name, lex.location); node = func; bool oldcomma; while(true) @@ -783,7 +798,7 @@ class Parser if(token.type == TokenType.Comma) { - func.addArg(new VoidExpression()); + func.addArg(new VoidExpression(lex.location)); lex.popFront(); token = lex.front(); } @@ -827,32 +842,32 @@ class Parser case TokenType.NewLine: break; case TokenType.Label: - node = new Label(token.value.stringValue); + node = new Label(token.value.stringValue, lex.location); break; case TokenType.Goto: lex.popFront(); token = lex.front(); if(token.type == TokenType.Label) - node = new Goto(token.value.stringValue); + node = new Goto(token.value.stringValue, lex.location); else { auto e = expression(); if(!e) syntaxError(); - node = new Goto(e); + node = new Goto(e, lex.location); } break; case TokenType.Gosub: lex.popFront(); token = lex.front(); if(token.type == TokenType.Label) - node = new Gosub(token.value.stringValue); + node = new Gosub(token.value.stringValue, lex.location); else { auto e = expression(); if(!e) syntaxError(); - node = new Gosub(e); + node = new Gosub(e, lex.location); } break; case TokenType.If: @@ -864,21 +879,21 @@ class Parser lex.popFront(); if(isFuncReturnExpr) { - node = new Return(expression()); + node = new Return(expression(), lex.location); } else { - node = new Return(null); + node = new Return(null, lex.location); } return node; case TokenType.End: - node = new End(); + node = new End(lex.location); break; case TokenType.Break: - node = new Break(); + node = new Break(lex.location); break; case TokenType.Continue: - node = new Continue(); + node = new Continue(lex.location); break; case TokenType.Var: lex.popFront(); @@ -935,7 +950,7 @@ class Parser auto token = lex.front(); if(token.type == TokenType.Semicolon || (token.type == TokenType.Comma && !isLValue(message))) { - Input input = new Input(message, token.type == TokenType.Semicolon); + Input input = new Input(message, token.type == TokenType.Semicolon, lex.location); do { lex.popFront(); @@ -956,7 +971,7 @@ class Parser syntaxError(); return null; } - Input input = new Input(null, true); + Input input = new Input(null, true, lex.location); input.addVariable(message); do { @@ -982,11 +997,11 @@ class Parser On on; if(token.type == TokenType.Gosub) { - on = new On(cond, true);//gosub + on = new On(cond, true, lex.location);//gosub } else if(token.type == TokenType.Goto) { - on = new On(cond, false);//gosub + on = new On(cond, false, lex.location);//gosub } else { @@ -1011,7 +1026,7 @@ class Parser } Data dataStatement() { - Data data = new Data(); + Data data = new Data(lex.location); lex.popFront(); auto token = lex.front(); while(true) @@ -1051,7 +1066,7 @@ class Parser } Read readStatement() { - Read read = new Read(); + Read read = new Read(lex.location); Token token; do { @@ -1075,7 +1090,7 @@ class Parser syntaxError(); return null; } - return new Restore(label); + return new Restore(label, lex.location); } Inc incStatement() { @@ -1105,17 +1120,17 @@ class Parser } else { - expr = new Constant(Value(1)); + expr = new Constant(Value(1), lex.location); } if(dec) { - expr = new BinaryOperator(new Constant(Value(0)), TokenType.Minus, expr); + expr = new BinaryOperator(new Constant(Value(0), lex.location), TokenType.Minus, expr, lex.location); } - return new Inc(var, expr); + return new Inc(var, expr, lex.location); } IndexExpressions indexExpressions() { - IndexExpressions ie = new IndexExpressions(); + IndexExpressions ie = new IndexExpressions(lex.location); int count = 0; while(true) { @@ -1160,12 +1175,12 @@ class Parser lex.popFront(); auto expr = expression(); token = lex.front(); - auto node = new ArrayAssign(name, ie, expr); + auto node = new ArrayAssign(name, ie, expr, lex.location); return node; } Statement var() { - Var var = new Var(); + Var var = new Var(lex.location); Token token; while(true) { @@ -1215,7 +1230,7 @@ class Parser if(token.type != TokenType.RBracket) return null; lex.popFront(); - DefineArray ary = new DefineArray(name, dim); + DefineArray ary = new DefineArray(name, dim, lex.location); return ary; } else @@ -1228,7 +1243,7 @@ class Parser token = lex.front(); } } - DefineVariable node = new DefineVariable(name, expr); + DefineVariable node = new DefineVariable(name, expr, lex.location); return node; } For forStatement() @@ -1263,11 +1278,11 @@ class Parser else { //とりあえず - step = new Constant(Value(1)); + step = new Constant(Value(1), lex.location); } token = lex.front(); Statements statements = forStatements(); - node = new For(init, to, step, statements); + node = new For(init, to, step, statements, lex.location); return node; } While whileStatement() @@ -1280,7 +1295,7 @@ class Parser return null; } Statements statements = whileStatements(); - auto node = new While(expr, statements); + auto node = new While(expr, statements, lex.location); return node; } If if_() @@ -1340,7 +1355,7 @@ class Parser else_ = ifStatements(); } } - auto if_ = new If(expr, then, else_); + auto if_ = new If(expr, then, else_, lex.location); return if_; } Assign assign(wstring name) @@ -1349,12 +1364,12 @@ class Parser auto token = lex.front();//=の次 Expression expr = expression(); if(expr is null) return null; - auto a = new Assign(name, expr); + auto a = new Assign(name, expr, lex.location); return a; } Print print() { - auto print = new Print(); + auto print = new Print(lex.location); bool addline = true; lex.popFront(); auto token = lex.front(); @@ -1429,7 +1444,7 @@ class Parser auto token = lex.front(); if(order == getOPRank(token.type)) { - BinaryOperator op = new BinaryOperator(exp); + BinaryOperator op = new BinaryOperator(exp, lex.location); while(order == getOPRank(token.type)) { auto tt = token.type; @@ -1451,7 +1466,7 @@ class Parser write(tt, " "); if(order == getOPRank(token.type)) { - BinaryOperator op2 = new BinaryOperator(op); + BinaryOperator op2 = new BinaryOperator(op, lex.location); op.item1 = op2; } version(none)stdout.flush(); @@ -1470,14 +1485,14 @@ class Parser case TokenType.Integer: version(none)write(token.value.integerValue, ' '); version(none)stdout.flush(); - node = new Constant(token.value); + node = new Constant(token.value, lex.location); break; case TokenType.Iden: if(!lex.empty()) lex.popFront(); if(lex.front().type == TokenType.LParen) { - auto func = new CallFunction(token.value.stringValue); + auto func = new CallFunction(token.value.stringValue, lex.location); node = func; //関数呼び出しだった while(true) @@ -1488,7 +1503,7 @@ class Parser if(token.type == TokenType.RParen) break; if(token.type == TokenType.Comma) { - func.addArg(new VoidExpression()); + func.addArg(new VoidExpression(lex.location)); lex.popFront(); token = lex.front(); } @@ -1499,7 +1514,7 @@ class Parser } else { - return new Variable(token.value.stringValue); + return new Variable(token.value.stringValue, lex.location); } break; case TokenType.LParen: @@ -1512,18 +1527,18 @@ class Parser break; case TokenType.Label://3.1 //文字列リテラル - node = new Constant(token.value); + node = new Constant(token.value, lex.location); break; case TokenType.Minus: //TODO:UnaryOperatorの実装 //とりあえず0-exprを作成 lex.popFront(); - node = new BinaryOperator(new Constant(Value(0)), TokenType.Minus, factor()); + node = new BinaryOperator(new Constant(Value(0), lex.location), TokenType.Minus, factor(), lex.location); return node; case TokenType.LogicalNot: case TokenType.Not: lex.popFront(); - node = new UnaryOperator(token.type, factor()); + node = new UnaryOperator(token.type, factor(), lex.location); return node; default: return node; diff --git a/SMILEBASIC/petitcomputer.d b/SMILEBASIC/petitcomputer.d index 6b8278b..5e0a094 100644 --- a/SMILEBASIC/petitcomputer.d +++ b/SMILEBASIC/petitcomputer.d @@ -1052,11 +1052,11 @@ class PetitComputer parser = new Parser( //readText("./SYS/GAME6TALK.TXT").to!wstring //readText("./SYS/GAME7EXPAD.TXT").to!wstring - readText("./SYS/GAME4SHOOTER.TXT").to!wstring + //readText("./SYS/GAME4SHOOTER.TXT").to!wstring //readText("./SYS/GAME2RPG.TXT").to!wstring //readText("./SYS/GAME1DOTRC.TXT").to!wstring //readText(input("LOAD PROGRAM:", true).to!string).to!wstring - //readText("./SYS/EX8TECDEMO.TXT").to!wstring + readText("./SYS/EX8TECDEMO.TXT").to!wstring //readText("./SYS/EX1TEXT.TXT").to!wstring //readText("FIZZBUZZ.TXT").to!wstring //readText("TEST.TXT").to!wstring @@ -1166,6 +1166,8 @@ class PetitComputer //gbox(0, 78, 78, 40, 40, RGB(255, 255, 0)); int startcnt = SDL_GetTicks(); float frame = 1000f / 60f; + typeof(vm.currentLocation()) loc; + debug bool trace = false; while (true) { uint elapse; @@ -1178,6 +1180,11 @@ class PetitComputer { //writefln("%04X:%s", vm.pc, vm.getCurrent); running = vm.runStep(); + debug if(trace && loc.line != vm.currentLocation.line) + { + loc = vm.currentLocation; + printConsole(loc.line, ":", loc.pos, ":", parser.getLine(loc)); + } } } catch(SmileBasicError sbe) @@ -1190,9 +1197,12 @@ class PetitComputer //printConsole(sbe.to!string); writeln(sbe.to!string); writeln(sbe.getErrorMessage2); + loc = vm.currentLocation; + printConsole(loc.line, ":", loc.pos, ":", parser.getLine(loc)); } - catch + catch(Throwable t) { + writeln(t); } } catch(Throwable t) @@ -1202,9 +1212,11 @@ class PetitComputer { printConsole(t.to!string); writeln(t); + printConsole(parser.getLine(vm.currentLocation)); } - catch + catch(Throwable t) { + writeln(t); } } //elapse = SDL_GetTicks() - startTicks; diff --git a/SMILEBASIC/token.d b/SMILEBASIC/token.d index 8c88da1..df4dadf 100644 --- a/SMILEBASIC/token.d +++ b/SMILEBASIC/token.d @@ -81,3 +81,9 @@ struct Token type = t; } } +struct SourceLocation +{ + int line;//何行目 + int pos;//何文字目 + int pos2;//全体から何文字目 +}