From 243af92ed77b7673e36f4e40da7036a42e610ae2 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Wed, 14 Jun 2023 16:49:08 +0200 Subject: [PATCH] Core: CParser::ReadDoubleNoE (to ignore E part of double) --- uppsrc/Core/CvFlt.cpp | 17 +++++++++++++++-- uppsrc/Core/Parser.h | 1 + uppsrc/Core/src.tpp/CParser_en-us.tpp | 6 ++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/uppsrc/Core/CvFlt.cpp b/uppsrc/Core/CvFlt.cpp index 188411d9b..aee6b28ba 100644 --- a/uppsrc/Core/CvFlt.cpp +++ b/uppsrc/Core/CvFlt.cpp @@ -510,7 +510,7 @@ String FormatF(double x, int precision, dword flags) } template -const CHAR *ScanDbl(double& result, const CHAR *s, int alt_dp) +const CHAR *ScanDbl(double& result, const CHAR *s, int alt_dp, bool E = true) { SkipSpaces__(s); @@ -571,7 +571,7 @@ const CHAR *ScanDbl(double& result, const CHAR *s, int alt_dp) ReadNumber(); exp += int(s0 - s) + ignored; } - if(*s == 'e' || *s == 'E') { + if(E && (*s == 'e' || *s == 'E')) { dword e = 0; bool overflow = false; s++; @@ -676,4 +676,17 @@ double CParser::ReadDouble() return n; } +double CParser::ReadDoubleNoE() +{ + LTIMING("ReadDouble No E"); + double n; + const char *t = ScanDbl(n, term, '.', false); + if(!t) ThrowError("missing number"); + if(!IsFin(n)) + ThrowError("invalid number"); + term = t; + DoSpaces(); + return n; +} + }; \ No newline at end of file diff --git a/uppsrc/Core/Parser.h b/uppsrc/Core/Parser.h index 3f98b6fba..7add18770 100644 --- a/uppsrc/Core/Parser.h +++ b/uppsrc/Core/Parser.h @@ -64,6 +64,7 @@ public: bool IsDouble() const { return IsInt(); } bool IsDouble2() const; double ReadDouble(); + double ReadDoubleNoE(); bool IsString() const { return IsChar('\"'); }; String ReadOneString(bool chkend = true); String ReadString(bool chkend = true); diff --git a/uppsrc/Core/src.tpp/CParser_en-us.tpp b/uppsrc/Core/src.tpp/CParser_en-us.tpp index e738193c1..6ff2c0c28 100644 --- a/uppsrc/Core/src.tpp/CParser_en-us.tpp +++ b/uppsrc/Core/src.tpp/CParser_en-us.tpp @@ -312,6 +312,12 @@ As an exception to C lexical rules, ReadDouble also recognizes form starting with decimal point, like `".21`".&] [s3; &] [s4; &] +[s5;:Upp`:`:CParser`:`:ReadDoubleNoE`(`): [@(0.0.255) double] [* ReadDoubleNoE]()&] +[s2;%% Speacial variant of ReadDouble that ignores exponential part +of number. E.g. CParser(`"1.2em`").ReadDoubleNoE() returns 1.2 +(and does not throw error for invalid double).&] +[s3; &] +[s4; &] [s5;:CParser`:`:IsString`(`)const: [@(0.0.255) bool]_[* IsString]()_[@(0.0.255) const]&] [s2;%% Tests for C`-like string literal at the current position. Same as [* IsChar](`'`\`"`');&]