From 22d1d9d6208cb2aaf5c1fdfedda64d51d36146e3 Mon Sep 17 00:00:00 2001 From: Dmytro Kyshchenko Date: Sun, 27 Mar 2022 09:51:12 +0300 Subject: [PATCH] #513 - Time Units --- xFunc.Maths/Parser.cs | 29 ++++++++++++++++- xFunc.Tests/ParserTests/TimeUnitTests.cs | 40 ++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 xFunc.Tests/ParserTests/TimeUnitTests.cs diff --git a/xFunc.Maths/Parser.cs b/xFunc.Maths/Parser.cs index 4bb1b4598..1837c3c94 100644 --- a/xFunc.Maths/Parser.cs +++ b/xFunc.Maths/Parser.cs @@ -727,7 +727,8 @@ private ImmutableArray ParseParameterList(ref TokenReader tokenRead ParseAngleUnit(ref tokenReader) ?? ParsePowerUnit(ref tokenReader) ?? ParseMassUnit(ref tokenReader) ?? - ParseLengthUnit(ref tokenReader); + ParseLengthUnit(ref tokenReader) ?? + ParseTimeUnit(ref tokenReader); if (unit is not null) return unit; @@ -866,6 +867,32 @@ private ImmutableArray ParseParameterList(ref TokenReader tokenRead }; }); + private IExpression? ParseTimeUnit(ref TokenReader tokenReader) + => tokenReader.Scoped(this, static (Parser _, ref TokenReader reader) => + { + var number = reader.GetCurrent(TokenKind.Number); + if (number.IsEmpty()) + return null; + + var id = reader.GetCurrent(Id); + if (id.IsEmpty()) + return null; + + return id.StringValue switch + { + "s" => TimeValue.Second(number.NumberValue).AsExpression(), + "ns" => TimeValue.Nanosecond(number.NumberValue).AsExpression(), + "μs" => TimeValue.Microsecond(number.NumberValue).AsExpression(), + "ms" => TimeValue.Millisecond(number.NumberValue).AsExpression(), + "min" => TimeValue.Minute(number.NumberValue).AsExpression(), + "h" => TimeValue.Hour(number.NumberValue).AsExpression(), + "day" => TimeValue.Day(number.NumberValue).AsExpression(), + "week" => TimeValue.Week(number.NumberValue).AsExpression(), + "year" => TimeValue.Year(number.NumberValue).AsExpression(), + _ => null, + }; + }); + private IExpression? ParsePolarComplexNumber(ref TokenReader tokenReader) => tokenReader.Scoped(this, static (Parser _, ref TokenReader reader) => { diff --git a/xFunc.Tests/ParserTests/TimeUnitTests.cs b/xFunc.Tests/ParserTests/TimeUnitTests.cs new file mode 100644 index 000000000..509408976 --- /dev/null +++ b/xFunc.Tests/ParserTests/TimeUnitTests.cs @@ -0,0 +1,40 @@ +namespace xFunc.Tests.ParserTests; + +public class TimeUnitTests : BaseParserTests +{ + [Fact] + public void ParseSecond() + => ParseTest("1 s", TimeValue.Second(1).AsExpression()); + + [Fact] + public void ParseNanosecond() + => ParseTest("1 ns", TimeValue.Nanosecond(1).AsExpression()); + + [Fact] + public void ParseMicrosecond() + => ParseTest("1 μs", TimeValue.Microsecond(1).AsExpression()); + + [Fact] + public void ParseMillisecond() + => ParseTest("1 ms", TimeValue.Millisecond(1).AsExpression()); + + [Fact] + public void ParseMinute() + => ParseTest("1 min", TimeValue.Minute(1).AsExpression()); + + [Fact] + public void ParseHour() + => ParseTest("1 h", TimeValue.Hour(1).AsExpression()); + + [Fact] + public void ParseDay() + => ParseTest("1 day", TimeValue.Day(1).AsExpression()); + + [Fact] + public void ParseWeek() + => ParseTest("1 week", TimeValue.Week(1).AsExpression()); + + [Fact] + public void ParseYear() + => ParseTest("1 year", TimeValue.Year(1).AsExpression()); +} \ No newline at end of file