diff --git a/repl/lib_standard.c b/repl/lib_standard.c index d7d5a8c..4375488 100644 --- a/repl/lib_standard.c +++ b/repl/lib_standard.c @@ -7,6 +7,49 @@ #include #include +static int nativeAbs(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { + if (arguments->count != 1) { + interpreter->errorOutput("Incorrect number of arguments to abs\n"); + return -1; + } + + //get the self + Toy_Literal selfLiteral = Toy_popLiteralArray(arguments); + + //parse to value if needed + Toy_Literal selfLiteralIdn = selfLiteral; + if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) { + Toy_freeLiteral(selfLiteralIdn); + } + + if (TOY_IS_IDENTIFIER(selfLiteral)) { + Toy_freeLiteral(selfLiteral); + return -1; + } + + if (!(TOY_IS_INTEGER(selfLiteral) || TOY_IS_FLOAT(selfLiteral))) { + interpreter->errorOutput("Incorrect argument type passed to abs\n"); + Toy_freeLiteral(selfLiteral); + return -1; + } + + Toy_Literal result; + + if (TOY_IS_INTEGER(selfLiteral)) { + result = TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(selfLiteral) > 0 ? TOY_AS_INTEGER(selfLiteral) : -TOY_AS_INTEGER(selfLiteral) ); + } + if (TOY_IS_FLOAT(selfLiteral)) { + result = TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(selfLiteral) > 0 ? TOY_AS_FLOAT(selfLiteral) : -TOY_AS_FLOAT(selfLiteral) ); + } + + Toy_pushLiteralArray(&interpreter->stack, result); + + Toy_freeLiteral(result); + Toy_freeLiteral(selfLiteral); + + return 1; +} + static int nativeClock(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 0) { @@ -702,6 +745,36 @@ static int nativeGetValues(Toy_Interpreter* interpreter, Toy_LiteralArray* argum return 1; } +static int nativeHash(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { + if (arguments->count != 1) { + interpreter->errorOutput("Incorrect number of arguments to hash\n"); + return -1; + } + + //get the self + Toy_Literal selfLiteral = Toy_popLiteralArray(arguments); + + //parse to value if needed + Toy_Literal selfLiteralIdn = selfLiteral; + if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) { + Toy_freeLiteral(selfLiteralIdn); + } + + if (TOY_IS_IDENTIFIER(selfLiteral)) { + Toy_freeLiteral(selfLiteral); + return -1; + } + + Toy_Literal result = TOY_TO_INTEGER_LITERAL(Toy_hashLiteral(selfLiteral)); + + Toy_pushLiteralArray(&interpreter->stack, result); + + Toy_freeLiteral(result); + Toy_freeLiteral(selfLiteral); + + return 1; +} + static int nativeIndexOf(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 2) { @@ -1667,6 +1740,7 @@ typedef struct Natives { int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) { //build the natives list Natives natives[] = { + {"abs", nativeAbs}, {"clock", nativeClock}, {"concat", nativeConcat}, //array, dictionary, string {"containsKey", nativeContainsKey}, //dictionary @@ -1676,6 +1750,7 @@ int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_L {"forEach", nativeForEach}, //array, dictionary {"getKeys", nativeGetKeys}, //dictionary {"getValues", nativeGetValues}, //dictionary + {"hash", nativeHash}, {"indexOf", nativeIndexOf}, //array {"map", nativeMap}, //array, dictionary {"reduce", nativeReduce}, //array, dictionary diff --git a/test/scripts/lib/standard.toy b/test/scripts/lib/standard.toy index 5c9c17e..117bb70 100644 --- a/test/scripts/lib/standard.toy +++ b/test/scripts/lib/standard.toy @@ -1,5 +1,18 @@ import standard; +//test abs +{ + assert abs(-5) == 5, "abs(-integer) failed"; + assert abs(-5.5) == 5.5, "abs(-float) failed"; + assert abs(5) == 5, "abs(+integer) failed"; + assert abs(5.5) == 5.5, "abs(+float) failed"; + + var x = -5; + + assert x.abs() == 5, "var.abs() failed"; +} + + //test clock { //this depends on external factors, so only check the length @@ -162,6 +175,13 @@ import standard; } +//test hash +{ + assert typeof "Hello world".hash() == int, "typeof \"Hello world\".hash() failed"; + assert "Hello world".hash() == 994097935, "\"Hello world\".hash() failed"; //NOTE: specific value based on algorithm +} + + //test indexOf { var a = [1, 2, 42, 3];