1
0

配列への代入を実装

This commit is contained in:
otya128
2015-06-12 21:19:21 +09:00
parent 61020e9941
commit 9b9951e07e
5 changed files with 161 additions and 0 deletions

View File

@@ -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();
}
}

View File

@@ -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);
} }

View File

@@ -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

View File

@@ -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;
} }

View File

@@ -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;
}
} }