Skip to content

Commit 92850d6

Browse files
authored
Merge pull request #147 from chr1st0scli/parse-number-culture
Parse number culture
2 parents c0ef93b + fc88b93 commit 92850d6

File tree

12 files changed

+63
-5
lines changed

12 files changed

+63
-5
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ Semantic versioning is followed.
1616

1717
### Removed
1818

19+
## [1.3.0] - 2024-06-30
20+
21+
### Added
22+
- `parse-number-culture` primitive procedure. #146
23+
1924
## [1.2.0] - 2024-02-18
2025

2126
### Added

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ RainLisp is a programming language, belonging to the LISP family of languages, w
1010

1111
It is not intended to replace your everyday programming language at work. Though, you can integrate it with your existing systems to allow for their configuration in terms of code.
1212

13-
For example, one can build a system where parts of its computations or workflow logic is implemented in RainLisp. Its simplicity and capabilites make it ideal for using it like a DSL (Domain Specific Language) that integrates with your .NET system.
13+
For example, one can build a system where parts of its computations or workflow logic is implemented in RainLisp. Its simplicity and capabilities make it ideal for using it like a DSL (Domain Specific Language) that integrates with your .NET system.
1414

1515
Additionally, you can easily extend it to implement your own LISP dialect or replace some of its components, like the tokenizer and parser, and reuse the evaluator to easily build an entirely different but compatible programming language.
1616

RainLisp/Docs/primitives.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
- [pair?](primitives/is-pair.md)
4949
- [parse-datetime](primitives/parse-datetime.md)
5050
- [parse-number](primitives/parse-number.md)
51+
- [parse-number-culture](primitives/parse-number-culture.md)
5152
- [replace-string](primitives/replace-string.md)
5253
- [round](primitives/round.md)
5354
- [second](primitives/second.md)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# parse-number-culture
2+
```scheme
3+
(parse-number-culture str culture)
4+
```
5+
Converts a string representation of a numeric value in a culture-specific format to its number equivalent.
6+
7+
> *str* is the string containing the numeric info.
8+
9+
> *culture* is a string specifying the culture name. If the culture name is an empty string, the [invariant](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo.invariantculture) culture is used.
10+
For a list of valid names, look at the "*Language tag*" column of the [language table](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c).
11+
12+
## Examples
13+
```scheme
14+
(parse-number-culture "2345.6789" "en-EN")
15+
```
16+
-> *2345.6789*
17+
18+
```scheme
19+
(parse-number-culture "2345,6789" "el-GR")
20+
```
21+
-> *2345.6789*

RainLisp/Docs/quick-start/numbers.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ The operations that relate to numbers are:
5656
- [floor](../primitives/floor.md)
5757
- [number-to-string](../primitives/number-to-string.md)
5858
- [parse-number](../primitives/parse-number.md)
59+
- [parse-number-culture](../primitives/parse-number-culture.md)
5960
- [round](../primitives/round.md)
6061

6162
Next, let's learn about [booleans](booleans.md).

RainLisp/Evaluation/PrimitiveOperation.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,17 @@ public static EvaluationResult NumberToString(EvaluationResult[]? values)
717717
public static EvaluationResult ParseNumber(EvaluationResult[]? values)
718718
=> ApplyUnaryOperator(AsString, val => ValueOrThrowInvalid(() => new NumberDatum(double.Parse(val, CultureInfo.InvariantCulture))), values);
719719

720+
/// <summary>
721+
/// Converts a string representation of a numeric value in a culture-specific format to its number equivalent.
722+
/// </summary>
723+
/// <param name="values">A string containing the numeric info, a string specifying the culture name. If the culture name is an empty string, the invariant culture is used.</param>
724+
/// <returns>The equivalent numeric value.</returns>
725+
/// <exception cref="WrongNumberOfArgumentsException">The given arguments are not two.</exception>
726+
/// <exception cref="WrongTypeOfArgumentException">Not all arguments are string values.</exception>
727+
/// <exception cref="InvalidValueException">The string value does not represent a number in a valid format for the specified culture or the culture is not found.</exception>
728+
public static EvaluationResult ParseNumberCulture(EvaluationResult[]? values)
729+
=> ApplyBinaryOperator(AsString, (val, cult) => ValueOrThrowInvalid(() => new NumberDatum(double.Parse(val, new CultureInfo(cult, false)))), values);
730+
720731
/// <summary>
721732
/// Rounds a numeric value to a specified number of fractional digits, using the away from zero rounding convention.
722733
/// </summary>

RainLisp/Grammar/Primitives.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,11 @@ public static class Primitives
315315
/// </summary>
316316
public const string PARSE_NUMBER = "parse-number";
317317

318+
/// <summary>
319+
/// Converts a string representation of a numeric value in a culture-specific format to its number equivalent.
320+
/// </summary>
321+
public const string PARSE_NUMBER_CULTURE = "parse-number-culture";
322+
318323
/// <summary>
319324
/// Rounds a numeric value to a specified number of fractional digits, using the away from zero rounding convention.
320325
/// </summary>

