diff --git a/sjscript/src/sjscript/calculate.d b/sjscript/src/sjscript/calculate.d index 59db6ec..39c2c2a 100644 --- a/sjscript/src/sjscript/calculate.d +++ b/sjscript/src/sjscript/calculate.d @@ -2,13 +2,15 @@ module sjscript.calculate; import std.algorithm, + std.array, std.exception, std.format, std.math, std.traits, std.variant; -import sjscript.Expression; +import sjscript.Expression, + sjscript.func; /// enum IsVarStore(T) = @@ -59,7 +61,6 @@ float CalculateTermValue(VarStore)(in Term.Value value, VarStore vars) /// float CalculateFunction(VarStore)(in FunctionCall fcall, VarStore vars) if (IsVarStore!VarStore) { - const args = fcall.args.map!(x => x.CalculateExpression(vars)); - // TODO: calling function - return 0; + return fcall.name.CallFunction( + fcall.args.map!(x => x.CalculateExpression(vars)).array); } diff --git a/sjscript/src/sjscript/func.d b/sjscript/src/sjscript/func.d new file mode 100644 index 0000000..3b51752 --- /dev/null +++ b/sjscript/src/sjscript/func.d @@ -0,0 +1,43 @@ +/// License: MIT +module sjscript.func; + +import std.algorithm, + std.exception, + std.math; + +/// +float CallFunction(string name, float[] args) { + void EnforceArgs(size_t len)() { + (args.length == len).enforce("invalid arguments"); + } + + switch (name) { + // ---- misc + case "abs": EnforceArgs!1; return fabs(args[0]); + case "sqrt": EnforceArgs!1; return sqrt(args[0]); + case "exp": EnforceArgs!1; return exp(args[0]); + case "pow": EnforceArgs!2; return pow(args[0], args[1]); + + // ---- triangle + case "sin": EnforceArgs!1; return sin(args[0]); + case "cos": EnforceArgs!1; return cos(args[0]); + case "tan": EnforceArgs!1; return tan(args[0]); + + case "asin": EnforceArgs!1; return asin(args[0]); + case "acos": EnforceArgs!1; return acos(args[0]); + case "atan": EnforceArgs!1; return atan(args[0]); + + case "atan2": EnforceArgs!2; return atan2(args[0], args[1]); + + // ---- rounding + case "ceil": EnforceArgs!1; return ceil(args[0]); + case "floor": EnforceArgs!1; return floor(args[0]); + case "round": EnforceArgs!1; return round(args[0]); + + // ---- conditional switch + case "step": EnforceArgs!2; return args[1] > args[0]? 1: 0; + case "clamp": EnforceArgs!3; return clamp(args[0], args[1], args[3]); + + default: throw new Exception("unknown exception"); + } +} diff --git a/sjscript/test/test01.sj b/sjscript/test/test01.sj index d60054f..1ec5d7f 100644 --- a/sjscript/test/test01.sj +++ b/sjscript/test/test01.sj @@ -1,5 +1,7 @@ // this is comment +$define pi {3.14} + $define sinwave { translate_x = $sinwave_add_x + sin(rtime * $sinwave_hz) * $sinwave_amp_x; translate_y = $sinwave_add_y + cos(rtime * $sinwave_hz) * $sinwave_amp_y; @@ -16,7 +18,7 @@ $define shoot { translate_y += __dir_y; } -$define beat {0} +$define beat {sin($pi/4)} A [$beat..$beat+10] { $define sinwave_add_x {0.5} $define sinwave_add_y {0.5}