SORTを実装
This commit is contained in:
@@ -1,3 +1,43 @@
|
|||||||
|
'--no-direct-mode --file TEST.TXT
|
||||||
|
DEF SORTTEST
|
||||||
|
DIM A[4]
|
||||||
|
DIM B$[4]
|
||||||
|
DIM C$[4]
|
||||||
|
A[0]=3
|
||||||
|
A[1]=2
|
||||||
|
A[2]=1
|
||||||
|
A[3]=0
|
||||||
|
B$[0]="0"
|
||||||
|
B$[1]="1"
|
||||||
|
B$[2]="2"
|
||||||
|
B$[3]="3"
|
||||||
|
C$[0]="A"
|
||||||
|
C$[1]="B"
|
||||||
|
C$[2]="C"
|
||||||
|
C$[3]="D"
|
||||||
|
SORT A,B$,C$
|
||||||
|
ASSERT__ A[0]==0,"SORT"
|
||||||
|
ASSERT__ B$[0]=="3","SORT"
|
||||||
|
ASSERT__ C$[0]=="D","SORT"
|
||||||
|
RSORT A,B$,C$
|
||||||
|
ASSERT__ A[3]==0,"RSORT"
|
||||||
|
ASSERT__ B$[3]=="3","RSORT"
|
||||||
|
ASSERT__ C$[3]=="D","RSORT"
|
||||||
|
SORTTEST2
|
||||||
|
END
|
||||||
|
DEF SORTTEST2
|
||||||
|
DIM A[10]
|
||||||
|
DIM B[10]
|
||||||
|
A[9]=-1
|
||||||
|
B[9]=12345
|
||||||
|
SORT 1,9,A,B
|
||||||
|
ASSERT__ A[1]==-1,"SORT"
|
||||||
|
ASSERT__ B[1]==12345,"SORT"
|
||||||
|
RSORT 1,8,A,B
|
||||||
|
ASSERT__ A[8]==-1,"RSORT"
|
||||||
|
ASSERT__ B[8]==12345,"RSORT"
|
||||||
|
END
|
||||||
|
SORTTEST
|
||||||
'SWAP TEST
|
'SWAP TEST
|
||||||
SWAPTEST
|
SWAPTEST
|
||||||
DEF SWAPTEST
|
DEF SWAPTEST
|
||||||
|
|||||||
@@ -1453,6 +1453,384 @@ class BuiltinFunction
|
|||||||
{
|
{
|
||||||
return p.inkey();
|
return p.inkey();
|
||||||
}
|
}
|
||||||
|
static auto getSortArgument(Value[] arg, out int start, out int count)
|
||||||
|
{
|
||||||
|
auto args = retro(arg);
|
||||||
|
//引数何も指定しなくても実行前エラーは出ない
|
||||||
|
if (args.length < 1)
|
||||||
|
throw new IllegalFunctionCall("");
|
||||||
|
if (args.length > 2)
|
||||||
|
{
|
||||||
|
if (args[0].isNumber || args[1].isNumber)
|
||||||
|
{
|
||||||
|
if (args[0].isNumber && args[1].isNumber)
|
||||||
|
{
|
||||||
|
start = args[0].castInteger();
|
||||||
|
count = args[1].castInteger();
|
||||||
|
args = args[2..$];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IllegalFunctionCall("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start = 0;
|
||||||
|
count = args[0].length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start = 0;
|
||||||
|
count = args[0].length;
|
||||||
|
}
|
||||||
|
if (args.length > 8)
|
||||||
|
throw new IllegalFunctionCall("");
|
||||||
|
foreach (ref a; args)
|
||||||
|
{
|
||||||
|
if (a.isString || !a.isArray)
|
||||||
|
{
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
struct wrappeeer
|
||||||
|
{
|
||||||
|
Value value;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
int[] integerArray;
|
||||||
|
double[] doubleArray;
|
||||||
|
wstring[] stringArray;
|
||||||
|
}
|
||||||
|
this(ref Value v)
|
||||||
|
{
|
||||||
|
value = v;
|
||||||
|
if (value.type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
integerArray = value.integerArray.array;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
doubleArray = value.doubleArray.array;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
stringArray = value.stringArray.array;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void slice(int x, int y)
|
||||||
|
{
|
||||||
|
if (value.type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
integerArray = integerArray[x..y];
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
doubleArray = doubleArray[x..y];
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
stringArray = stringArray[x..y];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t length()
|
||||||
|
{
|
||||||
|
if (value.type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
return integerArray.length;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
return doubleArray.length;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
return stringArray.length;
|
||||||
|
}
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
bool empty()
|
||||||
|
{
|
||||||
|
if (value.type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
return integerArray.empty;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
return doubleArray.empty;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
return stringArray.empty;
|
||||||
|
}
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
void popFront()
|
||||||
|
{
|
||||||
|
if (value.type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
integerArray.popFront;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
doubleArray.popFront;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
stringArray.popFront;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void front(Value v)
|
||||||
|
{
|
||||||
|
if (value.type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
integerArray.front = v.castInteger;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
doubleArray.front = v.castDouble;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
stringArray.front = v.castString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void popBack()
|
||||||
|
{
|
||||||
|
if (value.type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
integerArray.popBack;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
doubleArray.popBack;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
stringArray.popBack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value back()
|
||||||
|
{
|
||||||
|
if (value.type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
return Value(integerArray.back);
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
return Value(doubleArray.back);
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
return Value(stringArray.back);
|
||||||
|
}
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
void back(Value v)
|
||||||
|
{
|
||||||
|
if (value.type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
integerArray.back = v.castInteger;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
doubleArray.back = v.castDouble;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
stringArray.back = v.castString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
typeof(this) save()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
Value front()
|
||||||
|
{
|
||||||
|
if (value.type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
return Value(integerArray.front);
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
return Value(doubleArray.front);
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
return Value(stringArray.front);
|
||||||
|
}
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
void opIndexAssign(Value v, size_t index)
|
||||||
|
{
|
||||||
|
if (value.type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
integerArray[index] = v.castInteger;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
doubleArray[index] = v.castDouble;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
stringArray[index] = v.castString;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
Value opIndex(size_t index)
|
||||||
|
{
|
||||||
|
if (value.type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
return Value(integerArray[index]);
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
return Value(doubleArray[index]);
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
return Value(stringArray[index]);
|
||||||
|
}
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
wrappeeer opSlice(size_t x, size_t y)
|
||||||
|
{
|
||||||
|
wrappeeer aa = wrappeeer(value);
|
||||||
|
if (value.type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
aa.integerArray = integerArray[x..y];
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
aa.doubleArray = doubleArray[x..y];
|
||||||
|
}
|
||||||
|
if (value.type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
aa.stringArray = stringArray[x..y];
|
||||||
|
}
|
||||||
|
return aa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static string sortGenerator(int count, string less)()
|
||||||
|
{
|
||||||
|
string buf = "switch(args.length){";
|
||||||
|
string args = "";
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
args ~= ",wrappeeer(args[" ~ (i + 1).to!string ~ "])[start..start + count]";
|
||||||
|
buf ~= "case " ~ (i + 2).to!string ~ ":";
|
||||||
|
buf ~= "if(args[0].type==ValueType.IntegerArray){sort!(" ~ less ~ ", SwapStrategy.stable)(zip(iarray" ~ args ~ "));}";
|
||||||
|
buf ~= "else if(args[0].type==ValueType.DoubleArray){sort!(" ~ less ~ ", SwapStrategy.stable)(zip(darray" ~ args ~ "));}";
|
||||||
|
buf ~= "else if(args[0].type==ValueType.StringArray){sort!(" ~ less ~ ", SwapStrategy.stable)(zip(sarray" ~ args ~ "));}";
|
||||||
|
buf ~= "break;";
|
||||||
|
}
|
||||||
|
buf ~= "default:}";
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
//もう少しまともな実装できそう
|
||||||
|
static void SORT(Value[] arg)
|
||||||
|
{
|
||||||
|
import std.algorithm.sorting;
|
||||||
|
import std.range;
|
||||||
|
int start, count;
|
||||||
|
auto args = getSortArgument(arg, start, count);
|
||||||
|
|
||||||
|
int[] iarray;
|
||||||
|
double[] darray;
|
||||||
|
wstring[] sarray;
|
||||||
|
if (args[0].type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
iarray = args[0].integerArray.array[start..start + count];
|
||||||
|
}
|
||||||
|
if (args[0].type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
darray = args[0].doubleArray.array[start..start + count];
|
||||||
|
}
|
||||||
|
if (args[0].type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
sarray = args[0].stringArray.array[start..start + count];
|
||||||
|
}
|
||||||
|
if (args.length > 1)
|
||||||
|
{
|
||||||
|
mixin(sortGenerator!(8, "\"a[0]<b[0]\""));
|
||||||
|
/*
|
||||||
|
if (args[0].type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
sort!("a[0] < b[0]", SwapStrategy.stable)(zip(args[0].integerArray.array, wrappeeer(args[1])));
|
||||||
|
}
|
||||||
|
if (args[0].type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
sort!("a[0] < b[0]", SwapStrategy.stable)(zip(args[0].doubleArray.array, wrappeeer(args[1])));
|
||||||
|
}
|
||||||
|
if (args[0].type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
sort!("a[0] < b[0]", SwapStrategy.stable)(zip(args[0].stringArray.array, wrappeeer(args[1])));
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (args[0].type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
sort!("a < b", SwapStrategy.stable)(iarray);
|
||||||
|
}
|
||||||
|
if (args[0].type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
sort!("a < b", SwapStrategy.stable)(darray);
|
||||||
|
}
|
||||||
|
if (args[0].type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
sort!("a < b", SwapStrategy.stable)(sarray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void RSORT(Value[] arg)
|
||||||
|
{
|
||||||
|
import std.algorithm.sorting;
|
||||||
|
import std.range;
|
||||||
|
int start, count;
|
||||||
|
auto args = getSortArgument(arg, start, count);
|
||||||
|
|
||||||
|
int[] iarray;
|
||||||
|
double[] darray;
|
||||||
|
wstring[] sarray;
|
||||||
|
if (args[0].type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
iarray = args[0].integerArray.array[start..start + count];
|
||||||
|
}
|
||||||
|
if (args[0].type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
darray = args[0].doubleArray.array[start..start + count];
|
||||||
|
}
|
||||||
|
if (args[0].type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
sarray = args[0].stringArray.array[start..start + count];
|
||||||
|
}
|
||||||
|
if (args.length > 1)
|
||||||
|
{
|
||||||
|
mixin(sortGenerator!(8, "\"a[0]>b[0]\""));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (args[0].type == ValueType.IntegerArray)
|
||||||
|
{
|
||||||
|
sort!("a > b", SwapStrategy.stable)(iarray);
|
||||||
|
}
|
||||||
|
if (args[0].type == ValueType.DoubleArray)
|
||||||
|
{
|
||||||
|
sort!("a > b", SwapStrategy.stable)(darray);
|
||||||
|
}
|
||||||
|
if (args[0].type == ValueType.StringArray)
|
||||||
|
{
|
||||||
|
sort!("a > b", SwapStrategy.stable)(sarray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
//alias void function(PetitComputer, Value[], Value[]) BuiltinFunc;
|
//alias void function(PetitComputer, Value[], Value[]) BuiltinFunc;
|
||||||
static BuiltinFunctions[wstring] builtinFunctions;
|
static BuiltinFunctions[wstring] builtinFunctions;
|
||||||
static wstring getBasicName(BFD)(const wstring def)
|
static wstring getBasicName(BFD)(const wstring def)
|
||||||
|
|||||||
Reference in New Issue
Block a user