1
0
Files
otyaSMILEBASIC/SMILEBASIC/type.d
2015-08-22 22:16:13 +09:00

240 lines
6.4 KiB
D

module otya.smilebasic.type;
import otya.smilebasic.error;
enum ValueType : byte
{
Void,//DEF A()ENDの返り値とか未初期化の変数とか
Integer,
Double,
String,
Array,
IntegerArray,
DoubleArray,
StringArray,
}
struct Value
{
ValueType type;
union
{
int integerValue;
double doubleValue;
//TODO:Array!wchar stringValue;にしたい
wstring stringValue;
Array!int integerArray;
Array!double doubleArray;
Array!wstring stringArray;
}
this(int value)
{
this.type = ValueType.Integer;
integerValue = value;
}
this(double value)
{
this.type = ValueType.Double;
doubleValue = value;
}
this(wstring value)
{
this.type = ValueType.String;
stringValue = value;
}
this(ValueType type)
{
this.type = type;
if(type == ValueType.String)
{
stringValue = "";
}
}
void castOp(ValueType type)
{
switch(type)
{
case ValueType.Double:
break;
default:
break;
}
}
bool boolValue()
{
switch(type)
{
case ValueType.Double:
return this.doubleValue != 0;
case ValueType.Integer:
return this.integerValue != 0;
case ValueType.String:
return true;//3.1現在では文字列はtrue(ただし!"A"などは動かない)
default:
//配列はtype mismatch
return false;
}
}
bool isArray()
{
return this.type == ValueType.IntegerArray || this.type == ValueType.DoubleArray ||
this.type == ValueType.StringArray || this.type == ValueType.String;
}
bool isNumberArray()
{
return this.type == ValueType.IntegerArray || this.type == ValueType.DoubleArray;
}
bool isNumber()
{
return this.type == ValueType.Integer || this.type == ValueType.Double;
}
bool isString()
{
return this.type == ValueType.String;
}
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);
}
wstring castString()
{
return this.type == ValueType.String ? this.stringValue : "";
}
string toString()
{
import std.conv;
switch(this.type)
{
case ValueType.Void:
return "void";
case ValueType.Integer:
return this.integerValue.to!string;
case ValueType.String:
return this.stringValue.to!string;
default:
return "default";
}
}
}
class Array(T)
{
T[] array;
//最大要素数2^^31
//4次元配列
int[4] dim;
int dimCount;
this(int len)
{
dim[0] = len;
dim[1] = 0;
dim[2] = 0;
dim[3] = 0;
array = new T[len];
static if(is(T == double))
{
array[] = 0;
}
dimCount = 1;
}
this(int[] dim)
{
int len = 1;
foreach(int i, j; dim)
{
len *= j;
this.dim[i] = dim[i];
}
array = new T[len];
static if(is(T == double))
{
array[] = 0;
}
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)
{
if(dimCount != 1) throw new SyntaxError();
if(i1 >= dim[0]) throw new SubscriptOutOfRange();
return array[i1];
}
T opIndex(int i1, int i2)
{
if(dimCount != 2) throw new SyntaxError();
if(i1 >= dim[0] && i2 >= dim[1]) throw new SubscriptOutOfRange();
return array[i1 * dim[0] + i2];
}
T opIndex(int i1, int i2, int i3)
{
if(dimCount != 3) throw new SyntaxError();
if(i1 >= dim[0] && i2 >= dim[1] && i3 >= dim[2]) throw new SubscriptOutOfRange();
return array[i1 * dim[0] * dim[1] + i2 * dim[1] + i3];
}
T opIndex(int i1, int i2, int i3, int i4)
{
if(dimCount != 4) throw new SyntaxError();
if(i1 >= dim[0] && i2 >= dim[1] && i3 >= dim[2] && i4 >= dim[3]) throw new SubscriptOutOfRange();
return array[i1];//array[i1 * dim[0] * dim[1] * dim[2] + i2 * dim[1] + i3];
}
T opIndexAssign(T v, int i1)
{
if(dimCount != 1) throw new SyntaxError();
if(i1 >= dim[0]) throw new SubscriptOutOfRange();
return array[i1] = v;
}
T opIndexAssign(T v, int i1, int i2)
{
if(dimCount != 2) throw new SyntaxError();
if(i1 >= dim[0] && i2 >= dim[1]) throw new SubscriptOutOfRange();
return array[i1 * dim[0] + i2] = v;
}
T opIndexAssign(T v, int i1, int i2, int i3)
{
if(dimCount != 3) throw new SyntaxError();
if(i1 >= dim[0] && i2 >= dim[1] && i3 >= dim[2]) throw new SubscriptOutOfRange();
return array[i1 * dim[0] * dim[1] + i2 * dim[1] + i3] = v;
}
T opIndexAssign(T v, int i1, int i2, int i3, int i4)
{
if(dimCount != 4) throw new SyntaxError();
if(i1 >= dim[0] && i2 >= dim[1] && i3 >= dim[2] && i4 >= dim[3]) throw new SubscriptOutOfRange();
return array[i1] = v;//array[i1 * dim[0] * dim[1] * dim[2] + i2 * dim[1] + i3] = v;
}
}