RainLisp/Interpreter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ void Install(string procedureName, Func<EvaluationResult[]?, EvaluationResult> i
338338
Install(DATETIME_TO_STRING, PrimitiveOperation.DateTimeToString);
339339
Install(NUMBER_TO_STRING, PrimitiveOperation.NumberToString);
340340
Install(PARSE_NUMBER, PrimitiveOperation.ParseNumber);
341+
Install(PARSE_NUMBER_CULTURE, PrimitiveOperation.ParseNumberCulture);
341342
Install(ROUND, PrimitiveOperation.Round);
342343
Install(CEILING, PrimitiveOperation.Ceiling);
343344
Install(FLOOR, PrimitiveOperation.Floor);

RainLisp/RainLisp.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<Nullable>enable</Nullable>
77
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
88
<Title>RainLisp a .NET LISP implementation</Title>
9-
<Version>1.2.0</Version>
9+
<Version>1.3.0</Version>
1010
<Description>RainLisp a .NET LISP implementation.</Description>
1111
<Copyright>2023</Copyright>
1212
<PackageProjectUrl>https://github.com/chr1st0scli/RainLisp</PackageProjectUrl>

RainLispTests/EvaluatorErrorTests.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public void Evaluate_CallExpectingTwoWithWrongNumberOfArguments_Throws(string ex
9898
Evaluate_CallsWithWrongNumberOfArguments_Throws(new[]
9999
{
100100
">", ">=", "<", "<=", "=", "cons", "set-car!", "set-cdr!",
101-
"add-years", "add-months", "add-days", "add-hours", "add-minutes", "add-seconds", "add-milliseconds", "number-to-string",
101+
"add-years", "add-months", "add-days", "add-hours", "add-minutes", "add-seconds", "add-milliseconds", "number-to-string", "parse-number-culture",
102102
"days-diff", "hours-diff", "minutes-diff", "seconds-diff", "milliseconds-diff", "parse-datetime", "datetime-to-string", "round"
103103
}, expression, expected, false, actual);
104104
}
@@ -420,7 +420,7 @@ public void Evaluate_CallExpectingStringWithWrongTypeOfArgument_Throws(string ex
420420
[InlineData("({0} \"hello\" true)", typeof(BoolDatum))]
421421
public void Evaluate_CallExpecting2StringsWithWrongTypeOfArgument_Throws(string expression, Type actual)
422422
{
423-
Evaluate_CallsWithWrongExpression_Throws(new[] { "parse-datetime" }, expression, actual, typeof(StringDatum));
423+
Evaluate_CallsWithWrongExpression_Throws(new[] { "parse-datetime", "parse-number-culture" }, expression, actual, typeof(StringDatum));
424424
}
425425

426426
[Theory]
@@ -587,6 +587,9 @@ public void Evaluate_ExpressionCallingNonProcedure_Throws(string expression)
587587
[InlineData("(replace-string \"hello\" \"\" \"world\")")]
588588
[InlineData("(parse-number \"\")")]
589589
[InlineData("(parse-number \"a\")")]
590+
[InlineData("(parse-number-culture \"\" \"EN\")")]
591+
[InlineData("(parse-number-culture \"a\" \"EN\")")]
592+
[InlineData("(parse-number-culture \"1\" \"WQXY\")")]
590593
[InlineData("(round 2.5 -1)")]
591594
[InlineData("(round 2.5 29)")]
592595
public void Evaluate_ExpressionWithInvalidValue_Throws(string expression)

RainLispTests/EvaluatorTests.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,16 @@ public void Evaluate_StringLiteral_Correctly(string expression, string expectedR
100100
[InlineData("(parse-number \"2.5\")", 2.5d)]
101101
[InlineData("(parse-number \"21.53\")", 21.53d)]
102102
[InlineData("(parse-number \"21,53\")", 2153d)]
103+
[InlineData("(parse-number-culture \"2\" \"\")", 2d)]
104+
[InlineData("(parse-number-culture \"2\" \"en\")", 2d)]
105+
[InlineData("(parse-number-culture \"21\" \"en\")", 21d)]
106+
[InlineData("(parse-number-culture \"2.5\" \"en\")", 2.5d)]
107+
[InlineData("(parse-number-culture \"2.5\" \"\")", 2.5d)]
108+
[InlineData("(parse-number-culture \"2,5\" \"\")", 25d)]
109+
[InlineData("(parse-number-culture \"21.53\" \"en\")", 21.53d)]
110+
[InlineData("(parse-number-culture \"21.53\" \"el\")", 2153d)]
111+
[InlineData("(parse-number-culture \"21,53\" \"en\")", 2153d)]
112+
[InlineData("(parse-number-culture \"21,53\" \"el\")", 21.53d)]
103113
[InlineData("(round 2.5 0)", 3d)]
104114
[InlineData("(round 2.4 0)", 2d)]
105115
[InlineData("(round 21.423 2)", 21.42d)]

nuget.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ RainLisp is a programming language, belonging to the LISP family of languages, w
77

88
It is not intended to replace your everyday programming language at work. Though, you can integrate it with your existing systems to allow for their configuration in terms of code.
99

10-
For example, one can build a system where parts of its computations or workflow logic is implemented in RainLisp. Its simplicity and capabilites make it ideal for using it like a DSL (Domain Specific Language) that integrates with your .NET system.
10+
For example, one can build a system where parts of its computations or workflow logic is implemented in RainLisp. Its simplicity and capabilities make it ideal for using it like a DSL (Domain Specific Language) that integrates with your .NET system.
1111

1212
Additionally, you can easily extend it to implement your own LISP dialect or replace some of its components, like the tokenizer and parser, and reuse the evaluator to easily build an entirely different but compatible programming language.
1313

0 commit comments

Comments
 (0)