//$ Floating point literals.
//$
//$ Follows ISO C89, except that we allow underscores;
//$ AND we require both leading and trailing digits so that
//$ x.0 works for tuple projections and 0.f is a function
//$ application
syntax felix_float_lexer {
regdef decimal_string = digit (underscore ? digit) *;
regdef hexadecimal_string = hexdigit (underscore ? hexdigit) *;
regdef decimal_fractional_constant =
decimal_string '.' decimal_string;
regdef hexadecimal_fractional_constant =
("0x" |"0X")
hexadecimal_string '.' hexadecimal_string;
regdef decimal_exponent = ('E'|'e') ('+'|'-')? decimal_string;
regdef binary_exponent = ('P'|'p') ('+'|'-')? decimal_string;
regdef floating_suffix = 'L' | 'l' | 'F' | 'f' | 'D' | 'd';
regdef floating_literal =
(
decimal_fractional_constant decimal_exponent ? |
hexadecimal_fractional_constant binary_exponent ?
)
floating_suffix ?;
// Floating constant.
regdef sfloat = floating_literal;
literal sfloat =># """
(let*
(
(val (stripus _1))
(val (tolower-string val))
(n (string-length val))
(n-1 (- n 1))
(ch (substring val n-1 n))
(rest (substring val 0 n-1))
(result
(if (equal? ch "l") `("ldouble" ,val ,val)
(if (equal? ch "f") `("float" ,val ,val) `("double" ,val ,val))
)
)
)
result
)
""";
strfloat := sfloat =># "(second _1)";
// Floating literal.
sliteral := sfloat =># "`(ast_literal ,_sr ,@_1)";
}