DATA,READを実装.
This commit is contained in:
@@ -79,11 +79,18 @@ DEF ONGOSUBTEST
|
|||||||
RETURN
|
RETURN
|
||||||
@4
|
@4
|
||||||
END
|
END
|
||||||
|
@DATA_1
|
||||||
|
DATA "A",1,2,3,4
|
||||||
|
READ DATA$,_1,_2
|
||||||
|
READ _3,_4
|
||||||
|
ASSERT__ DATA$=="A", "DATA"
|
||||||
|
ASSERT__ _1==1, "DATA"
|
||||||
|
ASSERT__ _2==2, "DATA"
|
||||||
|
ASSERT__ _3==3, "DATA"
|
||||||
|
ASSERT__ _4==4, "DATA"
|
||||||
INPUT$="HELLO"
|
INPUT$="HELLO"
|
||||||
INPUT INPUT$,IN
|
INPUT INPUT$,IN
|
||||||
?INPUT$,IN
|
?INPUT$,IN
|
||||||
@DATA_1
|
|
||||||
DATA "A",1,2,3,4
|
|
||||||
LOCATE 10,
|
LOCATE 10,
|
||||||
COLOR 1,15
|
COLOR 1,15
|
||||||
PRINT "テスト正常終了"
|
PRINT "テスト正常終了"
|
||||||
@@ -20,6 +20,7 @@ struct VMVariable
|
|||||||
}
|
}
|
||||||
class VM
|
class VM
|
||||||
{
|
{
|
||||||
|
DataTable globalDataTable;
|
||||||
Code[] code;
|
Code[] code;
|
||||||
int stacki;
|
int stacki;
|
||||||
int pc;
|
int pc;
|
||||||
@@ -29,7 +30,7 @@ class VM
|
|||||||
Function[wstring] functions;
|
Function[wstring] functions;
|
||||||
int bp;
|
int bp;
|
||||||
PetitComputer petitcomputer;
|
PetitComputer petitcomputer;
|
||||||
this(Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions)
|
this(Code[] code, int len, VMVariable[wstring] globalTable, Function[wstring] functions, DataTable gdt/*GNU Debugging Tools*/)
|
||||||
{
|
{
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.stack = new Value[16384];
|
this.stack = new Value[16384];
|
||||||
@@ -40,6 +41,7 @@ class VM
|
|||||||
this.global[v.index] = Value(v.type);
|
this.global[v.index] = Value(v.type);
|
||||||
}
|
}
|
||||||
this.functions = functions;
|
this.functions = functions;
|
||||||
|
this.globalDataTable = gdt;
|
||||||
}
|
}
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
@@ -1120,3 +1122,20 @@ class InputCode : Code
|
|||||||
} while(error);
|
} while(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class ReadCode : Code
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
this(int count)
|
||||||
|
{
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
override void execute(VM vm)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
Value data;
|
||||||
|
vm.globalDataTable.read(data, vm);
|
||||||
|
vm.push(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ class DataTable
|
|||||||
{
|
{
|
||||||
Value[] data;
|
Value[] data;
|
||||||
int[wstring] label;
|
int[wstring] label;
|
||||||
|
int dataIndex;
|
||||||
void addData(Value data)
|
void addData(Value data)
|
||||||
{
|
{
|
||||||
this.data ~= data;
|
this.data ~= data;
|
||||||
@@ -40,6 +41,13 @@ class DataTable
|
|||||||
{
|
{
|
||||||
this.label[label] = data.length;
|
this.label[label] = data.length;
|
||||||
}
|
}
|
||||||
|
void read(out Value value, VM vm)
|
||||||
|
{
|
||||||
|
if(dataIndex >= data.length)
|
||||||
|
throw new OutOfDATA();
|
||||||
|
value = data[dataIndex];
|
||||||
|
dataIndex++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
class Function
|
class Function
|
||||||
{
|
{
|
||||||
@@ -618,6 +626,14 @@ class Compiler
|
|||||||
compilePopVar(i, sc);
|
compilePopVar(i, sc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void compileRead(Read read, Scope sc)
|
||||||
|
{
|
||||||
|
genCode(new ReadCode(read.variables.length));
|
||||||
|
foreach_reverse(i; read.variables)
|
||||||
|
{
|
||||||
|
compilePopVar(i, sc);
|
||||||
|
}
|
||||||
|
}
|
||||||
void compileStatement(Statement i, Scope s)
|
void compileStatement(Statement i, Scope s)
|
||||||
{
|
{
|
||||||
switch(i.type)
|
switch(i.type)
|
||||||
@@ -781,6 +797,9 @@ class Compiler
|
|||||||
s.data.addData(j);
|
s.data.addData(j);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case NodeType.Read:
|
||||||
|
compileRead(cast(Read)i, s);
|
||||||
|
break;
|
||||||
case NodeType.On:
|
case NodeType.On:
|
||||||
compileOn(cast(On)i, s);
|
compileOn(cast(On)i, s);
|
||||||
break;
|
break;
|
||||||
@@ -854,7 +873,7 @@ class Compiler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new VM(code, globalIndex + 1, global, functions);
|
return new VM(code, globalIndex + 1, global, functions, s.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,14 @@ class TypeMismatch : SmileBasicError
|
|||||||
super("Type mismatch");
|
super("Type mismatch");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class OutOfDATA : SmileBasicError
|
||||||
|
{
|
||||||
|
this()
|
||||||
|
{
|
||||||
|
this.errnum = 13;
|
||||||
|
super("Out of DATA");
|
||||||
|
}
|
||||||
|
}
|
||||||
class DuplicateVariable : SmileBasicError
|
class DuplicateVariable : SmileBasicError
|
||||||
{
|
{
|
||||||
this()
|
this()
|
||||||
|
|||||||
@@ -450,6 +450,27 @@ class Data : Statement
|
|||||||
data ~= v;
|
data ~= v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class Read : Statement
|
||||||
|
{
|
||||||
|
Expression[] variables;
|
||||||
|
this()
|
||||||
|
{
|
||||||
|
this.type = NodeType.Read;
|
||||||
|
}
|
||||||
|
void addVariable(Expression lvalue)
|
||||||
|
{
|
||||||
|
variables ~= lvalue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Restore : Statement
|
||||||
|
{
|
||||||
|
Expression label;
|
||||||
|
this(Expression label)
|
||||||
|
{
|
||||||
|
this.label = label;
|
||||||
|
this.type = NodeType.Restore;
|
||||||
|
}
|
||||||
|
}
|
||||||
class On : Statement
|
class On : Statement
|
||||||
{
|
{
|
||||||
Expression condition;
|
Expression condition;
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ class Lexical
|
|||||||
token = Token(TokenType.Integer, Value(num));
|
token = Token(TokenType.Integer, Value(num));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(c.isAlpha())
|
if(c.isAlpha() || c == '_')
|
||||||
{
|
{
|
||||||
wstring iden;
|
wstring iden;
|
||||||
for(;i < code.length;i++)
|
for(;i < code.length;i++)
|
||||||
@@ -787,6 +787,10 @@ class Parser
|
|||||||
return incStatement();
|
return incStatement();
|
||||||
case TokenType.Data:
|
case TokenType.Data:
|
||||||
return dataStatement();
|
return dataStatement();
|
||||||
|
case TokenType.Read:
|
||||||
|
return readStatement();
|
||||||
|
case TokenType.Restore:
|
||||||
|
return restoreStatement();
|
||||||
case TokenType.On:
|
case TokenType.On:
|
||||||
node = onStatement();
|
node = onStatement();
|
||||||
break;
|
break;
|
||||||
@@ -925,6 +929,34 @@ class Parser
|
|||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
Read readStatement()
|
||||||
|
{
|
||||||
|
Read read = new Read();
|
||||||
|
Token token;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
lex.popFront();
|
||||||
|
auto expr = expression();
|
||||||
|
if(!expr || !isLValue(expr))
|
||||||
|
{
|
||||||
|
syntaxError();
|
||||||
|
}
|
||||||
|
read.addVariable(expr);
|
||||||
|
token = lex.front();
|
||||||
|
} while(token.type == TokenType.Comma);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
Restore restoreStatement()
|
||||||
|
{
|
||||||
|
lex.popFront();
|
||||||
|
auto label = expression();
|
||||||
|
if(!label)
|
||||||
|
{
|
||||||
|
syntaxError();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new Restore(label);
|
||||||
|
}
|
||||||
Inc incStatement()
|
Inc incStatement()
|
||||||
{
|
{
|
||||||
auto token = lex.front();
|
auto token = lex.front();
|
||||||
|
|||||||
Reference in New Issue
Block a user