diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index b07b355..537a9df 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -545,12 +545,80 @@ class NewArray : Code vm.global[index].type = ValueType.IntegerArray; vm.global[index].integerArray = new Array!int(dim); break; + case ValueType.Double: + vm.global[index].type = ValueType.DoubleArray; + vm.global[index].doubleArray = new Array!double(dim); + break; + case ValueType.String: + vm.global[index].type = ValueType.StringArray; + vm.global[index].stringArray = new Array!wstring(dim); + break; default: throw new TypeMismatch(); break; } } } +class PushArray : Code +{ + int dim; + this(int dim) + { + this.dim = dim; + } + override void execute(VM vm) + { + 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 array; + vm.pop(array); + if(!array.isArray) + { + throw new TypeMismatch(); + } + if(array.type == ValueType.IntegerArray) + { + vm.push(Value(array.integerArray[index[0..dim]])); + return; + } + if(array.type == ValueType.DoubleArray) + { + vm.push(Value(array.doubleArray[index[0..dim]])); + return; + } + if(array.type == ValueType.StringArray) + { + vm.push(Value(array.stringArray[index[0..dim]])); + return; + } + if(array.type == ValueType.String) + { + if(dim != 1) + { + //TODO:syntaxError + throw new TypeMismatch(); + } + vm.push(Value(array.stringValue[index[0]].to!wstring)); + return; + } + throw new TypeMismatch(); + } +} class PopGArray : Code { int var; @@ -568,7 +636,7 @@ class PopGArray : Code throw new TypeMismatch(); } int[4] index; - for(int i = dim - 1; i >= 0; i--) + for(int i = 0; i < dim; i++)//for(int i = dim - 1; i >= 0; i--) { Value v; vm.pop(v); diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index 74d3677..1af0360 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -136,6 +136,19 @@ class Compiler auto binop = cast(BinaryOperator)exp; compileExpression(binop.item1); compileExpression(binop.item2); + if(binop.operator == TokenType.LBracket) + { + IndexExpressions ie = cast(IndexExpressions)binop.item2; + if(ie) + { + genCode(new PushArray(ie.expressions.length)); + } + else + { + genCode(new PushArray(1)); + } + break; + } genCodeOP(binop.operator); } break; diff --git a/SMILEBASIC/main.d b/SMILEBASIC/main.d index 01066e1..63577ba 100644 --- a/SMILEBASIC/main.d +++ b/SMILEBASIC/main.d @@ -54,8 +54,8 @@ FOR I=0 TO 10 ?I NEXT VAR V[10] -V[0]=12 -?V[0] +V[0,1]=12 +?V[1] ?\"ABC\"[1][0] GOSUB @A END diff --git a/SMILEBASIC/parser.d b/SMILEBASIC/parser.d index 6a8d7d9..0a20bca 100644 --- a/SMILEBASIC/parser.d +++ b/SMILEBASIC/parser.d @@ -868,13 +868,17 @@ class Parser auto tt = token.type; op.operator = token.type; lex.popFront(); - op.item2 = term(order - 1, node); if(tt == TokenType.LBracket) { + op.item2 = indexExpressions(); //[演算子 if(lex.front().type != TokenType.RBracket) syntaxError(); lex.popFront(); } + else + { + op.item2 = term(order - 1, node); + } token = lex.front(); version(none) write(tt, " "); diff --git a/SMILEBASIC/type.d b/SMILEBASIC/type.d index 491552d..ad22132 100644 --- a/SMILEBASIC/type.d +++ b/SMILEBASIC/type.d @@ -109,9 +109,10 @@ class Array(T) this(int[] dim) { int len = 1; - foreach(int i; dim) + foreach(int i, j; dim) { - len *= i; + len *= j; + this.dim[i] = dim[i]; } array = new T[len]; dimCount = dim.length;