1
0

builtinfunction.dが追加されていなかったので追加

This commit is contained in:
otya128
2015-07-11 17:42:20 +09:00
parent a410f80ed0
commit 8a0ae76334
2 changed files with 208 additions and 0 deletions

View File

@@ -853,3 +853,22 @@ class CallFunctionCode : Code
} }
} }
} }
import otya.smilebasic.builtinfunctions;
class CallBuiltinFunction : Code
{
BuiltinFunction func;
int argcount;
int outcount;
this(BuiltinFunction func, int argcount, int outcount/+可変長引数用+/)
{
this.func = func;
this.argcount = argcount;
this.outcount = outcount;
}
override void execute(VM vm)
{
Value[] arg = vm.stack[vm.stacki - argcount..vm.stacki - 1];
Value[] result = vm.stack[vm.stacki - argcount..vm.stacki - argcount + outcount - 1];//雑;
func.func(vm.petitcomputer, arg, result);
}
}

View File

@@ -0,0 +1,189 @@
module otya.smilebasic.builtinfunctions;
import std.conv;
import std.typecons;
import std.typetuple;
import std.traits;
import std.stdio;
import std.ascii;
import otya.smilebasic.error;
import otya.smilebasic.type;
import otya.smilebasic.petitcomputer;
//プチコンの引数省略は特殊なので
//LOCATE ,,0のように省略できる
struct DefaultValue(T)
{
T value;
bool isDefault;
this(int v, bool f)
{
value = v;
isDefault = f;
}
this(int v)
{
value = v;
isDefault = false;
}
this(bool f)
{
isDefault = f;
}
mixin Proxy!value;
}
alias ValueType = otya.smilebasic.type.ValueType;
struct BuiltinFunctionArgument
{
ValueType argType;
bool optionalArg;
}
class BuiltinFunction
{
BuiltinFunctionArgument[] argments;
ValueType result;
void function(PetitComputer, Value[], Value[]) func;
this(BuiltinFunctionArgument[] argments, ValueType result, void function(PetitComputer, Value[], Value[]) func)
{
this.argments = argments;
this.result = result;
this.func = func;
}
import std.math;
/*
static pure double ABS(double a, double b)
{
return a < 0 ? -a : a;
}*/
static ABS = function(double x) => abs(x);
static void LOCATE(PetitComputer p, DefaultValue!int x, DefaultValue!int y, DefaultValue!int z)
{
}
//alias void function(PetitComputer, Value[], Value[]) BuiltinFunc;
static BuiltinFunction[wstring] builtinFunctions;
static this()
{
foreach(name; __traits(derivedMembers, BuiltinFunction))
{
writeln(name);
static if(/*__traits(isStaticFunction, __traits(getMember, BuiltinFunction, name)) && */name[0].isUpper)
{
builtinFunctions[name] = new BuiltinFunction(
GetFunctionParamType!(BuiltinFunction, name),
GetFunctionReturnType!(BuiltinFunction, name),
mixin(AddFunc!(BuiltinFunction, name))
);
writeln(AddFunc!(BuiltinFunction, name));
}
}
}
}
template GetFunctionReturnType(T, string N)
{
static if(is(ReturnType!(__traits(getMember, T, N)) == double))
{
enum GetFunctionReturnType = ValueType.Double;
}
else static if(is(ReturnType!(__traits(getMember, T, N)) == void))
{
enum GetFunctionReturnType = ValueType.Void;
}
else
{
enum GetFunctionReturnType = ValueType.Void;
static assert(false, "Invalid type");
}
}
template AddFunc(T, string N)
{
static if(is(ReturnType!(__traits(getMember, T, N)) == double))
{
const string AddFunc = "function void(PetitComputer p, Value[] arg, Value[] ret){if(ret.length != 1){throw new IllegalFunctionCall();}ret[0] = Value(" ~ N ~ "(" ~
AddFuncArg!(0, 0, ParameterTypeTuple!(__traits(getMember, T, N))) ~ "));}";
}
else static if(is(ReturnType!(__traits(getMember, T, N)) == void))
{
const string AddFunc = "function void(PetitComputer p, Value[] arg, Value[] ret){if(ret.length != 1){throw new IllegalFunctionCall();}" ~ N ~ "(" ~
AddFuncArg!(0, 0, ParameterTypeTuple!(__traits(getMember, T, N))) ~ ");}";
}
else
{
const string AddFunc = "";
static assert(false, "Invalid type");
}
}
DefaultValue!int fromIntToDefault(Value v)
{
if(v.isNumber)
return DefaultValue!int(v.castInteger());
else
return DefaultValue!int(true);
}
template GetFunctionParamType(T, string N)
{
enum GetFunctionParamType = mixin("[" ~ Array!(ParameterTypeTuple!(__traits(getMember, T, N))) ~ "]");
private template Array(P...)
{
static if(is(P[0] == double))
{
const string arg = "ValueType.Double, false";
}
else static if(is(P[0] == int))
{
const string arg = "ValueType.Integer, false";
}
else static if(is(P[0] == DefaultValue!int))
{
const string arg = "ValueType.Integer, true";
}
else static if(is(P[0] == PetitComputer))
{
enum Array = Array!(P[1..$]);
}
static if(1 == P.length && !is(P[0] == PetitComputer))
{
enum Array = "BuiltinFunctionArgument(" ~ arg ~ ")";
}
else static if(!is(P[0] == PetitComputer))
{
enum Array = "BuiltinFunctionArgument(" ~ arg ~ ")," ~ Array!(P[1..$]);
}
}
}
template AddFuncArg(int N, int M, P...)
{
static if(is(P[0] == double))
{
enum add = 1;
const string arg = "arg[" ~ N.to!string ~ "].castDouble";
}
else static if(is(P[0] == PetitComputer))
{
enum add = 0;
const string arg = "p";
}
else static if(is(P[0] == int))
{
enum add = 1;
const string arg = "arg[" ~ N.to!string ~ "].castInteger";
}
else static if(is(P[0] == DefaultValue!int))
{
enum add = 1;
const string arg = "fromIntToDefault(arg[" ~ N.to!string ~ "])";
}
else
{
enum add = 1;
static assert(false, "Invalid type");
const string arg = "";
}
static if(1 == P.length)
{
const string AddFuncArg = arg;
}
else
{
const string AddFuncArg = arg ~ ", " ~ AddFuncArg!(N + add, M + 1, P[1..$]);
}
}