From cfec1b691198668c1252ae66465ce8e38bc113ee Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 6 Aug 2023 02:17:32 +1000 Subject: [PATCH] Added int to float coercions to function args and returns, when specified --- scripts/shadow.toy | 8 ++++++++ source/toy_interpreter.c | 14 ++++++++++++++ test/scripts/coercions.toy | 16 ++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 scripts/shadow.toy diff --git a/scripts/shadow.toy b/scripts/shadow.toy new file mode 100644 index 0000000..2b694a6 --- /dev/null +++ b/scripts/shadow.toy @@ -0,0 +1,8 @@ +//something was odd, so I broke this down for testing +import math; + +fn shadowCastPoint(x: float, y: float, depth: int) { + return sin(tan(x/y)) * depth; +} + +print shadowCastPoint(1, 1, 10); diff --git a/source/toy_interpreter.c b/source/toy_interpreter.c index a5f0fa5..1375a95 100644 --- a/source/toy_interpreter.c +++ b/source/toy_interpreter.c @@ -2310,6 +2310,13 @@ bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_Liter Toy_freeLiteral(argIdn); } + //BUGFIX: coerce ints to floats, if the function requires floats + if (TOY_IS_INTEGER(arg) && TOY_IS_TYPE(paramArray->literals[i + 1]) && TOY_AS_TYPE(paramArray->literals[i + 1]).typeOf == TOY_LITERAL_FLOAT) { + Toy_Literal f = TOY_TO_FLOAT_LITERAL( (float)TOY_AS_INTEGER(arg) ); + Toy_freeLiteral(arg); + arg = f; + } + if (!Toy_setScopeVariable(inner.scope, paramArray->literals[i], arg, false)) { interpreter->errorOutput("[internal] Could not define parameter (bad type?)\n"); @@ -2404,6 +2411,13 @@ bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_Liter for (int i = 0; i < returnsFromInner.count && returnValue; i++) { Toy_Literal ret = Toy_popLiteralArray(&returnsFromInner); + //BUGFIX: coerce the returned integers to floats, if specified + if (returnArray->count > 0 && TOY_AS_TYPE(returnArray->literals[i]).typeOf == TOY_LITERAL_FLOAT && TOY_IS_INTEGER(ret)) { + Toy_Literal f = TOY_TO_FLOAT_LITERAL( (float)TOY_AS_INTEGER(ret) ); + Toy_freeLiteral(ret); + ret = f; + } + //check the return types if (returnArray->count > 0 && TOY_AS_TYPE(returnArray->literals[i]).typeOf != ret.type) { interpreter->errorOutput("Bad type found in return value\n"); diff --git a/test/scripts/coercions.toy b/test/scripts/coercions.toy index 19acf6e..d0afe06 100644 --- a/test/scripts/coercions.toy +++ b/test/scripts/coercions.toy @@ -10,4 +10,20 @@ } +//test function coercion +{ + fn f(arg: float) { + assert typeof arg == float, "argument coercion failed"; + } + + f(42); + + fn g(): float { + return 42; + } + + assert typeof g() == float, "return coercion failed"; +} + + print "All good";