Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions lib/Translation/ForthToMLIR/ForthToMLIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,39 @@ bool ForthLexer::isNumber(const std::string &str) const {
return true;
}

/// Float grammar: [+-]? (D+ '.' D* | '.' D+ | D+) ([eE] [+-]? D+)?, where a
/// bare D+ needs the exponent. Spelled out rather than using strtod, which
/// also accepts hex, nan and inf.
bool ForthLexer::isFloat(const std::string &str) const {
if (str.empty())
size_t i = 0;
size_t n = str.size();
auto skipDigits = [&]() {
size_t start = i;
while (i < n && std::isdigit(static_cast<unsigned char>(str[i])))
++i;
return i - start;
};

if (i < n && (str[i] == '+' || str[i] == '-'))
++i;
size_t mantissaDigits = skipDigits();
bool hasDot = i < n && str[i] == '.';
if (hasDot) {
++i;
mantissaDigits += skipDigits();
}
if (mantissaDigits == 0)
return false;

double value;
return llvm::to_float(str, value);
bool hasExponent = i < n && (str[i] == 'e' || str[i] == 'E');
if (hasExponent) {
++i;
if (i < n && (str[i] == '+' || str[i] == '-'))
++i;
if (skipDigits() == 0)
return false;
}
return i == n && (hasDot || hasExponent);
}

Token ForthLexer::nextToken() {
Expand Down
19 changes: 19 additions & 0 deletions test/Translation/Forth/float-literal-strtod-spellings.forth
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
\ RUN: %warpforth-translate --forth-to-mlir %s | %FileCheck %s

\ Hex, nan and inf spellings are ordinary words, not float literals.
\ CHECK-NOT: f64
\ CHECK: func.func private @NAN(
\ CHECK: func.func private @INF(
\ CHECK: func.func private @INFINITY(
\ CHECK: func.func private @_0X1P3(
\ CHECK: func.func @main()
\ CHECK: call @NAN(
\ CHECK: call @INF(
\ CHECK: call @INFINITY(
\ CHECK: call @_0X1P3(
\! kernel main
: nan 7 ;
: inf 8 ;
: infinity 9 ;
: 0x1p3 10 ;
nan inf infinity 0x1p3
8 changes: 7 additions & 1 deletion test/Translation/Forth/float-literals.forth
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@
\ CHECK-NEXT: forth.constant %{{.*}}(-2.000000e+00 : f64)
\ CHECK-NEXT: forth.constant %{{.*}}(1.000000e-05 : f64)
\ CHECK-NEXT: forth.constant %{{.*}}(1.000000e+03 : f64)
\ CHECK-NEXT: forth.constant %{{.*}}(1.000000e+03 : f64)
\ CHECK-NEXT: forth.constant %{{.*}}(5.000000e-01 : f64)
\ CHECK-NEXT: forth.constant %{{.*}}(-5.000000e-01 : f64)
\ CHECK-NEXT: forth.constant %{{.*}}(5.000000e+00 : f64)
\ CHECK-NEXT: forth.constant %{{.*}}(1.500000e+00 : f64)
\ CHECK-NEXT: forth.constant %{{.*}}(2.500000e+02 : f64)
\! kernel main
3.14 -2.0 1.0e-5 1e3
3.14 -2.0 1.0e-5 1e3 1E3 .5 -.5 5. +1.5 2.5e+2
5 changes: 5 additions & 0 deletions test/Translation/Forth/hex-literal-error.forth
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s
\ CHECK: {{.*}}hex-literal-error.forth:5:1: error: unknown word: 0X10
\! kernel k
\! param a i64[1]
0x10 a !
Loading