1
0

SORTを実装

This commit is contained in:
otya128
2016-09-03 15:40:11 +09:00
parent d138da32eb
commit cc85f76b81
2 changed files with 418 additions and 0 deletions

View File

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

View File

@@ -1453,6 +1453,384 @@ class BuiltinFunction
{
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;
static BuiltinFunctions[wstring] builtinFunctions;
static wstring getBasicName(BFD)(const wstring def)