位置情報を記録するようにした
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -81,3 +81,9 @@ struct Token
|
|||||||
type = t;
|
type = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
struct SourceLocation
|
||||||
|
{
|
||||||
|
int line;//何行目
|
||||||
|
int pos;//何文字目
|
||||||
|
int pos2;//全体から何文字目
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user