1
0

位置情報を記録するようにした

This commit is contained in:
otya128
2015-08-30 12:33:54 +09:00
parent 9be57613f4
commit 87e86b6219
6 changed files with 196 additions and 100 deletions

View File

@@ -23,12 +23,6 @@ struct VMVariable
this.index = index; this.index = index;
} }
} }
struct SourceLocation
{
int line;//何行目
int pos;//何文字目
byte slot;//スロット
}
class VM class VM
{ {
DataTable globalDataTable; DataTable globalDataTable;
@@ -43,8 +37,9 @@ class VM
int[wstring] globalLabel; int[wstring] globalLabel;
int bp; int bp;
PetitComputer petitcomputer; PetitComputer petitcomputer;
DebugInfo debugInfo;
this(Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/, 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.code = code;
this.stack = new Value[16384]; this.stack = new Value[16384];
@@ -58,6 +53,7 @@ class VM
this.functions = functions; this.functions = functions;
this.globalDataTable = gdt; this.globalDataTable = gdt;
this.globalLabel = globalLabel; this.globalLabel = globalLabel;
this.debugInfo = dinfo;
} }
Code getCurrent() Code getCurrent()
{ {
@@ -75,6 +71,10 @@ class VM
stderr.writeln("CompilerBug?:stack"); stderr.writeln("CompilerBug?:stack");
} }
} }
SourceLocation currentLocation()
{
return debugInfo.getLocationByAddress(pc);
}
void init(PetitComputer petitcomputer) void init(PetitComputer petitcomputer)
{ {
this.petitcomputer = petitcomputer; this.petitcomputer = petitcomputer;

View File

@@ -6,6 +6,26 @@ import otya.smilebasic.type;
import otya.smilebasic.error; import otya.smilebasic.error;
import otya.smilebasic.systemvariable; import otya.smilebasic.systemvariable;
import std.stdio; 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 class Scope
{ {
GotoAddr breakAddr; GotoAddr breakAddr;
@@ -152,8 +172,10 @@ class Compiler
} }
} }
Statements statements; Statements statements;
DebugInfo debugInfo;
this(Statements statements) this(Statements statements)
{ {
this.debugInfo = new DebugInfo;
this.statements = statements; this.statements = statements;
code = new Code[0]; code = new Code[0];
global["DATE$"] = VMVariable(-1); global["DATE$"] = VMVariable(-1);
@@ -930,6 +952,7 @@ class Compiler
default: default:
stderr.writeln("Compile:NotImpl ", i.type); stderr.writeln("Compile:NotImpl ", i.type);
} }
this.debugInfo.addLocation(i.location, code);
} }
VM compile() VM compile()
{ {
@@ -1007,7 +1030,7 @@ class Compiler
code[i] = new RestoreCode(s.data.label[restore.label], s.data); 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);
} }
} }

View File

