配列への代入を実装
This commit is contained in:
@@ -551,3 +551,68 @@ class NewArray : Code
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class PopGArray : Code
|
||||||
|
{
|
||||||
|
int var;
|
||||||
|
int dim;
|
||||||
|
this(int var, int dim)
|
||||||
|
{
|
||||||
|
this.var = var;
|
||||||
|
this.dim = dim;
|
||||||
|
}
|
||||||
|
override void execute(VM vm)
|
||||||
|
{
|
||||||
|
Value array = vm.global[var];
|
||||||
|
if(!array.isArray)
|
||||||
|
{
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
int[4] index;
|
||||||
|
for(int i = dim - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
Value v;
|
||||||
|
vm.pop(v);
|
||||||
|
if(v.type == ValueType.Integer)
|
||||||
|
{
|
||||||
|
index[i] = v.integerValue;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(v.type == ValueType.Double)
|
||||||
|
{
|
||||||
|
index[i] = cast(int)v.doubleValue;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
Value assign;
|
||||||
|
vm.pop(assign);
|
||||||
|
if(array.type == ValueType.IntegerArray && assign.isNumber)
|
||||||
|
{
|
||||||
|
array.integerArray[index[0..dim]] = assign.castInteger();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(array.type == ValueType.DoubleArray && assign.isNumber)
|
||||||
|
{
|
||||||
|
array.doubleArray[index[0..dim]] = assign.castDouble();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(array.type == ValueType.StringArray && assign.type == ValueType.String)
|
||||||
|
{
|
||||||
|
array.stringArray[index[0..dim]] = assign.stringValue;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(array.type == ValueType.String && assign.type == ValueType.String)
|
||||||
|
{
|
||||||
|
if(dim != 1)
|
||||||
|
{
|
||||||
|
//TODO:syntaxError
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
//TODO:文字列の挙動
|
||||||
|
throw new TypeMismatch();
|
||||||
|
//array.stringValue[index[0]] = assign.stringValue[0];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -162,6 +162,18 @@ class Compiler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case NodeType.IndexExpressions://[expr,expr,expr,expr]用
|
||||||
|
{
|
||||||
|
auto index = cast(IndexExpressions)exp;
|
||||||
|
int count = 0;
|
||||||
|
foreach_reverse(Expression i; index.expressions)
|
||||||
|
{
|
||||||
|
compileExpression(i);
|
||||||
|
count++;
|
||||||
|
if(count >= 4) break;//念のため
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
stderr.writeln("Compile:NotImpl ", exp.type);
|
stderr.writeln("Compile:NotImpl ", exp.type);
|
||||||
break;
|
break;
|
||||||
@@ -358,6 +370,13 @@ class Compiler
|
|||||||
case NodeType.Var:
|
case NodeType.Var:
|
||||||
compileVar(cast(Var)i, s);
|
compileVar(cast(Var)i, s);
|
||||||
break;
|
break;
|
||||||
|
case NodeType.ArrayAssign:
|
||||||
|
{
|
||||||
|
auto assign = cast(ArrayAssign)i;
|
||||||
|
compileExpression(assign.assignExpression);
|
||||||
|
compileExpression(assign.indexExpression);
|
||||||
|
genCode(new PopGArray(getGlobalVarIndex(assign.name), assign.indexExpression.expressions.length));
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
stderr.writeln("Compile:NotImpl ", i.type);
|
stderr.writeln("Compile:NotImpl ", i.type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ FOR I=0 TO 10
|
|||||||
?I
|
?I
|
||||||
NEXT
|
NEXT
|
||||||
VAR V[10]
|
VAR V[10]
|
||||||
|
V[0]=12
|
||||||
?V[0]
|
?V[0]
|
||||||
?\"ABC\"[1][0]
|
?\"ABC\"[1][0]
|
||||||
GOSUB @A
|
GOSUB @A
|
||||||
|
|||||||
@@ -554,13 +554,19 @@ class Parser
|
|||||||
IndexExpressions indexExpressions()
|
IndexExpressions indexExpressions()
|
||||||
{
|
{
|
||||||
IndexExpressions ie = new IndexExpressions();
|
IndexExpressions ie = new IndexExpressions();
|
||||||
|
int count = 0;
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
ie.addExpression(expression());
|
ie.addExpression(expression());
|
||||||
|
count++;
|
||||||
auto token = lex.front();
|
auto token = lex.front();
|
||||||
if(token.type == TokenType.Comma)
|
if(token.type == TokenType.Comma)
|
||||||
{
|
{
|
||||||
lex.popFront();
|
lex.popFront();
|
||||||
|
if(count >= 4)
|
||||||
|
{
|
||||||
|
syntaxError();
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(token.type == TokenType.RBracket)
|
if(token.type == TokenType.RBracket)
|
||||||
@@ -589,7 +595,9 @@ class Parser
|
|||||||
syntaxError();
|
syntaxError();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
lex.popFront();
|
||||||
auto expr = expression();
|
auto expr = expression();
|
||||||
|
token = lex.front();
|
||||||
auto node = new ArrayAssign(name, ie, expr);
|
auto node = new ArrayAssign(name, ie, expr);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ struct Value
|
|||||||
{
|
{
|
||||||
int integerValue;
|
int integerValue;
|
||||||
double doubleValue;
|
double doubleValue;
|
||||||
|
//TODO:Array!wchar stringValue;にしたい
|
||||||
wstring stringValue;
|
wstring stringValue;
|
||||||
Array!int integerArray;
|
Array!int integerArray;
|
||||||
Array!double doubleArray;
|
Array!double doubleArray;
|
||||||
@@ -71,6 +72,23 @@ struct Value
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool isArray()
|
||||||
|
{
|
||||||
|
return this.type == ValueType.IntegerArray || this.type == ValueType.DoubleArray ||
|
||||||
|
this.type == ValueType.StringArray || this.type == ValueType.String;
|
||||||
|
}
|
||||||
|
bool isNumber()
|
||||||
|
{
|
||||||
|
return this.type == ValueType.Integer || this.type == ValueType.Double;
|
||||||
|
}
|
||||||
|
int castInteger()
|
||||||
|
{
|
||||||
|
return this.type == ValueType.Integer ? this.integerValue : (this.type == ValueType.Double ? cast(int)this.doubleValue : 0);
|
||||||
|
}
|
||||||
|
double castDouble()
|
||||||
|
{
|
||||||
|
return this.type == ValueType.Integer ? this.integerValue : (this.type == ValueType.Double ? this.doubleValue : 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
class Array(T)
|
class Array(T)
|
||||||
{
|
{
|
||||||
@@ -98,6 +116,40 @@ class Array(T)
|
|||||||
array = new T[len];
|
array = new T[len];
|
||||||
dimCount = dim.length;
|
dimCount = dim.length;
|
||||||
}
|
}
|
||||||
|
T opIndexAssign(T v, int[] dim)
|
||||||
|
{
|
||||||
|
import core.exception;
|
||||||
|
switch(dim.length)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
return this[dim[0]] = v;
|
||||||
|
case 2:
|
||||||
|
return this[dim[0], dim[1]] = v;
|
||||||
|
case 3:
|
||||||
|
return this[dim[0], dim[1], dim[2]] = v;
|
||||||
|
case 4:
|
||||||
|
return this[dim[0], dim[1], dim[2], dim[3]] = v;
|
||||||
|
default:
|
||||||
|
throw new RangeError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
T opIndex(int[] dim)
|
||||||
|
{
|
||||||
|
import core.exception;
|
||||||
|
switch(dim.length)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
return this[dim[0]];
|
||||||
|
case 2:
|
||||||
|
return this[dim[0], dim[1]];
|
||||||
|
case 3:
|
||||||
|
return this[dim[0], dim[1], dim[2]];
|
||||||
|
case 4:
|
||||||
|
return this[dim[0], dim[1], dim[2], dim[3]];
|
||||||
|
default:
|
||||||
|
throw new RangeError();
|
||||||
|
}
|
||||||
|
}
|
||||||
T opIndex(int i1)
|
T opIndex(int i1)
|
||||||
{
|
{
|
||||||
return array[i1];
|
return array[i1];
|
||||||
@@ -114,5 +166,21 @@ class Array(T)
|
|||||||
{
|
{
|
||||||
return array[i1];//array[i1 * dim[0] * dim[1] * dim[2] + i2 * dim[1] + i3];
|
return array[i1];//array[i1 * dim[0] * dim[1] * dim[2] + i2 * dim[1] + i3];
|
||||||
}
|
}
|
||||||
|
T opIndexAssign(T v, int i1)
|
||||||
|
{
|
||||||
|
return array[i1] = v;
|
||||||
|
}
|
||||||
|
T opIndexAssign(T v, int i1, int i2)
|
||||||
|
{
|
||||||
|
return array[i1 * dim[0] + i2] = v;
|
||||||
|
}
|
||||||
|
T opIndexAssign(T v, int i1, int i2, int i3)
|
||||||
|
{
|
||||||
|
return array[i1 * dim[0] * dim[1] + i2 * dim[1] + i3] = v;
|
||||||
|
}
|
||||||
|
T opIndexAssign(T v, int i1, int i2, int i3, int i4)
|
||||||
|
{
|
||||||
|
return array[i1] = v;//array[i1 * dim[0] * dim[1] * dim[2] + i2 * dim[1] + i3] = v;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user