From 78d145815572a7b28d6fb9169a5567a604e38846 Mon Sep 17 00:00:00 2001 From: Isaac Dupree Date: Sat, 26 May 2007 23:00:45 +0000 Subject: [PATCH] #1318: lex negative unboxed literals I reorganized the lexing of numeric literals a bit so the code didn't get too ugly, after trying a few ways, and also considering possible plans to be able to conditionally lex negative _boxed_ literals. --- compiler/parser/Lexer.x | 80 +++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/compiler/parser/Lexer.x b/compiler/parser/Lexer.x index de025de..db48dbe 100644 --- a/compiler/parser/Lexer.x +++ b/compiler/parser/Lexer.x @@ -108,6 +108,11 @@ $docsym = [\| \^ \* \$] @floating_point = @decimal \. @decimal @exponent? | @decimal @exponent +-- normal signed numerical literals can only be explicitly negative, +-- not explicitly positive (contrast @exponent) +@negative = \- +@signed = @negative ? + haskell :- -- everywhere: skip whitespace and comments @@ -353,22 +358,35 @@ $tab+ { warn Opt_WarnTabs (text "Tab character") } @consym { consym } } +-- For the normal boxed literals we need to be careful +-- when trying to be close to Haskell98 <0,glaexts> { - @decimal { tok_decimal } - 0[oO] @octal { tok_octal } - 0[xX] @hexadecimal { tok_hexadecimal } + -- Normal integral literals (:: Num a => a, from Integer) + @decimal { tok_num positive 0 0 decimal } + 0[oO] @octal { tok_num positive 2 2 octal } + 0[xX] @hexadecimal { tok_num positive 2 2 hexadecimal } + + -- Normal rational literals (:: Fractional a => a, from Rational) + @floating_point { strtoken tok_float } } { - @decimal \# { prim_decimal } - 0[oO] @octal \# { prim_octal } - 0[xX] @hexadecimal \# { prim_hexadecimal } + -- Unboxed ints (:: Int#) + -- It's simpler (and faster?) to give separate cases to the negatives, + -- especially considering octal/hexadecimal prefixes. + @decimal \# { tok_primint positive 0 1 decimal } + 0[oO] @octal \# { tok_primint positive 2 3 octal } + 0[xX] @hexadecimal \# { tok_primint positive 2 3 hexadecimal } + @negative @decimal \# { tok_primint negative 1 2 decimal } + @negative 0[oO] @octal \# { tok_primint negative 3 4 octal } + @negative 0[xX] @hexadecimal \# { tok_primint negative 3 4 hexadecimal } + + -- Unboxed floats and doubles (:: Float#, :: Double#) + -- prim_{float,double} work with signed literals + @signed @floating_point \# { init_strtoken 1 tok_primfloat } + @signed @floating_point \# \# { init_strtoken 2 tok_primdouble } } -<0,glaexts> @floating_point { strtoken tok_float } - @floating_point \# { init_strtoken 1 prim_float } - @floating_point \# \# { init_strtoken 2 prim_double } - -- Strings and chars are lexed by hand-written code. The reason is -- that even if we recognise the string or char here in the regex -- lexer, we would still have to parse the string afterward in order @@ -934,27 +952,29 @@ sym con span buf len = where fs = lexemeToFastString buf len -tok_decimal span buf len - = return (L span (ITinteger $! parseUnsignedInteger buf len 10 octDecDigit)) - -tok_octal span buf len - = return (L span (ITinteger $! parseUnsignedInteger (offsetBytes 2 buf) (len-2) 8 octDecDigit)) - -tok_hexadecimal span buf len - = return (L span (ITinteger $! parseUnsignedInteger (offsetBytes 2 buf) (len-2) 16 hexDigit)) - -prim_decimal span buf len - = return (L span (ITprimint $! parseUnsignedInteger buf (len-1) 10 octDecDigit)) - -prim_octal span buf len - = return (L span (ITprimint $! parseUnsignedInteger (offsetBytes 2 buf) (len-3) 8 octDecDigit)) - -prim_hexadecimal span buf len - = return (L span (ITprimint $! parseUnsignedInteger (offsetBytes 2 buf) (len-3) 16 hexDigit)) - +-- Variations on the integral numeric literal. +tok_integral :: (Integer -> Token) + -> (Integer -> Integer) + -- -> (StringBuffer -> StringBuffer) -> (Int -> Int) + -> Int -> Int + -> (Integer, (Char->Int)) -> Action +tok_integral itint transint transbuf translen (radix,char_to_int) span buf len = + return $ L span $ itint $! transint $ parseUnsignedInteger + (offsetBytes transbuf buf) (subtract translen len) radix char_to_int + +-- some conveniences for use with tok_integral +tok_num = tok_integral ITinteger +tok_primint = tok_integral ITprimint +positive = id +negative = negate +decimal = (10,octDecDigit) +octal = (8,octDecDigit) +hexadecimal = (16,hexDigit) + +-- readRational can understand negative rationals, exponents, everything. tok_float str = ITrational $! readRational str -prim_float str = ITprimfloat $! readRational str -prim_double str = ITprimdouble $! readRational str +tok_primfloat str = ITprimfloat $! readRational str +tok_primdouble str = ITprimdouble $! readRational str -- ----------------------------------------------------------------------------- -- Layout processing -- 1.7.10.4