From 28d57d352eb3bf0ec7d9c7e2d3ed54b113cfbba9 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Tue, 5 Sep 2023 09:48:06 +0200 Subject: [PATCH] Add 'toBool' conversion function Added a new function 'toBool' to convert values into boolean type. The changes include adding a new class for this function, adding it to the application scope, and explaining its functionality in the Wiki page. Also added the test cases for the new function. The function is designed to interpret numbers, strings, lists, and other data types in a way that makes sense in a boolean context. This provides a more intuitive way for users to perform boolean operations with different data types. --- StepLang.Tests/Examples/conversions.step.out | 11 +++++ StepLang.Wiki/Functions/ToBool.md | 43 +++++++++++++++++++ StepLang/Examples/conversions.step | 12 ++++++ .../Framework/Conversion/ToBoolFunction.cs | 39 +++++++++++++++++ StepLang/Interpreting/Scope.cs | 1 + 5 files changed, 106 insertions(+) create mode 100644 StepLang.Wiki/Functions/ToBool.md create mode 100644 StepLang/Framework/Conversion/ToBoolFunction.cs diff --git a/StepLang.Tests/Examples/conversions.step.out b/StepLang.Tests/Examples/conversions.step.out index e625be1b..ec4356b4 100644 --- a/StepLang.Tests/Examples/conversions.step.out +++ b/StepLang.Tests/Examples/conversions.step.out @@ -8,3 +8,14 @@ null 170 10 255 +False +False +True +False +True +True +False +False +True +True +False diff --git a/StepLang.Wiki/Functions/ToBool.md b/StepLang.Wiki/Functions/ToBool.md new file mode 100644 index 00000000..2587e411 --- /dev/null +++ b/StepLang.Wiki/Functions/ToBool.md @@ -0,0 +1,43 @@ +# Description + +The `toBool` function converts a value to a boolean value. + +# Syntax + +``` +toBool(any value) +``` + +- `value` is the value to convert to a boolean value. + +# Remarks + +- The function returns `true` if the value is truthy (true-like), `false` otherwise. + Whether or not a value is truthy can be determined using the following table: + + | Value Type | Truthy | Falsy | + |------------|--------------------------------------|-----------| + | `bool` | `true` | `false` | + | `number` | `> 0` | `<= 0` | + | `string` | `"true"` (case insensitive) or `"1"` | otherwise | + | `list` | if not empty | otherwise | + | `map` | if not empty | otherwise | + | `null` | never | always | + | `void` | never | always | + | `function` | always | never | + +# Examples + +```step +println(toBool("")) // False +println(toBool("this is falsy")) // False +println(toBool("true")) // True +println(toBool("false")) // False +println(toBool("True")) // True +println(toBool("1")) // True +println(toBool("0")) // False +println(toBool(0)) // False +println(toBool(1)) // True +println(toBool(2)) // True +println(toBool(-1)) // False +``` \ No newline at end of file diff --git a/StepLang/Examples/conversions.step b/StepLang/Examples/conversions.step index 579778dd..eb76bca2 100644 --- a/StepLang/Examples/conversions.step +++ b/StepLang/Examples/conversions.step @@ -9,3 +9,15 @@ println(toNumber("FF", 16)) println(toNumber("aa", 16)) println(toNumber("1010", 2)) println(toNumber("377", 8)) + +println(toBool("")) +println(toBool("this is falsy")) +println(toBool("true")) +println(toBool("false")) +println(toBool("True")) +println(toBool("1")) +println(toBool("0")) +println(toBool(0)) +println(toBool(1)) +println(toBool(2)) +println(toBool(-1)) diff --git a/StepLang/Framework/Conversion/ToBoolFunction.cs b/StepLang/Framework/Conversion/ToBoolFunction.cs new file mode 100644 index 00000000..04add455 --- /dev/null +++ b/StepLang/Framework/Conversion/ToBoolFunction.cs @@ -0,0 +1,39 @@ +using StepLang.Interpreting; +using StepLang.Parsing.Expressions; + +namespace StepLang.Framework.Conversion; + +public class ToBoolFunction : NativeFunction +{ + public const string Identifier = "toBool"; + + public override async Task EvaluateAsync(Interpreter interpreter, IReadOnlyList arguments, CancellationToken cancellationToken = default) + { + CheckArgumentCount(arguments, 1); + + var value = await arguments.Single().EvaluateAsync(interpreter, cancellationToken); + + var result = value switch + { + StringResult stringResult when string.IsNullOrWhiteSpace(stringResult.Value) => false, + StringResult stringResult => stringResult.Value.ToUpperInvariant() switch + { + "TRUE" => true, + "1" => true, + _ => false, + }, + NumberResult numberResult => numberResult.Value > 0, + BoolResult boolResult => boolResult.Value, + ListResult listResult => listResult.Value.Count > 0, + MapResult mapResult => mapResult.Value.Count > 0, + FunctionResult => true, + NullResult => false, + VoidResult => false, + _ => throw new NotImplementedException(), + }; + + return new BoolResult(result); + } + + protected override string DebugParamsString => "any value"; +} \ No newline at end of file diff --git a/StepLang/Interpreting/Scope.cs b/StepLang/Interpreting/Scope.cs index e90b7ef4..0e65df2a 100644 --- a/StepLang/Interpreting/Scope.cs +++ b/StepLang/Interpreting/Scope.cs @@ -53,6 +53,7 @@ private Scope() SetVariable(ToStringFunction.Identifier, new FunctionResult(new ToStringFunction())); SetVariable(ToRadixFunction.Identifier, new FunctionResult(new ToRadixFunction())); SetVariable(ToNumberFunction.Identifier, new FunctionResult(new ToNumberFunction())); + SetVariable(ToBoolFunction.Identifier, new FunctionResult(new ToBoolFunction())); // other functions SetVariable(FileExistsFunction.Identifier, new FunctionResult(new FileExistsFunction()));