@@ -45,6 +45,8 @@ enum NodeType
abstract class Node abstract class Node
{ {
NodeType type; NodeType type;
//式は複数行に渡って描けないのでStatementに置くべき
SourceLocation location;
} }
abstract class Expression : Node abstract class Expression : Node
{ {
@@ -52,8 +54,9 @@ abstract class Expression : Node
class Constant : Expression class Constant : Expression
{ {
Value value; Value value;
this(Value v) this(Value v, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Constant; this.type = NodeType.Constant;
this.value = v; this.value = v;
} }
@@ -63,20 +66,23 @@ class BinaryOperator : Expression
Expression item1; Expression item1;
TokenType operator; TokenType operator;
Expression item2; Expression item2;
this(BinaryOperator bop) this(BinaryOperator bop, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.BinaryOperator; this.type = NodeType.BinaryOperator;
this.item1 = bop.item1; this.item1 = bop.item1;
this.operator = bop.operator; this.operator = bop.operator;
this.item2 = bop.item2; this.item2 = bop.item2;
} }
this(Expression i1) this(Expression i1, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.BinaryOperator; this.type = NodeType.BinaryOperator;
this.item1 = i1; 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.type = NodeType.BinaryOperator;
this.item1 = i1; this.item1 = i1;
this.operator = o; this.operator = o;
@@ -87,8 +93,9 @@ class UnaryOperator : Expression
{ {
TokenType operator; TokenType operator;
Expression item; Expression item;
this(TokenType o, Expression i) this(TokenType o, Expression i, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.UnaryOperator; this.type = NodeType.UnaryOperator;
this.operator = o; this.operator = o;
this.item = i; this.item = i;
@@ -97,8 +104,9 @@ class UnaryOperator : Expression
class Variable : Expression class Variable : Expression
{ {
wstring name; wstring name;
this(wstring n) this(wstring n, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Variable; this.type = NodeType.Variable;
this.name = n; this.name = n;
} }
@@ -107,8 +115,9 @@ class CallFunction : Expression
{ {
wstring name; wstring name;
Expression[] args; Expression[] args;
this(wstring n) this(wstring n, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.CallFunction; this.type = NodeType.CallFunction;
this.name = n; this.name = n;
args = new Expression[0]; args = new Expression[0];
@@ -120,8 +129,9 @@ class CallFunction : Expression
} }
class VoidExpression : Expression class VoidExpression : Expression
{ {
this() this(SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.VoidExpression; this.type = NodeType.VoidExpression;
} }
} }
@@ -132,8 +142,9 @@ abstract class Statement : Node
class Statements : Statement class Statements : Statement
{ {
Statement[] statements; Statement[] statements;
this() this(SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Statements; this.type = NodeType.Statements;
statements = new Statement[0]; statements = new Statement[0];
} }
@@ -176,8 +187,9 @@ struct PrintArgument
class Print : Statement class Print : Statement
{ {
PrintArgument[] args; PrintArgument[] args;
this() this(SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Print; this.type = NodeType.Print;
args = new PrintArgument[0]; args = new PrintArgument[0];
} }
@@ -198,8 +210,9 @@ class Assign : Statement
{ {
wstring name; wstring name;
Expression expression; Expression expression;
this(wstring name, Expression expr) this(wstring name, Expression expr, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Assign; this.type = NodeType.Assign;
this.name = name; this.name = name;
this.expression = expr; this.expression = expr;
@@ -208,8 +221,9 @@ class Assign : Statement
class Label : Statement class Label : Statement
{ {
wstring label; wstring label;
this(wstring name) this(wstring name, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Label; this.type = NodeType.Label;
this.label = name; this.label = name;
} }
@@ -217,14 +231,16 @@ class Label : Statement
class Goto : Statement class Goto : Statement
{ {
wstring label; wstring label;
this(wstring name) this(wstring name, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Goto; this.type = NodeType.Goto;
this.label = name; this.label = name;
} }
Expression labelexpr; Expression labelexpr;
this(Expression expr) this(Expression expr, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Goto; this.type = NodeType.Goto;
this.labelexpr = expr; this.labelexpr = expr;
} }
@@ -234,8 +250,9 @@ class If : Statement
Expression condition; Expression condition;
Statements then; Statements then;
Statements else_; 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.type = NodeType.If;
this.condition = condition; this.condition = condition;
this.then = t; this.then = t;
@@ -252,16 +269,18 @@ class For : Statement
Expression toExpression; Expression toExpression;
Expression stepExpression; Expression stepExpression;
Statements statements; 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.type = NodeType.For;
this.initExpression = assign; this.initExpression = assign;
this.toExpression = toExpression; this.toExpression = toExpression;
this.stepExpression = stepExpression; this.stepExpression = stepExpression;
this.statements = statements; 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.type = NodeType.For;
this.initExpression = assign; this.initExpression = assign;
this.toExpression = toExpression; this.toExpression = toExpression;
@@ -272,14 +291,16 @@ class For : Statement
class Gosub : Statement class Gosub : Statement
{ {
wstring label; wstring label;
this(wstring name) this(wstring name, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Gosub; this.type = NodeType.Gosub;
this.label = name; this.label = name;
} }
Expression labelexpr; Expression labelexpr;
this(Expression expr) this(Expression expr, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Gosub; this.type = NodeType.Gosub;
this.labelexpr = expr; this.labelexpr = expr;
} }
@@ -287,38 +308,43 @@ class Gosub : Statement
class Return : Statement class Return : Statement
{ {
Expression expression; Expression expression;
this(Expression expression) this(Expression expression, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Return; this.type = NodeType.Return;
this.expression = expression; this.expression = expression;
} }
} }
class End : Statement class End : Statement
{ {
this() this(SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.End; this.type = NodeType.End;
} }
} }
class Break : Statement class Break : Statement
{ {
this() this(SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Break; this.type = NodeType.Break;
} }
} }
class Continue : Statement class Continue : Statement
{ {
this() this(SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Continue; this.type = NodeType.Continue;
} }
} }
class Var : Statement class Var : Statement
{ {
Statement[] define; Statement[] define;
this() this(SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Var; this.type = NodeType.Var;
this.define = new Statement[0]; this.define = new Statement[0];
} }
@@ -335,8 +361,9 @@ class DefineVariable : Statement
{ {
wstring name; wstring name;
Expression expression; Expression expression;
this(wstring name, Expression expr) this(wstring name, Expression expr, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.DefineVariable; this.type = NodeType.DefineVariable;
this.name = name; this.name = name;
this.expression = expr; this.expression = expr;
@@ -346,8 +373,9 @@ class DefineArray : Statement
{ {
wstring name; wstring name;
IndexExpressions dim; IndexExpressions dim;
this(wstring name, IndexExpressions dim) this(wstring name, IndexExpressions dim, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.DefineArray; this.type = NodeType.DefineArray;
this.name = name; this.name = name;
this.dim = dim; this.dim = dim;
@@ -356,8 +384,9 @@ class DefineArray : Statement
class IndexExpressions : Expression class IndexExpressions : Expression
{ {
Expression[] expressions; Expression[] expressions;
this() this(SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.IndexExpressions; this.type = NodeType.IndexExpressions;
this.expressions = new Expression[0]; this.expressions = new Expression[0];
} }
@@ -371,8 +400,9 @@ class ArrayAssign : Statement
wstring name; wstring name;
IndexExpressions indexExpression; IndexExpressions indexExpression;
Expression assignExpression; 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.type = NodeType.ArrayAssign;
this.name = name; this.name = name;
this.indexExpression = expr; this.indexExpression = expr;
@@ -386,14 +416,16 @@ class DefineFunction : Statement
wstring name; wstring name;
Statements functionBody; Statements functionBody;
bool returnExpr; bool returnExpr;
this(wstring name, bool returnExpr) this(wstring name, bool returnExpr, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.DefineFunction; this.type = NodeType.DefineFunction;
this.name = name; this.name = name;
this.returnExpr = returnExpr; this.returnExpr = returnExpr;
} }
this(wstring name) this(wstring name, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.DefineFunction; this.type = NodeType.DefineFunction;
this.name = name; this.name = name;
this.returnExpr = false; this.returnExpr = false;
@@ -412,8 +444,9 @@ class CallFunctionStatement : Statement
wstring name; wstring name;
Expression[] args; Expression[] args;
wstring[] outVariable; wstring[] outVariable;
this(wstring n) this(wstring n, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.CallFunctionStatement; this.type = NodeType.CallFunctionStatement;
this.name = n; this.name = n;
args = new Expression[0]; args = new Expression[0];
@@ -431,8 +464,9 @@ class While : Statement
{ {
Expression condExpression; Expression condExpression;
Statements statements; Statements statements;
this(Expression condExpression, Statements statements) this(Expression condExpression, Statements statements, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.While; this.type = NodeType.While;
this.condExpression = condExpression; this.condExpression = condExpression;
this.statements = statements; this.statements = statements;
@@ -442,8 +476,9 @@ class Inc : Statement
{ {
wstring name; wstring name;
Expression expression; Expression expression;
this(wstring name, Expression expr) this(wstring name, Expression expr, SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Inc; this.type = NodeType.Inc;
this.name = name; this.name = name;
this.expression = expr; this.expression = expr;
@@ -452,8 +487,9 @@ class Inc : Statement
class Data : Statement class Data : Statement
{ {
Value[] data; Value[] data;
this() this(SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Data; this.type = NodeType.Data;
this.data = new Value[0]; this.data = new Value[0];
} }
@@ -465,8 +501,9 @@ class Data : Statement
class Read : Statement class Read : Statement
{ {
Expression[] variables; Expression[] variables;
this() this(SourceLocation loc)
{ {
super.location = loc;
this.type = NodeType.Read; this.type = NodeType.Read;
} }
void addVariable(Expression lvalue) void addVariable(Expression lvalue)
@@ -477,8 +514,9 @@ class Read : Statement
class Restore : Statement class Restore : Statement
{ {
Expression label; Expression label;
this(Expression label) this(Expression label, SourceLocation loc)
{ {
super.location = loc;
this.label = label; this.label = label;
this.type = NodeType.Restore; this.type = NodeType.Restore;
} }
@@ -488,8 +526,9 @@ class On : Statement
Expression condition; Expression condition;
bool isGosub; bool isGosub;
wstring[] labels; wstring[] labels;
this(Expression expr, bool isgosub) this(Expression expr, bool isgosub, SourceLocation loc)
{ {
super.location = loc;
this.condition = expr; this.condition = expr;
this.isGosub = isgosub; this.isGosub = isgosub;
this.labels = new wstring[0]; this.labels = new wstring[0];
@@ -505,8 +544,9 @@ class Input : Statement
Expression message; Expression message;
bool question; bool question;
Expression[] variables; Expression[] variables;
this(Expression message, bool question) this(Expression message, bool question, SourceLocation loc)
{ {
super.location = loc;
this.message = message; this.message = message;
this.question = question; this.question = question;
this.variables = new Expression[0]; this.variables = new Expression[0];

View File

@@ -85,7 +85,9 @@ class Lexical
{ {
return c == '$' || c == '%' || c == '#'; return c == '$' || c == '%' || c == '#';
} }
SourceLocation location;
Token token; Token token;
private int pos;
void popFront() void popFront()
{ {
if(empty()) if(empty())
@@ -316,9 +318,13 @@ class Lexical
i++; i++;
} }
} }
pos = i;
} }
break; break;
} }
this.location.pos = i - this.pos;
this.location.line = line;
this.location.pos2 = index - 1;
index = i; index = i;
} }
Token front() Token front()
@@ -367,6 +373,15 @@ unittest
} }
class Parser 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; wstring code;
Lexical lex; Lexical lex;
this(wstring input) this(wstring input)
@@ -488,7 +503,7 @@ class Parser
Statements parseProgram() Statements parseProgram()
{ {
lex.popFront(); lex.popFront();
auto statements = new Statements(); auto statements = new Statements(lex.location);
while(!lex.empty()) while(!lex.empty())
{ {
auto token = lex.front(); auto token = lex.front();
@@ -539,7 +554,7 @@ class Parser
syntaxError(); syntaxError();
return null; return null;
} }
DefineFunction node = new DefineFunction(token.value.stringValue); DefineFunction node = new DefineFunction(token.value.stringValue, lex.location);
lex.popFront(); lex.popFront();
token = lex.front(); token = lex.front();
if(token.type == TokenType.LParen) if(token.type == TokenType.LParen)
@@ -630,7 +645,7 @@ class Parser
} }
Statements functionStatements() Statements functionStatements()
{ {
auto statements = new Statements(); auto statements = new Statements(lex.location);
while(true) while(true)
{ {
auto type = lex.front().type; auto type = lex.front().type;
@@ -651,7 +666,7 @@ class Parser
} }
Statements ifStatements() Statements ifStatements()
{ {
auto statements = new Statements(); auto statements = new Statements(lex.location);
bool flag = true; bool flag = true;
while(!lex.empty()) while(!lex.empty())
{ {
@@ -662,7 +677,7 @@ class Parser
if(type == TokenType.Endif) break; if(type == TokenType.Endif) break;
if(type == TokenType.Label) if(type == TokenType.Label)
{ {
statements.addStatement(new Goto(lex.front.value.stringValue)); statements.addStatement(new Goto(lex.front.value.stringValue, lex.location));
lex.popFront; lex.popFront;
continue; continue;
} }
@@ -676,7 +691,7 @@ class Parser
} }
Statements multilineIfStatements() Statements multilineIfStatements()
{ {
auto statements = new Statements(); auto statements = new Statements(lex.location);
while(!lex.empty()) while(!lex.empty())
{ {
auto type = lex.front().type; auto type = lex.front().type;
@@ -692,7 +707,7 @@ class Parser
} }
Statements forStatements() Statements forStatements()
{ {
auto statements = new Statements(); auto statements = new Statements(lex.location);
while(!lex.empty()) while(!lex.empty())
{ {
auto type = lex.front().type; auto type = lex.front().type;
@@ -722,7 +737,7 @@ class Parser
} }
Statements whileStatements() Statements whileStatements()
{ {
auto statements = new Statements(); auto statements = new Statements(lex.location);
while(!lex.empty()) while(!lex.empty())
{ {
auto type = lex.front().type; auto type = lex.front().type;
@@ -774,7 +789,7 @@ class Parser
return node; return node;
} }
//命令呼び出し //命令呼び出し
auto func = new CallFunctionStatement(name); auto func = new CallFunctionStatement(name, lex.location);
node = func; node = func;
bool oldcomma; bool oldcomma;
while(true) while(true)
@@ -783,7 +798,7 @@ class Parser
if(token.type == TokenType.Comma) if(token.type == TokenType.Comma)
{ {
func.addArg(new VoidExpression()); func.addArg(new VoidExpression(lex.location));
lex.popFront(); lex.popFront();
token = lex.front(); token = lex.front();
} }
@@ -827,32 +842,32 @@ class Parser
case TokenType.NewLine: case TokenType.NewLine:
break; break;
case TokenType.Label: case TokenType.Label:
node = new Label(token.value.stringValue); node = new Label(token.value.stringValue, lex.location);
break; break;
case TokenType.Goto: case TokenType.Goto:
lex.popFront(); lex.popFront();
token = lex.front(); token = lex.front();
if(token.type == TokenType.Label) if(token.type == TokenType.Label)
node = new Goto(token.value.stringValue); node = new Goto(token.value.stringValue, lex.location);
else else
{ {
auto e = expression(); auto e = expression();
if(!e) if(!e)
syntaxError(); syntaxError();
node = new Goto(e); node = new Goto(e, lex.location);
} }
break; break;
case TokenType.Gosub: case TokenType.Gosub:
lex.popFront(); lex.popFront();
token = lex.front(); token = lex.front();
if(token.type == TokenType.Label) if(token.type == TokenType.Label)
node = new Gosub(token.value.stringValue); node = new Gosub(token.value.stringValue, lex.location);
else else
{ {
auto e = expression(); auto e = expression();
if(!e) if(!e)
syntaxError(); syntaxError();
node = new Gosub(e); node = new Gosub(e, lex.location);
} }
break; break;
case TokenType.If: case TokenType.If:
@@ -864,21 +879,21 @@ class Parser
lex.popFront(); lex.popFront();
if(isFuncReturnExpr) if(isFuncReturnExpr)
{ {
node = new Return(expression()); node = new Return(expression(), lex.location);
} }
else else
{ {
node = new Return(null); node = new Return(null, lex.location);
} }
return node; return node;
case TokenType.End: case TokenType.End:
node = new End(); node = new End(lex.location);
break; break;
case TokenType.Break: case TokenType.Break:
node = new Break(); node = new Break(lex.location);
break; break;
case TokenType.Continue: case TokenType.Continue:
node = new Continue(); node = new Continue(lex.location);
break; break;
case TokenType.Var: case TokenType.Var:
lex.popFront(); lex.popFront();
@@ -935,7 +950,7 @@ class Parser
auto token = lex.front(); auto token = lex.front();
if(token.type == TokenType.Semicolon || (token.type == TokenType.Comma && !isLValue(message))) 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 do
{ {
lex.popFront(); lex.popFront();
@@ -956,7 +971,7 @@ class Parser
syntaxError(); syntaxError();
return null; return null;
} }
Input input = new Input(null, true); Input input = new Input(null, true, lex.location);
input.addVariable(message); input.addVariable(message);
do do
{ {
@@ -982,11 +997,11 @@ class Parser
On on; On on;
if(token.type == TokenType.Gosub) 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) else if(token.type == TokenType.Goto)
{ {
on = new On(cond, false);//gosub on = new On(cond, false, lex.location);//gosub
} }
else else
{ {
@@ -1011,7 +1026,7 @@ class Parser
} }
Data dataStatement() Data dataStatement()
{ {
Data data = new Data(); Data data = new Data(lex.location);
lex.popFront(); lex.popFront();
auto token = lex.front(); auto token = lex.front();
while(true) while(true)
@@ -1051,7 +1066,7 @@ class Parser
} }
Read readStatement() Read readStatement()
{ {
Read read = new Read(); Read read = new Read(lex.location);
Token token; Token token;
do do
{ {
@@ -1075,7 +1090,7 @@ class Parser
syntaxError(); syntaxError();
return null; return null;
} }
return new Restore(label); return new Restore(label, lex.location);
} }
Inc incStatement() Inc incStatement()
{ {
@@ -1105,17 +1120,17 @@ class Parser
} }
else else
{ {
expr = new Constant(Value(1)); expr = new Constant(Value(1), lex.location);
} }
if(dec) 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 indexExpressions()
{ {
IndexExpressions ie = new IndexExpressions(); IndexExpressions ie = new IndexExpressions(lex.location);
int count = 0; int count = 0;
while(true) while(true)
{ {
@@ -1160,12 +1175,12 @@ class Parser
lex.popFront(); lex.popFront();
auto expr = expression(); auto expr = expression();
token = lex.front(); token = lex.front();
auto node = new ArrayAssign(name, ie, expr); auto node = new ArrayAssign(name, ie, expr, lex.location);
return node; return node;
} }
Statement var() Statement var()
{ {
Var var = new Var(); Var var = new Var(lex.location);
Token token; Token token;
while(true) while(true)
{ {
@@ -1215,7 +1230,7 @@ class Parser
if(token.type != TokenType.RBracket) if(token.type != TokenType.RBracket)
return null; return null;
lex.popFront(); lex.popFront();
DefineArray ary = new DefineArray(name, dim); DefineArray ary = new DefineArray(name, dim, lex.location);
return ary; return ary;
} }
else else
@@ -1228,7 +1243,7 @@ class Parser
token = lex.front(); token = lex.front();
} }
} }
DefineVariable node = new DefineVariable(name, expr); DefineVariable node = new DefineVariable(name, expr, lex.location);
return node; return node;
} }
For forStatement() For forStatement()
@@ -1263,11 +1278,11 @@ class Parser
else else
{ {
//とりあえず //とりあえず
step = new Constant(Value(1)); step = new Constant(Value(1), lex.location);
} }
token = lex.front(); token = lex.front();
Statements statements = forStatements(); Statements statements = forStatements();
node = new For(init, to, step, statements); node = new For(init, to, step, statements, lex.location);
return node; return node;
} }
While whileStatement() While whileStatement()
@@ -1280,7 +1295,7 @@ class Parser
return null; return null;
} }
Statements statements = whileStatements(); Statements statements = whileStatements();
auto node = new While(expr, statements); auto node = new While(expr, statements, lex.location);
return node; return node;
} }
If if_() If if_()
@@ -1340,7 +1355,7 @@ class Parser
else_ = ifStatements(); else_ = ifStatements();
} }
} }
auto if_ = new If(expr, then, else_); auto if_ = new If(expr, then, else_, lex.location);
return if_; return if_;
} }
Assign assign(wstring name) Assign assign(wstring name)
@@ -1349,12 +1364,12 @@ class Parser
auto token = lex.front();//=の次 auto token = lex.front();//=の次
Expression expr = expression(); Expression expr = expression();
if(expr is null) return null; if(expr is null) return null;
auto a = new Assign(name, expr); auto a = new Assign(name, expr, lex.location);
return a; return a;
} }
Print print() Print print()
{ {
auto print = new Print(); auto print = new Print(lex.location);
bool addline = true; bool addline = true;
lex.popFront(); lex.popFront();
auto token = lex.front(); auto token = lex.front();
@@ -1429,7 +1444,7 @@ class Parser
auto token = lex.front(); auto token = lex.front();
if(order == getOPRank(token.type)) if(order == getOPRank(token.type))
{ {
BinaryOperator op = new BinaryOperator(exp); BinaryOperator op = new BinaryOperator(exp, lex.location);
while(order == getOPRank(token.type)) while(order == getOPRank(token.type))
{ {
auto tt = token.type; auto tt = token.type;
@@ -1451,7 +1466,7 @@ class Parser
write(tt, " "); write(tt, " ");
if(order == getOPRank(token.type)) if(order == getOPRank(token.type))
{ {
BinaryOperator op2 = new BinaryOperator(op); BinaryOperator op2 = new BinaryOperator(op, lex.location);
op.item1 = op2; op.item1 = op2;
} }
version(none)stdout.flush(); version(none)stdout.flush();
@@ -1470,14 +1485,14 @@ class Parser
case TokenType.Integer: case TokenType.Integer:
version(none)write(token.value.integerValue, ' '); version(none)write(token.value.integerValue, ' ');
version(none)stdout.flush(); version(none)stdout.flush();
node = new Constant(token.value); node = new Constant(token.value, lex.location);
break; break;
case TokenType.Iden: case TokenType.Iden:
if(!lex.empty()) if(!lex.empty())
lex.popFront(); lex.popFront();
if(lex.front().type == TokenType.LParen) if(lex.front().type == TokenType.LParen)
{ {
auto func = new CallFunction(token.value.stringValue); auto func = new CallFunction(token.value.stringValue, lex.location);
node = func; node = func;
//関数呼び出しだった //関数呼び出しだった
while(true) while(true)
@@ -1488,7 +1503,7 @@ class Parser
if(token.type == TokenType.RParen) break; if(token.type == TokenType.RParen) break;
if(token.type == TokenType.Comma) if(token.type == TokenType.Comma)
{ {
func.addArg(new VoidExpression()); func.addArg(new VoidExpression(lex.location));
lex.popFront(); lex.popFront();
token = lex.front(); token = lex.front();
} }
@@ -1499,7 +1514,7 @@ class Parser
} }
else else
{ {
return new Variable(token.value.stringValue); return new Variable(token.value.stringValue, lex.location);
} }
break; break;
case TokenType.LParen: case TokenType.LParen:
@@ -1512,18 +1527,18 @@ class Parser
break; break;
case TokenType.Label://3.1 case TokenType.Label://3.1
//文字列リテラル //文字列リテラル
node = new Constant(token.value); node = new Constant(token.value, lex.location);
break; break;
case TokenType.Minus: case TokenType.Minus:
//TODO:UnaryOperatorの実装 //TODO:UnaryOperatorの実装
//とりあえず0-exprを作成 //とりあえず0-exprを作成
lex.popFront(); 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; return node;
case TokenType.LogicalNot: case TokenType.LogicalNot:
case TokenType.Not: case TokenType.Not:
lex.popFront(); lex.popFront();
node = new UnaryOperator(token.type, factor()); node = new UnaryOperator(token.type, factor(), lex.location);
return node; return node;
default: default:
return node; return node;

View File

@@ -1052,11 +1052,11 @@ class PetitComputer
parser = new Parser( parser = new Parser(
//readText("./SYS/GAME6TALK.TXT").to!wstring //readText("./SYS/GAME6TALK.TXT").to!wstring
//readText("./SYS/GAME7EXPAD.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/GAME2RPG.TXT").to!wstring
//readText("./SYS/GAME1DOTRC.TXT").to!wstring //readText("./SYS/GAME1DOTRC.TXT").to!wstring
//readText(input("LOAD PROGRAM:", true).to!string).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("./SYS/EX1TEXT.TXT").to!wstring
//readText("FIZZBUZZ.TXT").to!wstring //readText("FIZZBUZZ.TXT").to!wstring
//readText("TEST.TXT").to!wstring //readText("TEST.TXT").to!wstring
@@ -1166,6 +1166,8 @@ class PetitComputer
//gbox(0, 78, 78, 40, 40, RGB(255, 255, 0)); //gbox(0, 78, 78, 40, 40, RGB(255, 255, 0));
int startcnt = SDL_GetTicks(); int startcnt = SDL_GetTicks();
float frame = 1000f / 60f; float frame = 1000f / 60f;
typeof(vm.currentLocation()) loc;
debug bool trace = false;
while (true) while (true)
{ {
uint elapse; uint elapse;
@@ -1178,6 +1180,11 @@ class PetitComputer
{ {
//writefln("%04X:%s", vm.pc, vm.getCurrent); //writefln("%04X:%s", vm.pc, vm.getCurrent);
running = vm.runStep(); 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) catch(SmileBasicError sbe)
@@ -1190,9 +1197,12 @@ class PetitComputer
//printConsole(sbe.to!string); //printConsole(sbe.to!string);
writeln(sbe.to!string); writeln(sbe.to!string);
writeln(sbe.getErrorMessage2); writeln(sbe.getErrorMessage2);
loc = vm.currentLocation;
printConsole(loc.line, ":", loc.pos, ":", parser.getLine(loc));
} }
catch catch(Throwable t)
{ {
writeln(t);
} }
} }
catch(Throwable t) catch(Throwable t)
@@ -1202,9 +1212,11 @@ class PetitComputer
{ {
printConsole(t.to!string); printConsole(t.to!string);
writeln(t); writeln(t);
printConsole(parser.getLine(vm.currentLocation));
} }
catch catch(Throwable t)
{ {
writeln(t);
} }
} }
//elapse = SDL_GetTicks() - startTicks; //elapse = SDL_GetTicks() - startTicks;

View File

@@ -81,3 +81,9 @@ struct Token
type = t; type = t;
} }
} }
struct SourceLocation
{
int line;//何行目
int pos;//何文字目
int pos2;//全体から何文字目
}