language-lua (empty) → 0.1
raw patch · 12 files changed
+2444/−0 lines, 12 filesdep +arraydep +basedep +mtlsetup-changed
Dependencies added: array, base, mtl, parsec
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- dist/build/Language/Lua/Lexer.hs +484/−0
- language-lua.cabal +37/−0
- src/Language/Lua/Lexer.x +148/−0
- src/Language/Lua/Parser.hs +374/−0
- src/Language/Lua/PrettyPrinter.hs +181/−0
- src/Language/Lua/Token.hs +66/−0
- src/Language/Lua/Types.hs +88/−0
- src/Text/Parsec/LTok.hs +45/−0
- src/Text/PrettyPrint/LICENSE +25/−0
- src/Text/PrettyPrint/Leijen.hs +964/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2012, Ömer Sinan Ağacan++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Ömer Sinan Ağacan nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ dist/build/Language/Lua/Lexer.hs view
@@ -0,0 +1,484 @@+{-# LANGUAGE CPP,MagicHash #-}+{-# LINE 4 "src/Language/Lua/Lexer.x" #-}++module Language.Lua.Lexer+ ( llex+ , LTok+ , AlexPosn(..)+ ) where++import Language.Lua.Token++#if __GLASGOW_HASKELL__ >= 603+#include "ghcconfig.h"+#elif defined(__GLASGOW_HASKELL__)+#include "config.h"+#endif+#if __GLASGOW_HASKELL__ >= 503+import Data.Array+import Data.Char (ord)+import Data.Array.Base (unsafeAt)+#else+import Array+import Char (ord)+#endif+#if __GLASGOW_HASKELL__ >= 503+import GHC.Exts+#else+import GlaExts+#endif+{-# LINE 1 "templates/wrappers.hs" #-}+{-# LINE 1 "templates/wrappers.hs" #-}+{-# LINE 1 "<command-line>" #-}+{-# LINE 1 "templates/wrappers.hs" #-}+-- -----------------------------------------------------------------------------+-- Alex wrapper code.+--+-- This code is in the PUBLIC DOMAIN; you may copy it freely and use+-- it for any purpose whatsoever.++import Data.Word (Word8)+{-# LINE 22 "templates/wrappers.hs" #-}++import qualified Data.Bits++-- | Encode a Haskell String to a list of Word8 values, in UTF8 format.+utf8Encode :: Char -> [Word8]+utf8Encode = map fromIntegral . go . ord+ where+ go oc+ | oc <= 0x7f = [oc]++ | oc <= 0x7ff = [ 0xc0 + (oc `Data.Bits.shiftR` 6)+ , 0x80 + oc Data.Bits..&. 0x3f+ ]++ | oc <= 0xffff = [ 0xe0 + (oc `Data.Bits.shiftR` 12)+ , 0x80 + ((oc `Data.Bits.shiftR` 6) Data.Bits..&. 0x3f)+ , 0x80 + oc Data.Bits..&. 0x3f+ ]+ | otherwise = [ 0xf0 + (oc `Data.Bits.shiftR` 18)+ , 0x80 + ((oc `Data.Bits.shiftR` 12) Data.Bits..&. 0x3f)+ , 0x80 + ((oc `Data.Bits.shiftR` 6) Data.Bits..&. 0x3f)+ , 0x80 + oc Data.Bits..&. 0x3f+ ]++++type Byte = Word8++-- -----------------------------------------------------------------------------+-- The input type+++type AlexInput = (AlexPosn, -- current position,+ Char, -- previous char+ [Byte], -- pending bytes on current char+ String) -- current input string++ignorePendingBytes :: AlexInput -> AlexInput+ignorePendingBytes (p,c,ps,s) = (p,c,[],s)++alexInputPrevChar :: AlexInput -> Char+alexInputPrevChar (p,c,bs,s) = c++alexGetByte :: AlexInput -> Maybe (Byte,AlexInput)+alexGetByte (p,c,(b:bs),s) = Just (b,(p,c,bs,s))+alexGetByte (p,c,[],[]) = Nothing+alexGetByte (p,_,[],(c:s)) = let p' = alexMove p c + (b:bs) = utf8Encode c+ in p' `seq` Just (b, (p', c, bs, s))+++{-# LINE 89 "templates/wrappers.hs" #-}++{-# LINE 103 "templates/wrappers.hs" #-}++{-# LINE 118 "templates/wrappers.hs" #-}++-- -----------------------------------------------------------------------------+-- Token positions++-- `Posn' records the location of a token in the input text. It has three+-- fields: the address (number of chacaters preceding the token), line number+-- and column of a token within the file. `start_pos' gives the position of the+-- start of the file and `eof_pos' a standard encoding for the end of file.+-- `move_pos' calculates the new position after traversing a given character,+-- assuming the usual eight character tab stops.+++data AlexPosn = AlexPn !Int !Int !Int+ deriving (Eq,Show)++alexStartPos :: AlexPosn+alexStartPos = AlexPn 0 1 1++alexMove :: AlexPosn -> Char -> AlexPosn+alexMove (AlexPn a l c) '\t' = AlexPn (a+1) l (((c+7) `div` 8)*8+1)+alexMove (AlexPn a l c) '\n' = AlexPn (a+1) (l+1) 1+alexMove (AlexPn a l c) _ = AlexPn (a+1) l (c+1)+++-- -----------------------------------------------------------------------------+-- Default monad++{-# LINE 231 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- Monad (with ByteString input)++{-# LINE 320 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- Basic wrapper++{-# LINE 346 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- Basic wrapper, ByteString version++{-# LINE 364 "templates/wrappers.hs" #-}++{-# LINE 377 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- Posn wrapper++-- Adds text positions to the basic model.+++--alexScanTokens :: String -> [token]+alexScanTokens str = go (alexStartPos,'\n',[],str)+ where go inp@(pos,_,_,str) =+ case alexScan inp 0 of+ AlexEOF -> []+ AlexError ((AlexPn _ line column),_,_,_) -> error $ "lexical error at " ++ (show line) ++ " line, " ++ (show column) ++ " column"+ AlexSkip inp' len -> go inp'+ AlexToken inp' len act -> act pos (take len str) : go inp'++++-- -----------------------------------------------------------------------------+-- Posn wrapper, ByteString version++{-# LINE 409 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- GScan wrapper++-- For compatibility with previous versions of Alex, and because we can.++alex_base :: AlexAddr+alex_base = AlexA# "\xf8\xff\xff\xff\x77\x00\x00\x00\xc9\xff\xff\xff\xbb\x00\x00\x00\x94\x01\x00\x00\x8d\x01\x00\x00\x00\x00\x00\x00\xfe\x01\x00\x00\xfe\x02\x00\x00\xc7\x00\x00\x00\xbe\x02\x00\x00\xbe\x03\x00\x00\x0e\x04\x00\x00\x26\x04\x00\x00\xdf\x03\x00\x00\x00\x00\x00\x00\x20\x04\x00\x00\x20\x05\x00\x00\x75\x05\x00\x00\x8c\x05\x00\x00\xc3\x05\x00\x00\xe9\x05\x00\x00\x00\x06\x00\x00\x26\x06\x00\x00\xdc\xff\xff\xff\xde\x00\x00\x00\xed\x00\x00\x00\xfe\x00\x00\x00\x8d\x06\x00\x00\x4d\x06\x00\x00\x00\x00\x00\x00\xf9\x00\x00\x00\x43\x07\x00\x00\x1e\x07\x00\x00\x15\x08\x00\x00\x2b\x08\x00\x00\xaa\x01\x00\x00\x36\x08\x00\x00\xda\x05\x00\x00\x54\x08\x00\x00\x7a\x08\x00\x00\xa0\x08\x00\x00\xb7\x08\x00\x00\x00\x00\x00\x00\x28\x09\x00\x00\x00\x00\x00\x00\xdb\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd\xff\xff\xff\xce\xff\xff\xff\xd9\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd\xff\xff\xff\x00\x00\x00\x00\x3f\x06\x00\x00\xeb\xff\xff\xff\x00\x00\x00\x00"#++alex_table :: AlexAddr+alex_table = AlexA# "\x00\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x35\x00\x19\x00\x20\x00\x19\x00\x36\x00\x37\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x34\x00\x41\x00\x1f\x00\x47\x00\x11\x00\x33\x00\x00\x00\x31\x00\x00\x00\x01\x00\x3b\x00\x3c\x00\x2f\x00\x2d\x00\x44\x00\x2e\x00\x45\x00\x30\x00\x23\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x43\x00\x42\x00\x38\x00\x3a\x00\x39\x00\x00\x00\x00\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x3f\x00\x00\x00\x40\x00\x32\x00\x00\x00\x00\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x3d\x00\x00\x00\x3e\x00\x02\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x2c\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x04\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x1b\x00\x1f\x00\x1b\x00\x00\x00\x00\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x00\x00\x08\x00\x0a\x00\x1c\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x09\x00\x03\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x10\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x00\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x11\x00\x00\x00\x00\x00\x11\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x11\x00\x00\x00\x11\x00\x00\x00\x0c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x00\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x2b\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x0d\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x14\x00\x00\x00\x14\x00\x00\x00\x00\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x16\x00\x00\x00\x16\x00\x00\x00\x00\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x00\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x00\x00\x00\x00\x00\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x00\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x46\x00\x00\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\x00\x00\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1c\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1d\x00\x03\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x10\x00\x05\x00\x06\x00\x06\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x25\x00\x00\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x25\x00\x1a\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x00\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2a\x00\x17\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x00\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x00\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x2c\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x04\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#++alex_check :: AlexAddr+alex_check = AlexA# "\xff\xff\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x3d\x00\x2b\x00\x2d\x00\x2d\x00\x3d\x00\x3d\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3d\x00\x3a\x00\x20\x00\x2e\x00\x22\x00\x23\x00\xff\xff\x25\x00\xff\xff\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\xff\xff\x5d\x00\x5e\x00\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\xff\xff\x7d\x00\x7e\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\xff\xff\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x2b\x00\x20\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xc2\x00\xc3\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x45\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x58\x00\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\xff\xff\xff\xff\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\x72\x00\xff\xff\x74\x00\xff\xff\x76\x00\xff\xff\x78\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x22\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x45\x00\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x58\x00\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\xff\xff\xff\xff\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\x72\x00\xff\xff\x74\x00\xff\xff\x76\x00\xff\xff\x78\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\xff\xff\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x2b\x00\xff\xff\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc2\x00\xc3\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x2b\x00\xff\xff\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x0a\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2e\x00\x45\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x45\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x65\x00\x45\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2e\x00\x58\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\x65\x00\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x65\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x78\x00\x50\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\xff\xff\xff\xff\xff\xff\x70\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x50\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x70\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\xff\xff\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc2\x00\xc3\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#++alex_deflt :: AlexAddr+alex_deflt = AlexA# "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0f\x00\x0f\x00\x01\x00\xff\xff\x01\x00\x11\x00\xff\xff\xff\xff\x11\x00\x1e\x00\x1e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x20\x00\x20\x00\x20\x00\xff\xff\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#++alex_accept = listArray (0::Int,71) [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[(AlexAccSkip)],[(AlexAccSkip)],[(AlexAcc (alex_action_2))],[(AlexAcc (alex_action_3))],[(AlexAcc (alex_action_3))],[(AlexAcc (alex_action_4))],[(AlexAcc (alex_action_5))],[(AlexAcc (alex_action_5))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_7))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_9))],[(AlexAcc (alex_action_10))],[(AlexAcc (alex_action_11))],[(AlexAcc (alex_action_12))],[(AlexAcc (alex_action_13))],[(AlexAcc (alex_action_14))],[(AlexAcc (alex_action_15))],[(AlexAcc (alex_action_16))],[(AlexAcc (alex_action_17))],[(AlexAcc (alex_action_18))],[(AlexAcc (alex_action_19))],[(AlexAcc (alex_action_20))],[(AlexAcc (alex_action_21))],[(AlexAcc (alex_action_22))],[(AlexAcc (alex_action_23))],[(AlexAcc (alex_action_24))],[(AlexAcc (alex_action_25))],[(AlexAcc (alex_action_26))],[(AlexAcc (alex_action_27))],[(AlexAcc (alex_action_28))],[(AlexAcc (alex_action_29))],[(AlexAcc (alex_action_30))],[(AlexAcc (alex_action_31))],[(AlexAcc (alex_action_32))],[(AlexAcc (alex_action_33))],[(AlexAcc (alex_action_34))],[(AlexAcc (alex_action_35))],[(AlexAcc (alex_action_36))],[(AlexAcc (alex_action_37))]]+{-# LINE 91 "src/Language/Lua/Lexer.x" #-}+++-- | Lua token with position information.+type LTok = (LToken, AlexPosn)+type AlexAction = AlexPosn -> String -> LTok++{-# INLINE ident #-}+ident :: AlexAction+ident posn "and" = (LTokAnd, posn)+ident posn "break" = (LTokBreak, posn)+ident posn "do" = (LTokDo, posn)+ident posn "else" = (LTokElse, posn)+ident posn "elseif" = (LTokElseIf, posn)+ident posn "end" = (LTokEnd, posn)+ident posn "false" = (LTokFalse, posn)+ident posn "for" = (LTokFor, posn)+ident posn "function" = (LTokFunction, posn)+ident posn "goto" = (LTokGoto, posn)+ident posn "if" = (LTokIf, posn)+ident posn "in" = (LTokIn, posn)+ident posn "local" = (LTokLocal, posn)+ident posn "nil" = (LTokNil, posn)+ident posn "not" = (LTokNot, posn)+ident posn "or" = (LTokOr, posn)+ident posn "repeat" = (LTokRepeat, posn)+ident posn "return" = (LTokReturn, posn)+ident posn "then" = (LTokThen, posn)+ident posn "true" = (LTokTrue, posn)+ident posn "until" = (LTokUntil, posn)+ident posn "while" = (LTokWhile, posn)+ident posn name = (LTokIdent name, posn)++--data AlexPosn = AlexPn !Int -- absolute character offset+-- !Int -- line number+-- !Int -- column number+--+--type AlexInput = (AlexPosn, -- current position,+-- Char, -- previous char+-- [Byte], -- rest of the bytes for the current char+-- String) -- current input string++alexScanTokens' :: String -> [LTok]+alexScanTokens' str = go (alexStartPos,'\n',[],str)+ where go inp@(pos,_,_,str) =+ case alexScan inp 0 of+ AlexEOF -> [(LTokEof, pos)]+ AlexError ((AlexPn _ line column),_,_,_) -> error $ "lexical error at " ++ (show line) ++ " line, " ++ (show column) ++ " column"+ AlexSkip inp' len -> go inp'+ AlexToken inp' len act -> act pos (take len str) : go inp'++-- | Lua lexer.+llex :: String -> [LTok]+llex = alexScanTokens'++main = do+ s <- getContents+ print (alexScanTokens s)++alex_action_2 = ident +alex_action_3 = \posn s -> (LTokNum s, posn) +alex_action_4 = \posn s -> (LTokNum s, posn) +alex_action_5 = \posn s -> (LTokNum s, posn) +alex_action_6 = \posn s -> (LTokNum s, posn) +alex_action_7 = \posn s -> (LTokNum s, posn) +alex_action_8 = \posn s -> (LTokNum s, posn) +alex_action_9 = \posn s -> (LTokSLit (tail . init $ s), posn) +alex_action_10 = \posn s -> (LTokSLit (tail . init $ s), posn) +alex_action_11 = \posn _ -> (LTokPlus, posn) +alex_action_12 = \posn _ -> (LTokMinus, posn) +alex_action_13 = \posn _ -> (LTokStar, posn) +alex_action_14 = \posn _ -> (LTokSlash, posn) +alex_action_15 = \posn _ -> (LTokPercent, posn) +alex_action_16 = \posn _ -> (LTokExp, posn) +alex_action_17 = \posn _ -> (LTokSh, posn) +alex_action_18 = \posn _ -> (LTokEqual, posn) +alex_action_19 = \posn _ -> (LTokNotequal, posn) +alex_action_20 = \posn _ -> (LTokLEq, posn) +alex_action_21 = \posn _ -> (LTokGEq, posn) +alex_action_22 = \posn _ -> (LTokLT, posn) +alex_action_23 = \posn _ -> (LTokGT, posn) +alex_action_24 = \posn _ -> (LTokAssign, posn) +alex_action_25 = \posn _ -> (LTokLParen, posn) +alex_action_26 = \posn _ -> (LTokRParen, posn) +alex_action_27 = \posn _ -> (LTokLBrace, posn) +alex_action_28 = \posn _ -> (LTokRBrace, posn) +alex_action_29 = \posn _ -> (LTokLBracket, posn) +alex_action_30 = \posn _ -> (LTokRBracket, posn) +alex_action_31 = \posn _ -> (LTokDColon, posn) +alex_action_32 = \posn _ -> (LTokSemic, posn) +alex_action_33 = \posn _ -> (LTokColon, posn) +alex_action_34 = \posn _ -> (LTokComma, posn) +alex_action_35 = \posn _ -> (LTokDot, posn) +alex_action_36 = \posn _ -> (LTokDDot, posn) +alex_action_37 = \posn _ -> (LTokEllipsis, posn) +{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "<command-line>" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+-- -----------------------------------------------------------------------------+-- ALEX TEMPLATE+--+-- This code is in the PUBLIC DOMAIN; you may copy it freely and use+-- it for any purpose whatsoever.++-- -----------------------------------------------------------------------------+-- INTERNALS and main scanner engine++{-# LINE 37 "templates/GenericTemplate.hs" #-}++{-# LINE 47 "templates/GenericTemplate.hs" #-}+++data AlexAddr = AlexA# Addr#++#if __GLASGOW_HASKELL__ < 503+uncheckedShiftL# = shiftL#+#endif++{-# INLINE alexIndexInt16OffAddr #-}+alexIndexInt16OffAddr (AlexA# arr) off =+#ifdef WORDS_BIGENDIAN+ narrow16Int# i+ where+ i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low)+ high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))+ low = int2Word# (ord# (indexCharOffAddr# arr off'))+ off' = off *# 2#+#else+ indexInt16OffAddr# arr off+#endif++++++{-# INLINE alexIndexInt32OffAddr #-}+alexIndexInt32OffAddr (AlexA# arr) off = +#ifdef WORDS_BIGENDIAN+ narrow32Int# i+ where+ !i = word2Int# ((b3 `uncheckedShiftL#` 24#) `or#`+ (b2 `uncheckedShiftL#` 16#) `or#`+ (b1 `uncheckedShiftL#` 8#) `or#` b0)+ !b3 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 3#)))+ !b2 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 2#)))+ !b1 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))+ !b0 = int2Word# (ord# (indexCharOffAddr# arr off'))+ !off' = off *# 4#+#else+ indexInt32OffAddr# arr off+#endif++++++#if __GLASGOW_HASKELL__ < 503+quickIndex arr i = arr ! i+#else+-- GHC >= 503, unsafeAt is available from Data.Array.Base.+quickIndex = unsafeAt+#endif+++++-- -----------------------------------------------------------------------------+-- Main lexing routines++data AlexReturn a+ = AlexEOF+ | AlexError !AlexInput+ | AlexSkip !AlexInput !Int+ | AlexToken !AlexInput !Int a++-- alexScan :: AlexInput -> StartCode -> AlexReturn a+alexScan input (I# (sc))+ = alexScanUser undefined input (I# (sc))++alexScanUser user input (I# (sc))+ = case alex_scan_tkn user input 0# input sc AlexNone of+ (AlexNone, input') ->+ case alexGetByte input of+ Nothing -> ++++ AlexEOF+ Just _ ->++++ AlexError input'++ (AlexLastSkip input'' len, _) ->++++ AlexSkip input'' len++ (AlexLastAcc k input''' len, _) ->++++ AlexToken input''' len k+++-- Push the input through the DFA, remembering the most recent accepting+-- state it encountered.++alex_scan_tkn user orig_input len input s last_acc =+ input `seq` -- strict in the input+ let + new_acc = (check_accs (alex_accept `quickIndex` (I# (s))))+ in+ new_acc `seq`+ case alexGetByte input of+ Nothing -> (new_acc, input)+ Just (c, new_input) -> ++++ let+ (base) = alexIndexInt32OffAddr alex_base s+ ((I# (ord_c))) = fromIntegral c+ (offset) = (base +# ord_c)+ (check) = alexIndexInt16OffAddr alex_check offset+ + (new_s) = if (offset >=# 0#) && (check ==# ord_c)+ then alexIndexInt16OffAddr alex_table offset+ else alexIndexInt16OffAddr alex_deflt s+ in+ case new_s of + -1# -> (new_acc, input)+ -- on an error, we want to keep the input *before* the+ -- character that failed, not after.+ _ -> alex_scan_tkn user orig_input (if c < 0x80 || c >= 0xC0 then (len +# 1#) else len)+ -- note that the length is increased ONLY if this is the 1st byte in a char encoding)+ new_input new_s new_acc++ where+ check_accs [] = last_acc+ check_accs (AlexAcc a : _) = AlexLastAcc a input (I# (len))+ check_accs (AlexAccSkip : _) = AlexLastSkip input (I# (len))+ check_accs (AlexAccPred a predx : rest)+ | predx user orig_input (I# (len)) input+ = AlexLastAcc a input (I# (len))+ check_accs (AlexAccSkipPred predx : rest)+ | predx user orig_input (I# (len)) input+ = AlexLastSkip input (I# (len))+ check_accs (_ : rest) = check_accs rest++data AlexLastAcc a+ = AlexNone+ | AlexLastAcc a !AlexInput !Int+ | AlexLastSkip !AlexInput !Int++instance Functor AlexLastAcc where+ fmap f AlexNone = AlexNone+ fmap f (AlexLastAcc x y z) = AlexLastAcc (f x) y z+ fmap f (AlexLastSkip x y) = AlexLastSkip x y++data AlexAcc a user+ = AlexAcc a+ | AlexAccSkip+ | AlexAccPred a (AlexAccPred user)+ | AlexAccSkipPred (AlexAccPred user)++type AlexAccPred user = user -> AlexInput -> Int -> AlexInput -> Bool++-- -----------------------------------------------------------------------------+-- Predicates on a rule++alexAndPred p1 p2 user in1 len in2+ = p1 user in1 len in2 && p2 user in1 len in2++--alexPrevCharIsPred :: Char -> AlexAccPred _ +alexPrevCharIs c _ input _ _ = c == alexInputPrevChar input++alexPrevCharMatches f _ input _ _ = f (alexInputPrevChar input)++--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _ +alexPrevCharIsOneOf arr _ input _ _ = arr ! alexInputPrevChar input++--alexRightContext :: Int -> AlexAccPred _+alexRightContext (I# (sc)) user _ _ input = + case alex_scan_tkn user input 0# input sc AlexNone of+ (AlexNone, _) -> False+ _ -> True+ -- TODO: there's no need to find the longest+ -- match when checking the right context, just+ -- the first match will do.++-- used by wrappers+iUnbox (I# (i)) = i
+ language-lua.cabal view
@@ -0,0 +1,37 @@+Name: language-lua+Description: Lua 5.2 lexer, parser and pretty-printer.+Version: 0.1+Synopsis: Lua parser and pretty-printer+Homepage: http://github.com/osa1/language-lua+Bug-reports: http://github.com/osa1/language-lua/issues+License: BSD3+License-file: LICENSE+Author: Ömer Sinan Ağacan+Maintainer: omeragacan@gmail.com+Category: Language+Build-type: Simple+Stability: Experimental+Cabal-version: >= 1.9.2++Extra-source-files:src/Text/PrettyPrint/LICENSE++Source-repository head+ type: git+ location: git://github.com/osa1/language-lua.git++Library+ Hs-source-dirs: src++ Exposed-modules: Language.Lua.Types,+ Language.Lua.Token,+ Language.Lua.Parser,+ Language.Lua.Lexer,+ Language.Lua.PrettyPrinter+ Text.Parsec.LTok++ Other-modules: Text.PrettyPrint.Leijen++ Build-depends: base >= 4.5 && < 4.6,+ mtl >= 2.0 && < 2.1,+ parsec >= 3.1.3 && < 3.2,+ array >= 0.4 && < 0.5
+ src/Language/Lua/Lexer.x view
@@ -0,0 +1,148 @@+-- TODO:+-- * Multi-line comments and strings++{+module Language.Lua.Lexer+ ( llex+ , LTok+ , AlexPosn(..)+ ) where++import Language.Lua.Token+}++%wrapper "posn"++$space = [ \ \t ] -- horizontal white space+$eol = \n -- end of line++$letter = [a-zA-Z] -- first letter of variables+$identletter = [a-zA-Z_0-9] -- letters for rest of variables++$digit = 0-9 -- decimal digits+$octdigit = 0-7 -- octal digits+$hexdigit = [0-9a-fA-F] -- hexadecimal digits++$instr = \0-\255 # [ \\ \" \n ] -- valid character in a string literal+$anyButNL = \0-\255 # \n++@sp = $space*++-- escape characters+@charescd = \\ ([ntvbrfaeE\\\?\"] | $octdigit{1,3} | x$hexdigit+ | X$hexdigit+)+@charescs = \\ ([ntvbrfaeE\\\?\'] | $octdigit{1,3} | x$hexdigit+ | X$hexdigit+)++@digits = $digit++@hexdigits = $hexdigit+++@mantpart = (@digits \. @digits) | @digits \. | \. @digits+@exppart = [eE][\+\-]? @digits++@hexprefix = 0x | 0X+@mantparthex = (@hexdigits \. @hexdigits) | @hexdigits \. | \. @hexdigits+@expparthex = [pP][\+\-]? @hexdigits++tokens :-++ $white+ ;+ "--" [^\n]* ;++ $letter $identletter* { ident }++ @digits { \posn s -> (LTokNum s, posn) }+ @digits @exppart { \posn s -> (LTokNum s, posn) }+ @mantpart @exppart? { \posn s -> (LTokNum s, posn) }+ @hexprefix @hexdigits { \posn s -> (LTokNum s, posn) }+ @hexprefix @hexdigits @expparthex { \posn s -> (LTokNum s, posn) }+ @hexprefix @mantparthex @expparthex? { \posn s -> (LTokNum s, posn) }++ \"($instr|@charescd)*\" { \posn s -> (LTokSLit (tail . init $ s), posn) }+ \'($instr|@charescs)*\' { \posn s -> (LTokSLit (tail . init $ s), posn) }++ "+" { \posn _ -> (LTokPlus, posn) }+ "-" { \posn _ -> (LTokMinus, posn) }+ "*" { \posn _ -> (LTokStar, posn) }+ "/" { \posn _ -> (LTokSlash, posn) }+ "%" { \posn _ -> (LTokPercent, posn) }+ "^" { \posn _ -> (LTokExp, posn) }+ "#" { \posn _ -> (LTokSh, posn) }+ "==" { \posn _ -> (LTokEqual, posn) }+ "~=" { \posn _ -> (LTokNotequal, posn) }+ "<=" { \posn _ -> (LTokLEq, posn) }+ ">=" { \posn _ -> (LTokGEq, posn) }+ "<" { \posn _ -> (LTokLT, posn) }+ ">" { \posn _ -> (LTokGT, posn) }+ "=" { \posn _ -> (LTokAssign, posn) }+ "(" { \posn _ -> (LTokLParen, posn) }+ ")" { \posn _ -> (LTokRParen, posn) }+ "{" { \posn _ -> (LTokLBrace, posn) }+ "}" { \posn _ -> (LTokRBrace, posn) }+ "[" { \posn _ -> (LTokLBracket, posn) }+ "]" { \posn _ -> (LTokRBracket, posn) }+ "::" { \posn _ -> (LTokDColon, posn) }+ ";" { \posn _ -> (LTokSemic, posn) }+ ":" { \posn _ -> (LTokColon, posn) }+ "," { \posn _ -> (LTokComma, posn) }+ "." { \posn _ -> (LTokDot, posn) }+ ".." { \posn _ -> (LTokDDot, posn) }+ "..." { \posn _ -> (LTokEllipsis, posn) }+++{++-- | Lua token with position information.+type LTok = (LToken, AlexPosn)+type AlexAction = AlexPosn -> String -> LTok++{-# INLINE ident #-}+ident :: AlexAction+ident posn "and" = (LTokAnd, posn)+ident posn "break" = (LTokBreak, posn)+ident posn "do" = (LTokDo, posn)+ident posn "else" = (LTokElse, posn)+ident posn "elseif" = (LTokElseIf, posn)+ident posn "end" = (LTokEnd, posn)+ident posn "false" = (LTokFalse, posn)+ident posn "for" = (LTokFor, posn)+ident posn "function" = (LTokFunction, posn)+ident posn "goto" = (LTokGoto, posn)+ident posn "if" = (LTokIf, posn)+ident posn "in" = (LTokIn, posn)+ident posn "local" = (LTokLocal, posn)+ident posn "nil" = (LTokNil, posn)+ident posn "not" = (LTokNot, posn)+ident posn "or" = (LTokOr, posn)+ident posn "repeat" = (LTokRepeat, posn)+ident posn "return" = (LTokReturn, posn)+ident posn "then" = (LTokThen, posn)+ident posn "true" = (LTokTrue, posn)+ident posn "until" = (LTokUntil, posn)+ident posn "while" = (LTokWhile, posn)+ident posn name = (LTokIdent name, posn)++--data AlexPosn = AlexPn !Int -- absolute character offset+-- !Int -- line number+-- !Int -- column number+--+--type AlexInput = (AlexPosn, -- current position,+-- Char, -- previous char+-- [Byte], -- rest of the bytes for the current char+-- String) -- current input string++alexScanTokens' :: String -> [LTok]+alexScanTokens' str = go (alexStartPos,'\n',[],str)+ where go inp@(pos,_,_,str) =+ case alexScan inp 0 of+ AlexEOF -> [(LTokEof, pos)]+ AlexError ((AlexPn _ line column),_,_,_) -> error $ "lexical error at " ++ (show line) ++ " line, " ++ (show column) ++ " column"+ AlexSkip inp' len -> go inp'+ AlexToken inp' len act -> act pos (take len str) : go inp'++-- | Lua lexer.+llex :: String -> [LTok]+llex = alexScanTokens'++main = do+ s <- getContents+ print (alexScanTokens s)+}
+ src/Language/Lua/Parser.hs view
@@ -0,0 +1,374 @@+{-# OPTIONS_GHC -Wall+ -fno-warn-hi-shadowing+ -fno-warn-name-shadowing+ -fno-warn-unused-do-bind #-}+module Language.Lua.Parser+ ( parseText+ , stat+ , exp+ , chunk+ ) where++import Prelude hiding (exp, LT, GT, EQ, repeat)++import Language.Lua.Lexer+import Language.Lua.Token+import Language.Lua.Types++import Text.Parsec hiding (string)+import Text.Parsec.LTok+import Text.Parsec.Expr+import Control.Applicative ((<*), (<$>), (<*>))+import Control.Monad (void, liftM)++-- | Runs Lua lexer before parsing.+parseText :: Parsec [LTok] () a -> String -> Either ParseError a+parseText p s = parse p "test" (llex s)++parens :: Monad m => ParsecT [LTok] u m a -> ParsecT [LTok] u m a+parens = between (tok LTokLParen) (tok LTokRParen)++brackets :: Monad m => ParsecT [LTok] u m a -> ParsecT [LTok] u m a+brackets = between (tok LTokLBracket) (tok LTokRBracket)++name :: Parser String+name = tokenValue <$> anyIdent++number :: Parser String+number = tokenValue <$> anyNum+++data PrimaryExp+ = PName Name+ | PParen Exp+ deriving (Show, Eq)++data SuffixedExp+ = SuffixedExp PrimaryExp [SuffixExp]+ deriving (Show, Eq)++data SuffixExp+ = SSelect Name+ | SSelectExp Exp+ | SSelectMethod Name FunArg+ | SFunCall FunArg+ deriving (Show, Eq)++primaryExp :: Parser PrimaryExp+primaryExp = (PName <$> name) <|> (liftM PParen $ parens exp)++suffixedExp :: Parser SuffixedExp+suffixedExp = SuffixedExp <$> primaryExp <*> many suffixExp++suffixExp :: Parser SuffixExp+suffixExp = selectName <|> selectExp <|> selectMethod <|> funarg+ where selectName = SSelect <$> (tok LTokDot >> name)+ selectExp = SSelectExp <$> brackets exp+ selectMethod = tok LTokColon >> (SSelectMethod <$> name <*> funArg)+ funarg = SFunCall <$> funArg++sexpToPexp :: SuffixedExp -> PrefixExp+sexpToPexp (SuffixedExp t r) = case r of+ [] -> t'+ (SSelect sname:xs) -> iter xs (PEVar (SelectName t' sname))+ (SSelectExp sexp:xs) -> iter xs (PEVar (Select t' sexp))+ (SSelectMethod mname args:xs) -> iter xs (PEFunCall (MethodCall t' mname args))+ (SFunCall args:xs) -> iter xs (PEFunCall (NormalFunCall t' args))++ where t' :: PrefixExp+ t' = case t of+ PName name -> PEVar (Name name)+ PParen exp -> Paren exp++ iter :: [SuffixExp] -> PrefixExp -> PrefixExp+ iter [] pe = pe+ iter (SSelect sname:xs) pe = iter xs (PEVar (SelectName pe sname))+ iter (SSelectExp sexp:xs) pe = iter xs (PEVar (Select pe sexp))+ iter (SSelectMethod mname args:xs) pe = iter xs (PEFunCall (MethodCall pe mname args))+ iter (SFunCall args:xs) pe = iter xs (PEFunCall (NormalFunCall pe args))++-- TODO: improve error messages.+sexpToVar :: SuffixedExp -> Parser Var+sexpToVar (SuffixedExp (PName name) []) = return (Name name)+sexpToVar (SuffixedExp _ []) = fail "syntax error"+sexpToVar sexp = case sexpToPexp sexp of+ PEVar var -> return var+ _ -> fail "syntax error"++sexpToFunCall :: SuffixedExp -> Parser FunCall+sexpToFunCall (SuffixedExp _ []) = fail "syntax error"+sexpToFunCall sexp = case sexpToPexp sexp of+ PEFunCall funcall -> return funcall+ _ -> fail "syntax error"++var :: Parser Var+var = suffixedExp >>= sexpToVar++funCall :: Parser FunCall+funCall = suffixedExp >>= sexpToFunCall++stringlit :: Parser String+stringlit = tokenValue <$> string++funArg :: Parser FunArg+funArg = tableArg <|> stringArg <|> parlist+ where tableArg = TableArg <$> table+ stringArg = StringArg <$> stringlit+ parlist = parens (do exps <- exp `sepBy` tok LTokComma+ return $ Args exps)++funBody :: Parser FunBody+funBody = do+ (params, vararg) <- parlist+ body <- block+ tok LTokEnd+ return $ FunBody params vararg body++ where parlist = parens $ do+ vars <- name `sepEndBy` tok LTokComma+ vararg <- optionMaybe (tok LTokEllipsis <|> tok LTokComma)+ return $ case vararg of+ Nothing -> (vars, False)+ Just LTokEllipsis -> (vars, True)+ _ -> (vars, False)++block :: Parser Block+block = do+ stats <- many stat+ ret <- optionMaybe retstat+ return $ Block stats ret++retstat :: Parser [Exp]+retstat = do+ tok LTokReturn+ exps <- exp `sepBy` tok LTokComma+ optional (tok LTokSemic)+ return exps++tableField :: Parser TableField+tableField = expField <|> namedField <|> field+ where expField :: Parser TableField+ expField = do+ e1 <- brackets exp+ tok LTokAssign+ e2 <- exp+ return $ ExpField e1 e2++ namedField :: Parser TableField+ namedField = do+ name' <- name+ tok LTokAssign+ val <- exp+ return $ NamedField name' val++ field :: Parser TableField+ field = Field <$> exp++table :: Parser Table+table = between (tok LTokLBrace)+ (tok LTokRBrace)+ (do fields <- tableField `sepEndBy` fieldSep+ return $ Table fields)+ where fieldSep = tok LTokComma <|> tok LTokSemic++-----------------------------------------------------------------------+---- Expressions++nilExp, boolExp, numberExp, stringExp, varargExp, fundefExp,+ prefixexpExp, tableconstExp, opExp, exp, exp' :: Parser Exp++nilExp = tok LTokNil >> return Nil++boolExp = (tok LTokTrue >> return (Bool True)) <|>+ (tok LTokFalse >> return (Bool False))++numberExp = Number <$> number++stringExp = String <$> stringlit++varargExp = tok LTokEllipsis >> return Vararg++fundefExp = do+ tok LTokFunction+ body <- funBody+ return $ EFunDef (FunDef body)++prefixexpExp = PrefixExp <$> (liftM sexpToPexp suffixedExp)++tableconstExp = TableConst <$> table++binary :: Monad m => LToken -> (a -> a -> a) -> Assoc -> Operator [LTok] u m a+binary op fun = Infix (tok op >> return fun)++prefix :: Monad m => LToken -> (a -> a) -> Operator [LTok] u m a+prefix op fun = Prefix (tok op >> return fun)++opTable :: Monad m => [[Operator [LTok] u m Exp]]+opTable = [ [ binary LTokExp (Binop Exp) AssocRight ]+ , [ prefix LTokNot (Unop Not)+ , prefix LTokSh (Unop Len)+ , prefix LTokMinus (Unop Neg)+ ]+ , [ binary LTokStar (Binop Mul) AssocLeft+ , binary LTokSlash (Binop Div) AssocLeft+ , binary LTokPercent (Binop Mod) AssocLeft+ ]+ , [ binary LTokPlus (Binop Add) AssocLeft+ , binary LTokMinus (Binop Sub) AssocLeft+ ]+ , [ binary LTokDDot (Binop Concat) AssocRight ]+ , [ binary LTokGT (Binop GT) AssocLeft+ , binary LTokLT (Binop LT) AssocLeft+ , binary LTokGEq (Binop GTE) AssocLeft+ , binary LTokLEq (Binop LTE) AssocLeft+ , binary LTokNotequal (Binop NEQ) AssocLeft+ , binary LTokEqual (Binop EQ) AssocLeft+ ]+ , [ binary LTokAnd (Binop And) AssocLeft ]+ , [ binary LTokOr (Binop Or) AssocLeft ]+ ]++opExp = buildExpressionParser opTable exp' <?> "opExp"++exp' = choice [ nilExp, boolExp, numberExp, stringExp, varargExp,+ fundefExp, prefixexpExp, tableconstExp ]++-- | Expression parser.+exp = choice [ opExp, nilExp, boolExp, numberExp, stringExp, varargExp,+ fundefExp, prefixexpExp, tableconstExp ]++-----------------------------------------------------------------------+---- Statements++assignStat, funCallStat, labelStat, breakStat, gotoStat,+ doStat, whileStat, repeatStat, ifStat, forRangeStat,+ forInStat, funAssignStat, localFunAssignStat, localAssignStat, stat :: Parser Stat++emptyStat :: Parser ()+emptyStat = void (tok LTokSemic)++assignStat = do+ vars <- var `sepBy` tok LTokComma+ tok LTokAssign+ exps <- exp `sepBy` tok LTokComma+ return $ Assign vars exps++funCallStat = FunCall <$> funCall++labelStat = Label <$> label+ where label = between (tok LTokDColon) (tok LTokDColon) name++breakStat = tok LTokBreak >> return Break++gotoStat = Goto <$> (tok LTokGoto >> name)++doStat = Do <$> between (tok LTokDo) (tok LTokEnd) block++whileStat =+ between (tok LTokWhile)+ (tok LTokEnd)+ (do cond <- exp+ tok LTokDo+ body <- block+ return $ While cond body)++repeatStat = do+ tok LTokRepeat+ body <- block+ tok LTokUntil+ cond <- exp+ return $ Repeat body cond++ifStat =+ between (tok LTokIf)+ (tok LTokEnd)+ (do f <- ifPart+ conds <- many elseifPart+ l <- optionMaybe elsePart+ return $ If (f:conds) l)++ where ifPart :: Parser (Exp, Block)+ ifPart = do+ cond <- exp+ tok LTokThen+ body <- block+ return (cond, body)++ elseifPart :: Parser (Exp, Block)+ elseifPart = do+ tok LTokElseIf+ cond <- exp+ tok LTokThen+ body <- block+ return (cond, body)++ elsePart :: Parser Block+ elsePart = tok LTokElse >> block++forRangeStat =+ between (tok LTokFor)+ (tok LTokEnd)+ (do name' <- name+ tok LTokAssign+ start <- exp+ tok LTokComma+ end <- exp+ range <- optionMaybe $ tok LTokComma >> exp+ tok LTokDo+ body <- block+ return $ ForRange name' start end range body)++forInStat =+ between (tok LTokFor)+ (tok LTokEnd)+ (do names <- name `sepBy` tok LTokComma+ tok LTokIn+ exps <- exp `sepBy` tok LTokComma+ tok LTokDo+ body <- block+ return $ ForIn names exps body)++funAssignStat = do+ tok LTokFunction+ name' <- funName+ body <- funBody+ return $ FunAssign name' body+ where funName :: Parser FunName+ funName = FunName <$> name+ <*> optionMaybe (tok LTokDot >> name)+ <*> many (tok LTokColon >> name)++localFunAssignStat = do+ tok LTokLocal+ tok LTokFunction+ name' <- name+ body <- funBody+ return $ LocalFunAssign name' body++localAssignStat = do+ tok LTokLocal+ names <- name `sepBy` tok LTokComma+ rest <- optionMaybe $ tok LTokAssign >> exp `sepBy` tok LTokComma+ return $ LocalAssign names rest++-- | Statement parser.+stat =+ choice [ try assignStat+ , try funCallStat+ , try labelStat+ , try breakStat+ , try gotoStat+ , try doStat+ , try whileStat+ , try repeatStat+ , try ifStat+ , try forRangeStat+ , try forInStat+ , try funAssignStat+ , try localFunAssignStat+ , try localAssignStat+ ]++-- | Lua file parser.+chunk :: Parser Block+chunk = block <* tok LTokEof
+ src/Language/Lua/PrettyPrinter.hs view
@@ -0,0 +1,181 @@+{-# OPTIONS_GHC -Wall+ -fno-warn-hi-shadowing+ -fno-warn-name-shadowing+ -fno-warn-unused-do-bind #-}+{-# LANGUAGE FlexibleInstances #-}++-- | Lua pretty-printer.+-- This is a work in progress.+module Language.Lua.PrettyPrinter (pprint, Printer(..), LPretty) where++import Prelude hiding (EQ, GT, LT)+import Text.PrettyPrint.Leijen hiding ((<$>))++import Language.Lua.Types++data Printer = Printer { ident :: Int }++intercalate :: Doc -> [Doc] -> Doc+intercalate s elems = sep (punctuate s elems)++infixr 5 <$>+(<$>) :: Doc -> Doc -> Doc+x <$> y | isEmpty y = x+ | otherwise = x <> line <> y++class LPretty a where+ pprint :: Printer -> a -> Doc++instance LPretty [Char] where+ pprint _ s = text s++instance LPretty Bool where+ pprint _ True = text "true"+ pprint _ False = text "false"++instance LPretty Exp where+ pprint _ Nil = text "nil"+ pprint p (Bool s) = pprint p s+ pprint _ (Number n) = text n+ pprint _ (String s) = dquotes (text s)+ pprint _ Vararg = text "..."+ pprint p (EFunDef f) = pprint p f+ pprint p (PrefixExp pe) = pprint p pe+ pprint p (TableConst t) = pprint p t+ pprint p (Binop op e1 e2) = pprint p e1 <+> pprint p op <+> pprint p e2+ pprint p (Unop op e) = pprint p op <> pprint p e++instance LPretty Var where+ pprint _ (Name n) = text n+ pprint p (Select pe e) = pprint p pe <> brackets (pprint p e)+ pprint p (SelectName pe name) = group (pprint p pe <$$> (char '.' <> pprint p name))++instance LPretty Binop where+ pprint _ Add = char '+'+ pprint _ Sub = char '-'+ pprint _ Mul = char '*'+ pprint _ Div = char '/'+ pprint _ Exp = char '^'+ pprint _ Mod = char '%'+ pprint _ Concat = text ".."+ pprint _ LT = char '<'+ pprint _ LTE = text "<="+ pprint _ GT = char '>'+ pprint _ GTE = text ">="+ pprint _ EQ = text "=="+ pprint _ NEQ = text "~="+ pprint _ And = text "and"+ pprint _ Or = text "or"++instance LPretty Unop where+ pprint _ Neg = char '-'+ pprint _ Not = text "not "+ pprint _ Len = char '#'++instance LPretty PrefixExp where+ pprint p (PEVar var) = pprint p var+ pprint p (PEFunCall funcall) = pprint p funcall+ pprint p (Paren e) = parens (pprint p e)++instance LPretty Table where+ pprint p (Table fields) = braces (nest 4 (cat (punctuate comma (map (pprint p) fields))))++instance LPretty TableField where+ pprint p (ExpField e1 e2) = brackets (pprint p e1) <+> equals <+> pprint p e2+ pprint p (NamedField name e) = pprint p name <+> equals <+> pprint p e+ pprint p (Field e) = pprint p e++instance LPretty Block where+ pprint p (Block stats ret)+ = case stats of+ [] -> ret'+ _ -> (foldr (<$>) empty (map (pprint p) stats)) <$> ret'+ where ret' = case ret of+ Nothing -> empty+ Just e -> nest 2 (text "return" </> (intercalate comma (map (pprint p) e)))++instance LPretty FunName where+ pprint p (FunName name s methods) = text name <> s' <> (intercalate colon (map (pprint p) methods))+ where s' = case s of+ Nothing -> empty+ Just s' -> char '.' <> text s'++instance LPretty FunDef where+ pprint p (FunDef body) = pprint p body++instance LPretty FunBody where+ pprint p funbody = pprintFunction p Nothing funbody++pprintFunction :: Printer -> Maybe Doc -> FunBody -> Doc+pprintFunction p funname (FunBody args vararg block)+ = group (nest 4 (funhead <$> funbody) <$> end)+ where funhead = case funname of+ Nothing -> nest 2 (text "function" </> args')+ Just n -> nest 2 (text "function" </> n </> args')+ args' = parens (align (cat (punctuate (comma <> space)+ (map (pprint p) (args ++ if vararg then ["..."] else [])))))+ funbody = pprint p block+ end = text "end"++instance LPretty FunCall where+ pprint p (NormalFunCall pe arg) = group (nest 4 (pprint p pe <$$> pprint p arg))+ pprint p (MethodCall pe method arg) = group (nest 4 (pprint p pe <$$> (colon <> text method) <$$> pprint p arg))++instance LPretty FunArg where+ pprint p (Args exps) = parens (nest 4 (cat (punctuate (comma <> space) (map (pprint p) exps))))+ pprint p (TableArg t) = pprint p t+ pprint _ (StringArg s) = dquotes (text s)++instance LPretty Stat where+ pprint p (Assign names vals)+ = (intercalate comma (map (pprint p) names))+ <+> equals+ <+> (intercalate comma (map (pprint p) vals))+ pprint p (FunCall funcall) = pprint p funcall+ pprint p (Label name) = text "::" <> text name <> text "::"+ pprint p Break = text "break"+ pprint p (Goto name) = text "goto" <+> text name+ pprint p (Do block) = group (nest 4 (text "do" <$> pprint p block) <$> text "end")+ pprint p (While guard e)+ = (nest 4 (text "while" <+> pprint p guard <+> text "do"+ </> indent 4 (pprint p e)))+ </> text "end"+ pprint p (Repeat block guard)+ = nest 4 (text "repeat" </> pprint p block) </> (nest 4 (text "until" </> pprint p guard))++ pprint p (If cases elsePart) = group (printIf cases elsePart)+ where printIf ((guard, block):xs) e+ = group (nest 4 (text "if" <+> pprint p guard <+> text "then"+ <$> pprint p block))+ <$> printIf' p xs e++ printIf' p [] Nothing = text "end"+ printIf' p [] (Just b) = group (nest 4 (text "else" </> pprint p b)+ <$> text "end")+ printIf' p ((guard, block):xs) e+ = group (nest 4 (text "elseif" <+> pprint p guard <+> text "then"+ <$> pprint p block))+ <$> printIf' p xs e++ pprint p (ForRange name e1 e2 e3 block)+ = text "for" <+> text name <> equals <> pprint p e1 <> comma <> pprint p e2 <> e3' <+> text "do"+ <$> indent 4 (pprint p block)+ <$> text "end"+ where e3' = case e3 of+ Nothing -> empty+ Just e -> comma <> pprint p e++ pprint p (ForIn names exps block)+ = text "for" <+> (intercalate comma (map (pprint p) names))+ <+> text "in" <+> (intercalate comma (map (pprint p) exps)) <+> text "do"+ <$> indent 4 (pprint p block)+ <$> text "end"++ pprint p (FunAssign name body) = pprintFunction p (Just (pprint p name)) body+ pprint p (LocalFunAssign name body) = text "local" <+> pprintFunction p (Just (pprint p name)) body+ pprint p (LocalAssign names exps)+ = text "local" <+> (intercalate comma (map (pprint p) names)) <+> equals <+> exps'+ where exps' = case exps of+ Nothing -> empty+ Just es -> intercalate comma (map (pprint p) es)+ pprint p EmptyStat = empty
+ src/Language/Lua/Token.hs view
@@ -0,0 +1,66 @@+module Language.Lua.Token (LToken(..), tokenValue) where++-- ^Lua tokens+data LToken = LTokPlus -- ^++ | LTokMinus -- ^\-+ | LTokStar -- ^\*+ | LTokSlash -- ^/+ | LTokPercent -- ^%+ | LTokExp -- ^^+ | LTokSh -- ^#+ | LTokEqual -- ^==+ | LTokNotequal -- ^~=+ | LTokLEq -- ^<=+ | LTokGEq -- ^\>=+ | LTokLT -- ^<+ | LTokGT -- ^\>+ | LTokAssign -- ^=+ | LTokLParen -- ^(+ | LTokRParen -- ^)+ | LTokLBrace -- ^{+ | LTokRBrace -- ^}+ | LTokLBracket -- ^\[+ | LTokRBracket -- ^]+ | LTokDColon -- ^::+ | LTokSemic -- ^;+ | LTokColon -- ^:+ | LTokComma -- ^,+ | LTokDot -- ^.+ | LTokDDot -- ^..+ | LTokEllipsis -- ^...++ | LTokAnd -- ^and+ | LTokBreak -- ^break+ | LTokDo -- ^do+ | LTokElse -- ^else+ | LTokElseIf -- ^elseif+ | LTokEnd -- ^end+ | LTokFalse -- ^false+ | LTokFor -- ^for+ | LTokFunction -- ^function+ | LTokGoto -- ^goto+ | LTokIf -- ^if+ | LTokIn -- ^in+ | LTokLocal -- ^local+ | LTokNil -- ^nil+ | LTokNot -- ^not+ | LTokOr -- ^or+ | LTokRepeat -- ^repeat+ | LTokReturn -- ^return+ | LTokThen -- ^then+ | LTokTrue -- ^true+ | LTokUntil -- ^until+ | LTokWhile -- ^while++ | LTokNum String -- ^number constant+ | LTokSLit String -- ^string constant+ | LTokIdent String -- ^identifier+ | LTokEof -- ^end of file+ deriving (Show, Eq)++-- | Partial function, returns value of `LTokNum`, `LTokSLit` and `LTokIdent`.+tokenValue :: LToken -> String+tokenValue (LTokNum n) = n+tokenValue (LTokSLit s) = s+tokenValue (LTokIdent i) = i+tokenValue tok = error ("trying to get value of " ++ show tok)
+ src/Language/Lua/Types.hs view
@@ -0,0 +1,88 @@+{-# OPTIONS_GHC -Wall #-}+-- | Lua 5.2 syntax tree, as specified in <http://www.lua.org/manual/5.2/manual.html#9>.+module Language.Lua.Types where++type Name = String++data Stat+ = Assign [Var] [Exp] -- ^var1, var2 .. = exp1, exp2 ..+ | FunCall FunCall -- ^function call+ | Label Name -- ^label for goto+ | Break -- ^break+ | Goto Name -- ^goto label+ | Do Block -- ^do .. end+ | While Exp Block -- ^while .. do .. end+ | Repeat Block Exp -- ^repeat .. until ..+ | If [(Exp, Block)] (Maybe Block) -- ^if .. then .. [elseif ..] [else ..] end+ | ForRange Name Exp Exp (Maybe Exp) Block -- ^for x=start, end [, step] do .. end+ | ForIn [Name] [Exp] Block -- ^for x in .. do .. end+ | FunAssign FunName FunBody -- ^function \<var\> (..) .. end+ | LocalFunAssign Name FunBody -- ^local function \<var\> (..) .. end+ | LocalAssign [Name] (Maybe [Exp]) -- ^local var1, var2 .. = exp1, exp2 ..+ | EmptyStat -- ^/;/+ deriving (Show, Eq)++data Exp+ = Nil+ | Bool Bool+ | Number String+ | String String+ | Vararg -- ^/.../+ | EFunDef FunDef -- ^/function (..) .. end/+ | PrefixExp PrefixExp+ | TableConst Table -- ^table constructor+ | Binop Binop Exp Exp -- ^binary operators, /+ - * ^ % .. < <= > >= == ~= and or/+ | Unop Unop Exp -- ^unary operators, /- not #/+ deriving (Show, Eq)++data Var+ = Name Name -- ^variable+ | Select PrefixExp Exp -- ^/table[exp]/+ | SelectName PrefixExp Name -- ^/table.variable/+ deriving (Show, Eq)++data Binop = Add | Sub | Mul | Div | Exp | Mod | Concat+ | LT | LTE | GT | GTE | EQ | NEQ | And | Or+ deriving (Show, Eq)++data Unop = Neg | Not | Len+ deriving (Show, Eq)++data PrefixExp+ = PEVar Var+ | PEFunCall FunCall+ | Paren Exp+ deriving (Show, Eq)++data Table = Table [TableField] -- ^list of table fields+ deriving (Show, Eq)++data TableField+ = ExpField Exp Exp -- ^/[exp] = exp/+ | NamedField Name Exp -- ^/name = exp/+ | Field Exp+ deriving (Show, Eq)++-- | A block is list of statements with optional return statement.+data Block = Block [Stat] (Maybe [Exp])+ deriving (Show, Eq)++data FunName = FunName Name (Maybe Name) [Name]+ deriving (Show, Eq)++data FunDef = FunDef FunBody+ deriving (Show, Eq)++data FunBody = FunBody [Name] Bool Block -- ^(args, vararg predicate, block)+ deriving (Show, Eq)++data FunCall+ = NormalFunCall PrefixExp FunArg -- ^/prefixexp ( funarg )/+ | MethodCall PrefixExp Name FunArg -- ^/prefixexp : name ( funarg )/+ deriving (Show, Eq)++data FunArg+ = Args [Exp] -- ^list of args+ | TableArg Table -- ^table constructor+ | StringArg String -- ^string+ deriving (Show, Eq)
+ src/Text/Parsec/LTok.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE FlexibleContexts, NoMonomorphismRestriction #-}+{-# OPTIONS_GHC -Wall #-}++-- | Lexer/Parsec interface+module Text.Parsec.LTok where++import Language.Lua.Lexer (LTok, AlexPosn(..))+import Language.Lua.Token++import Text.Parsec hiding (satisfy)++type Parser = Parsec [LTok] ()++-- | This parser succeeds whenever the given predicate returns true when called with+-- parsed `LTok`. Same as 'Text.Parsec.Char.satisfy'.+satisfy :: (Stream [LTok] m LTok) => (LTok -> Bool) -> ParsecT [LTok] u m LToken+satisfy f = tokenPrim show nextPos tokeq+ where nextPos :: SourcePos -> LTok -> [LTok] -> SourcePos+ nextPos pos _ ((_, (AlexPn _ l c)):_) = setSourceColumn (setSourceLine pos l) c+ nextPos pos _ [] = pos -- TODO: ??++ tokeq :: LTok -> Maybe LToken+ tokeq t = if f t then Just (fst t) else Nothing++-- | Parses given `LToken`.+tok :: (Stream [LTok] m LTok) => LToken -> ParsecT [LTok] u m LToken+tok t = satisfy (\(t', _) -> t' == t) <?> show t++-- | Parses a `LTokIdent`.+anyIdent :: Monad m => ParsecT [LTok] u m LToken+anyIdent = satisfy p <?> "ident"+ where p (t, _) = case t of LTokIdent _ -> True+ _ -> False++-- | Parses a `LTokNum`.+anyNum :: Monad m => ParsecT [LTok] u m LToken+anyNum = satisfy p <?> "number"+ where p (t, _) = case t of LTokNum _ -> True+ _ -> False++-- | Parses a `LTokSLit`.+string :: Monad m => ParsecT [LTok] u m LToken+string = satisfy p <?> "string"+ where p (t, _) = case t of LTokSLit _ -> True+ _ -> False
+ src/Text/PrettyPrint/LICENSE view
@@ -0,0 +1,25 @@+Copyright 2000, Daan Leijen. All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in+ the documentation and/or other materials provided with the+ distribution.++This software is provided by the copyright holders "as is" and any+express or implied warranties, including, but not limited to, the+implied warranties of merchantability and fitness for a particular+purpose are disclaimed. In no event shall the copyright holders be+liable for any direct, indirect, incidental, special, exemplary, or+consequential damages (including, but not limited to, procurement of+substitute goods or services; loss of use, data, or profits; or+business interruption) however caused and on any theory of liability,+whether in contract, strict liability, or tort (including negligence+or otherwise) arising in any way out of the use of this software, even+if advised of the possibility of such damage.
+ src/Text/PrettyPrint/Leijen.hs view
@@ -0,0 +1,964 @@+{-# OPTIONS_HADDOCK hide #-}+-----------------------------------------------------------------------------+-- |+-- Module : Text.PrettyPrint.Leijen+-- Copyright : Daan Leijen (c) 2000, http://www.cs.uu.nl/~daan+-- License : BSD-style (see the file LICENSE)+--+-- Maintainer : otakar.smrz cmu.edu+-- Stability : provisional+-- Portability : portable+--+-- Pretty print module based on Philip Wadler's \"prettier printer\"+--+-- @+-- \"A prettier printer\"+-- Draft paper, April 1997, revised March 1998.+-- <http://cm.bell-labs.com/cm/cs/who/wadler/papers/prettier/prettier.ps>+-- @+--+-- PPrint is an implementation of the pretty printing combinators+-- described by Philip Wadler (1997). In their bare essence, the+-- combinators of Wadler are not expressive enough to describe some+-- commonly occurring layouts. The PPrint library adds new primitives+-- to describe these layouts and works well in practice.+--+-- The library is based on a single way to concatenate documents,+-- which is associative and has both a left and right unit. This+-- simple design leads to an efficient and short implementation. The+-- simplicity is reflected in the predictable behaviour of the+-- combinators which make them easy to use in practice.+--+-- A thorough description of the primitive combinators and their+-- implementation can be found in Philip Wadler's paper+-- (1997). Additions and the main differences with his original paper+-- are:+--+-- * The nil document is called empty.+--+-- * The above combinator is called '<$>'. The operator '</>' is used+-- for soft line breaks.+--+-- * There are three new primitives: 'align', 'fill' and+-- 'fillBreak'. These are very useful in practice.+--+-- * Lots of other useful combinators, like 'fillSep' and 'list'.+--+-- * There are two renderers, 'renderPretty' for pretty printing and+-- 'renderCompact' for compact output. The pretty printing algorithm+-- also uses a ribbon-width now for even prettier output.+--+-- * There are two displayers, 'displayS' for strings and 'displayIO' for+-- file based output.+--+-- * There is a 'Pretty' class.+--+-- * The implementation uses optimised representations and strictness+-- annotations.+--+-- Full documentation available at <http://www.cs.uu.nl/~daan/download/pprint/pprint.html>.+-----------------------------------------------------------+module Text.PrettyPrint.Leijen (+ -- * Documents+ Doc, putDoc, hPutDoc,++ -- * Basic combinators+ empty, char, text, (<>), nest, line, linebreak, group, softline,+ softbreak,++ -- * Alignment+ --+ -- The combinators in this section can not be described by Wadler's+ -- original combinators. They align their output relative to the+ -- current output position - in contrast to @nest@ which always+ -- aligns to the current nesting level. This deprives these+ -- combinators from being \`optimal\'. In practice however they+ -- prove to be very useful. The combinators in this section should+ -- be used with care, since they are more expensive than the other+ -- combinators. For example, @align@ shouldn't be used to pretty+ -- print all top-level declarations of a language, but using @hang@+ -- for let expressions is fine.+ align, hang, indent, encloseSep, list, tupled, semiBraces,++ -- * Operators+ (<+>), (<$>), (</>), (<$$>), (<//>),++ -- * List combinators+ hsep, vsep, fillSep, sep, hcat, vcat, fillCat, cat, punctuate,++ -- * Fillers+ fill, fillBreak,++ -- * Bracketing combinators+ enclose, squotes, dquotes, parens, angles, braces, brackets,++ -- * Character documents+ lparen, rparen, langle, rangle, lbrace, rbrace, lbracket, rbracket,+ squote, dquote, semi, colon, comma, space, dot, backslash, equals,++ -- * Primitive type documents+ string, int, integer, float, double, rational,++ -- * Pretty class+ Pretty(..),++ -- * Rendering+ SimpleDoc(..), renderPretty, renderCompact, displayS, displayIO++ -- * Undocumented+ , bool++ , column, nesting, width++ , isEmpty+ ) where++import System.IO (Handle,hPutStr,hPutChar,stdout)++infixr 5 </>,<//>,<$>,<$$>+infixr 6 <>,<+>+++-----------------------------------------------------------+-- list, tupled and semiBraces pretty print a list of+-- documents either horizontally or vertically aligned.+-----------------------------------------------------------+++-- | The document @(list xs)@ comma separates the documents @xs@ and+-- encloses them in square brackets. The documents are rendered+-- horizontally if that fits the page. Otherwise they are aligned+-- vertically. All comma separators are put in front of the elements.+list :: [Doc] -> Doc+list = encloseSep lbracket rbracket comma++-- | The document @(tupled xs)@ comma separates the documents @xs@ and+-- encloses them in parenthesis. The documents are rendered+-- horizontally if that fits the page. Otherwise they are aligned+-- vertically. All comma separators are put in front of the elements.+tupled :: [Doc] -> Doc+tupled = encloseSep lparen rparen comma+++-- | The document @(semiBraces xs)@ separates the documents @xs@ with+-- semi colons and encloses them in braces. The documents are rendered+-- horizontally if that fits the page. Otherwise they are aligned+-- vertically. All semi colons are put in front of the elements.+semiBraces :: [Doc] -> Doc+semiBraces = encloseSep lbrace rbrace semi++-- | The document @(encloseSep l r sep xs)@ concatenates the documents+-- @xs@ separated by @sep@ and encloses the resulting document by @l@+-- and @r@. The documents are rendered horizontally if that fits the+-- page. Otherwise they are aligned vertically. All separators are put+-- in front of the elements. For example, the combinator 'list' can be+-- defined with @encloseSep@:+--+-- > list xs = encloseSep lbracket rbracket comma xs+-- > test = text "list" <+> (list (map int [10,200,3000]))+--+-- Which is layed out with a page width of 20 as:+--+-- @+-- list [10,200,3000]+-- @+--+-- But when the page width is 15, it is layed out as:+--+-- @+-- list [10+-- ,200+-- ,3000]+-- @+encloseSep :: Doc -> Doc -> Doc -> [Doc] -> Doc+encloseSep left right sep ds+ = case ds of+ [] -> left <> right+ [d] -> left <> d <> right+ _ -> align (cat (zipWith (<>) (left : repeat sep) ds) <> right)+++-----------------------------------------------------------+-- punctuate p [d1,d2,...,dn] => [d1 <> p,d2 <> p, ... ,dn]+-----------------------------------------------------------+++-- | @(punctuate p xs)@ concatenates all documents in @xs@ with+-- document @p@ except for the last document.+--+-- > someText = map text ["words","in","a","tuple"]+-- > test = parens (align (cat (punctuate comma someText)))+--+-- This is layed out on a page width of 20 as:+--+-- @+-- (words,in,a,tuple)+-- @+--+-- But when the page width is 15, it is layed out as:+--+-- @+-- (words,+-- in,+-- a,+-- tuple)+-- @+--+-- (If you want put the commas in front of their elements instead of+-- at the end, you should use 'tupled' or, in general, 'encloseSep'.)+punctuate :: Doc -> [Doc] -> [Doc]+punctuate p [] = []+punctuate p [d] = [d]+punctuate p (d:ds) = (d <> p) : punctuate p ds+++-----------------------------------------------------------+-- high-level combinators+-----------------------------------------------------------+++-- | The document @(sep xs)@ concatenates all documents @xs@ either+-- horizontally with @(\<+\>)@, if it fits the page, or vertically with+-- @(\<$\>)@.+--+-- > sep xs = group (vsep xs)+sep :: [Doc] -> Doc+sep = group . vsep++-- | The document @(fillSep xs)@ concatenates documents @xs@+-- horizontally with @(\<+\>)@ as long as its fits the page, than+-- inserts a @line@ and continues doing that for all documents in+-- @xs@.+--+-- > fillSep xs = foldr (\<\/\>) empty xs+fillSep :: [Doc] -> Doc+fillSep = fold (</>)++-- | The document @(hsep xs)@ concatenates all documents @xs@+-- horizontally with @(\<+\>)@.+hsep :: [Doc] -> Doc+hsep = fold (<+>)+++-- | The document @(vsep xs)@ concatenates all documents @xs@+-- vertically with @(\<$\>)@. If a 'group' undoes the line breaks+-- inserted by @vsep@, all documents are separated with a space.+--+-- > someText = map text (words ("text to lay out"))+-- >+-- > test = text "some" <+> vsep someText+--+-- This is layed out as:+--+-- @+-- some text+-- to+-- lay+-- out+-- @+--+-- The 'align' combinator can be used to align the documents under+-- their first element+--+-- > test = text "some" <+> align (vsep someText)+--+-- Which is printed as:+--+-- @+-- some text+-- to+-- lay+-- out+-- @+vsep :: [Doc] -> Doc+vsep = fold (<$>)++-- | The document @(cat xs)@ concatenates all documents @xs@ either+-- horizontally with @(\<\>)@, if it fits the page, or vertically with+-- @(\<$$\>)@.+--+-- > cat xs = group (vcat xs)+cat :: [Doc] -> Doc+cat = group . vcat++-- | The document @(fillCat xs)@ concatenates documents @xs@+-- horizontally with @(\<\>)@ as long as its fits the page, than inserts+-- a @linebreak@ and continues doing that for all documents in @xs@.+--+-- > fillCat xs = foldr (\<\/\/\>) empty xs+fillCat :: [Doc] -> Doc+fillCat = fold (<//>)++-- | The document @(hcat xs)@ concatenates all documents @xs@+-- horizontally with @(\<\>)@.+hcat :: [Doc] -> Doc+hcat = fold (<>)++-- | The document @(vcat xs)@ concatenates all documents @xs@+-- vertically with @(\<$$\>)@. If a 'group' undoes the line breaks+-- inserted by @vcat@, all documents are directly concatenated.+vcat :: [Doc] -> Doc+vcat = fold (<$$>)++fold f [] = empty+fold f ds = foldr1 f ds++-- | The document @(x \<\> y)@ concatenates document @x@ and document+-- @y@. It is an associative operation having 'empty' as a left and+-- right unit. (infixr 6)+(<>) :: Doc -> Doc -> Doc+x <> y = x `beside` y++-- | The document @(x \<+\> y)@ concatenates document @x@ and @y@ with a+-- @space@ in between. (infixr 6)+(<+>) :: Doc -> Doc -> Doc+x <+> y = x <> space <> y++-- | The document @(x \<\/\> y)@ concatenates document @x@ and @y@ with a+-- 'softline' in between. This effectively puts @x@ and @y@ either+-- next to each other (with a @space@ in between) or underneath each+-- other. (infixr 5)+(</>) :: Doc -> Doc -> Doc+x </> y = x <> softline <> y++-- | The document @(x \<\/\/\> y)@ concatenates document @x@ and @y@ with+-- a 'softbreak' in between. This effectively puts @x@ and @y@ either+-- right next to each other or underneath each other. (infixr 5)+(<//>) :: Doc -> Doc -> Doc+x <//> y = x <> softbreak <> y++-- | The document @(x \<$\> y)@ concatenates document @x@ and @y@ with a+-- 'line' in between. (infixr 5)+(<$>) :: Doc -> Doc -> Doc+x <$> y = x <> line <> y++-- | The document @(x \<$$\> y)@ concatenates document @x@ and @y@ with+-- a @linebreak@ in between. (infixr 5)+(<$$>) :: Doc -> Doc -> Doc+x <$$> y = x <> linebreak <> y++-- | The document @softline@ behaves like 'space' if the resulting+-- output fits the page, otherwise it behaves like 'line'.+--+-- > softline = group line+softline :: Doc+softline = group line++-- | The document @softbreak@ behaves like 'empty' if the resulting+-- output fits the page, otherwise it behaves like 'line'.+--+-- > softbreak = group linebreak+softbreak :: Doc+softbreak = group linebreak++-- | Document @(squotes x)@ encloses document @x@ with single quotes+-- \"'\".+squotes :: Doc -> Doc+squotes = enclose squote squote++-- | Document @(dquotes x)@ encloses document @x@ with double quotes+-- '\"'.+dquotes :: Doc -> Doc+dquotes = enclose dquote dquote++-- | Document @(braces x)@ encloses document @x@ in braces, \"{\" and+-- \"}\".+braces :: Doc -> Doc+braces = enclose lbrace rbrace++-- | Document @(parens x)@ encloses document @x@ in parenthesis, \"(\"+-- and \")\".+parens :: Doc -> Doc+parens = enclose lparen rparen++-- | Document @(angles x)@ encloses document @x@ in angles, \"\<\" and+-- \"\>\".+angles :: Doc -> Doc+angles = enclose langle rangle++-- | Document @(brackets x)@ encloses document @x@ in square brackets,+-- \"[\" and \"]\".+brackets :: Doc -> Doc+brackets = enclose lbracket rbracket++-- | The document @(enclose l r x)@ encloses document @x@ between+-- documents @l@ and @r@ using @(\<\>)@.+--+-- > enclose l r x = l <> x <> r+enclose :: Doc -> Doc -> Doc -> Doc+enclose l r x = l <> x <> r++-- | The document @lparen@ contains a left parenthesis, \"(\".+lparen :: Doc+lparen = char '('+-- | The document @rparen@ contains a right parenthesis, \")\".+rparen :: Doc+rparen = char ')'+-- | The document @langle@ contains a left angle, \"\<\".+langle :: Doc+langle = char '<'+-- | The document @rangle@ contains a right angle, \">\".+rangle :: Doc+rangle = char '>'+-- | The document @lbrace@ contains a left brace, \"{\".+lbrace :: Doc+lbrace = char '{'+-- | The document @rbrace@ contains a right brace, \"}\".+rbrace :: Doc+rbrace = char '}'+-- | The document @lbracket@ contains a left square bracket, \"[\".+lbracket :: Doc+lbracket = char '['+-- | The document @rbracket@ contains a right square bracket, \"]\".+rbracket :: Doc+rbracket = char ']'+++-- | The document @squote@ contains a single quote, \"'\".+squote :: Doc+squote = char '\''+-- | The document @dquote@ contains a double quote, '\"'.+dquote :: Doc+dquote = char '"'+-- | The document @semi@ contains a semi colon, \";\".+semi :: Doc+semi = char ';'+-- | The document @colon@ contains a colon, \":\".+colon :: Doc+colon = char ':'+-- | The document @comma@ contains a comma, \",\".+comma :: Doc+comma = char ','+-- | The document @space@ contains a single space, \" \".+--+-- > x <+> y = x <> space <> y+space :: Doc+space = char ' '+-- | The document @dot@ contains a single dot, \".\".+dot :: Doc+dot = char '.'+-- | The document @backslash@ contains a back slash, \"\\\".+backslash :: Doc+backslash = char '\\'+-- | The document @equals@ contains an equal sign, \"=\".+equals :: Doc+equals = char '='+++-----------------------------------------------------------+-- Combinators for prelude types+-----------------------------------------------------------++-- string is like "text" but replaces '\n' by "line"++-- | The document @(string s)@ concatenates all characters in @s@+-- using @line@ for newline characters and @char@ for all other+-- characters. It is used instead of 'text' whenever the text contains+-- newline characters.+string :: String -> Doc+string "" = empty+string ('\n':s) = line <> string s+string s = case (span (/='\n') s) of+ (xs,ys) -> text xs <> string ys++bool :: Bool -> Doc+bool b = text (show b)++-- | The document @(int i)@ shows the literal integer @i@ using+-- 'text'.+int :: Int -> Doc+int i = text (show i)++-- | The document @(integer i)@ shows the literal integer @i@ using+-- 'text'.+integer :: Integer -> Doc+integer i = text (show i)++-- | The document @(float f)@ shows the literal float @f@ using+-- 'text'.+float :: Float -> Doc+float f = text (show f)++-- | The document @(double d)@ shows the literal double @d@ using+-- 'text'.+double :: Double -> Doc+double d = text (show d)++-- | The document @(rational r)@ shows the literal rational @r@ using+-- 'text'.+rational :: Rational -> Doc+rational r = text (show r)+++-----------------------------------------------------------+-- overloading "pretty"+-----------------------------------------------------------++-- | The member @prettyList@ is only used to define the @instance Pretty+-- a => Pretty [a]@. In normal circumstances only the @pretty@ function+-- is used.+class Pretty a where+ pretty :: a -> Doc+ prettyList :: [a] -> Doc+ prettyList = list . map pretty++instance Pretty a => Pretty [a] where+ pretty = prettyList++instance Pretty Doc where+ pretty = id++instance Pretty () where+ pretty () = text "()"++instance Pretty Bool where+ pretty b = bool b++instance Pretty Char where+ pretty c = char c+ prettyList s = string s++instance Pretty Int where+ pretty i = int i++instance Pretty Integer where+ pretty i = integer i++instance Pretty Float where+ pretty f = float f++instance Pretty Double where+ pretty d = double d+++--instance Pretty Rational where+-- pretty r = rational r++instance (Pretty a,Pretty b) => Pretty (a,b) where+ pretty (x,y) = tupled [pretty x, pretty y]++instance (Pretty a,Pretty b,Pretty c) => Pretty (a,b,c) where+ pretty (x,y,z)= tupled [pretty x, pretty y, pretty z]++instance Pretty a => Pretty (Maybe a) where+ pretty Nothing = empty+ pretty (Just x) = pretty x++++-----------------------------------------------------------+-- semi primitive: fill and fillBreak+-----------------------------------------------------------++-- | The document @(fillBreak i x)@ first renders document @x@. It+-- than appends @space@s until the width is equal to @i@. If the+-- width of @x@ is already larger than @i@, the nesting level is+-- increased by @i@ and a @line@ is appended. When we redefine @ptype@+-- in the previous example to use @fillBreak@, we get a useful+-- variation of the previous output:+--+-- > ptype (name,tp)+-- > = fillBreak 6 (text name) <+> text "::" <+> text tp+--+-- The output will now be:+--+-- @+-- let empty :: Doc+-- nest :: Int -> Doc -> Doc+-- linebreak+-- :: Doc+-- @+fillBreak :: Int -> Doc -> Doc+fillBreak f x = width x (\w ->+ if (w > f) then nest f linebreak+ else text (spaces (f - w)))+++-- | The document @(fill i x)@ renders document @x@. It than appends+-- @space@s until the width is equal to @i@. If the width of @x@ is+-- already larger, nothing is appended. This combinator is quite+-- useful in practice to output a list of bindings. The following+-- example demonstrates this.+--+-- > types = [("empty","Doc")+-- > ,("nest","Int -> Doc -> Doc")+-- > ,("linebreak","Doc")]+-- >+-- > ptype (name,tp)+-- > = fill 6 (text name) <+> text "::" <+> text tp+-- >+-- > test = text "let" <+> align (vcat (map ptype types))+--+-- Which is layed out as:+--+-- @+-- let empty :: Doc+-- nest :: Int -> Doc -> Doc+-- linebreak :: Doc+-- @+fill :: Int -> Doc -> Doc+fill f d = width d (\w ->+ if (w >= f) then empty+ else text (spaces (f - w)))++width :: Doc -> (Int -> Doc) -> Doc+width d f = column (\k1 -> d <> column (\k2 -> f (k2 - k1)))+++-----------------------------------------------------------+-- semi primitive: Alignment and indentation+-----------------------------------------------------------++-- | The document @(indent i x)@ indents document @x@ with @i@ spaces.+--+-- > test = indent 4 (fillSep (map text+-- > (words "the indent combinator indents these words !")))+--+-- Which lays out with a page width of 20 as:+--+-- @+-- the indent+-- combinator+-- indents these+-- words !+-- @+indent :: Int -> Doc -> Doc+indent i d = hang i (text (spaces i) <> d)++-- | The hang combinator implements hanging indentation. The document+-- @(hang i x)@ renders document @x@ with a nesting level set to the+-- current column plus @i@. The following example uses hanging+-- indentation for some text:+--+-- > test = hang 4 (fillSep (map text+-- > (words "the hang combinator indents these words !")))+--+-- Which lays out on a page with a width of 20 characters as:+--+-- @+-- the hang combinator+-- indents these+-- words !+-- @+--+-- The @hang@ combinator is implemented as:+--+-- > hang i x = align (nest i x)+hang :: Int -> Doc -> Doc+hang i d = align (nest i d)++-- | The document @(align x)@ renders document @x@ with the nesting+-- level set to the current column. It is used for example to+-- implement 'hang'.+--+-- As an example, we will put a document right above another one,+-- regardless of the current nesting level:+--+-- > x $$ y = align (x <$> y)+--+-- > test = text "hi" <+> (text "nice" $$ text "world")+--+-- which will be layed out as:+--+-- @+-- hi nice+-- world+-- @+align :: Doc -> Doc+align d = column (\k ->+ nesting (\i -> nest (k - i) d)) --nesting might be negative :-)++++-----------------------------------------------------------+-- Primitives+-----------------------------------------------------------++-- | The abstract data type @Doc@ represents pretty documents.+--+-- @Doc@ is an instance of the 'Show' class. @(show doc)@ pretty+-- prints document @doc@ with a page width of 100 characters and a+-- ribbon width of 40 characters.+--+-- > show (text "hello" <$> text "world")+--+-- Which would return the string \"hello\\nworld\", i.e.+--+-- @+-- hello+-- world+-- @+data Doc = Empty+ | Char Char -- invariant: char is not '\n'+ | Text !Int String -- invariant: text doesn't contain '\n'+ | Line !Bool -- True <=> when undone by group, do not insert a space+ | Cat Doc Doc+ | Nest !Int Doc+ | Union Doc Doc -- invariant: first lines of first doc longer than the first lines of the second doc+ | Column (Int -> Doc)+ | Nesting (Int -> Doc)++isEmpty :: Doc -> Bool+isEmpty Empty = True+isEmpty _ = False++-- | The data type @SimpleDoc@ represents rendered documents and is+-- used by the display functions.+--+-- The @Int@ in @SText@ contains the length of the string. The @Int@+-- in @SLine@ contains the indentation for that line. The library+-- provides two default display functions 'displayS' and+-- 'displayIO'. You can provide your own display function by writing a+-- function from a @SimpleDoc@ to your own output format.+data SimpleDoc = SEmpty+ | SChar Char SimpleDoc+ | SText !Int String SimpleDoc+ | SLine !Int SimpleDoc+++-- | The empty document is, indeed, empty. Although @empty@ has no+-- content, it does have a \'height\' of 1 and behaves exactly like+-- @(text \"\")@ (and is therefore not a unit of @\<$\>@).+empty :: Doc+empty = Empty++-- | The document @(char c)@ contains the literal character @c@. The+-- character shouldn't be a newline (@'\n'@), the function 'line'+-- should be used for line breaks.+char :: Char -> Doc+char '\n' = line+char c = Char c++-- | The document @(text s)@ contains the literal string @s@. The+-- string shouldn't contain any newline (@'\n'@) characters. If the+-- string contains newline characters, the function 'string' should be+-- used.+text :: String -> Doc+text "" = Empty+text s = Text (length s) s++-- | The @line@ document advances to the next line and indents to the+-- current nesting level. Document @line@ behaves like @(text \" \")@+-- if the line break is undone by 'group'.+line :: Doc+line = Line False++-- | The @linebreak@ document advances to the next line and indents to+-- the current nesting level. Document @linebreak@ behaves like+-- 'empty' if the line break is undone by 'group'.+linebreak :: Doc+linebreak = Line True++beside x y = Cat x y++-- | The document @(nest i x)@ renders document @x@ with the current+-- indentation level increased by i (See also 'hang', 'align' and+-- 'indent').+--+-- > nest 2 (text "hello" <$> text "world") <$> text "!"+--+-- outputs as:+--+-- @+-- hello+-- world+-- !+-- @+nest :: Int -> Doc -> Doc+nest i x = Nest i x++column, nesting :: (Int -> Doc) -> Doc+column f = Column f+nesting f = Nesting f++-- | The @group@ combinator is used to specify alternative+-- layouts. The document @(group x)@ undoes all line breaks in+-- document @x@. The resulting line is added to the current line if+-- that fits the page. Otherwise, the document @x@ is rendered without+-- any changes.+group :: Doc -> Doc+group x = Union (flatten x) x++flatten :: Doc -> Doc+flatten (Cat x y) = Cat (flatten x) (flatten y)+flatten (Nest i x) = Nest i (flatten x)+flatten (Line break) = if break then Empty else Text 1 " "+flatten (Union x y) = flatten x+flatten (Column f) = Column (flatten . f)+flatten (Nesting f) = Nesting (flatten . f)+flatten other = other --Empty,Char,Text++++-----------------------------------------------------------+-- Renderers+-----------------------------------------------------------++-----------------------------------------------------------+-- renderPretty: the default pretty printing algorithm+-----------------------------------------------------------++-- list of indentation/document pairs; saves an indirection over [(Int,Doc)]+data Docs = Nil+ | Cons !Int Doc Docs+++-- | This is the default pretty printer which is used by 'show',+-- 'putDoc' and 'hPutDoc'. @(renderPretty ribbonfrac width x)@ renders+-- document @x@ with a page width of @width@ and a ribbon width of+-- @(ribbonfrac * width)@ characters. The ribbon width is the maximal+-- amount of non-indentation characters on a line. The parameter+-- @ribbonfrac@ should be between @0.0@ and @1.0@. If it is lower or+-- higher, the ribbon width will be 0 or @width@ respectively.+renderPretty :: Float -> Int -> Doc -> SimpleDoc+renderPretty rfrac w x+ = best 0 0 (Cons 0 x Nil)+ where+ -- r :: the ribbon width in characters+ r = max 0 (min w (round (fromIntegral w * rfrac)))++ -- best :: n = indentation of current line+ -- k = current column+ -- (ie. (k >= n) && (k - n == count of inserted characters)+ best n k Nil = SEmpty+ best n k (Cons i d ds)+ = case d of+ Empty -> best n k ds+ Char c -> let k' = k+1 in seq k' (SChar c (best n k' ds))+ Text l s -> let k' = k+l in seq k' (SText l s (best n k' ds))+ Line _ -> SLine i (best i i ds)+ Cat x y -> best n k (Cons i x (Cons i y ds))+ Nest j x -> let i' = i+j in seq i' (best n k (Cons i' x ds))+ Union x y -> nicest n k (best n k (Cons i x ds))+ (best n k (Cons i y ds))++ Column f -> best n k (Cons i (f k) ds)+ Nesting f -> best n k (Cons i (f i) ds)++ --nicest :: r = ribbon width, w = page width,+ -- n = indentation of current line, k = current column+ -- x and y, the (simple) documents to chose from.+ -- precondition: first lines of x are longer than the first lines of y.+ nicest n k x y | fits width x = x+ | otherwise = y+ where+ width = min (w - k) (r - k + n)+++fits w x | w < 0 = False+fits w SEmpty = True+fits w (SChar c x) = fits (w - 1) x+fits w (SText l s x) = fits (w - l) x+fits w (SLine i x) = True+++-----------------------------------------------------------+-- renderCompact: renders documents without indentation+-- fast and fewer characters output, good for machines+-----------------------------------------------------------+++-- | @(renderCompact x)@ renders document @x@ without adding any+-- indentation. Since no \'pretty\' printing is involved, this+-- renderer is very fast. The resulting output contains fewer+-- characters than a pretty printed version and can be used for output+-- that is read by other programs.+renderCompact :: Doc -> SimpleDoc+renderCompact x+ = scan 0 [x]+ where+ scan k [] = SEmpty+ scan k (d:ds) = case d of+ Empty -> scan k ds+ Char c -> let k' = k+1 in seq k' (SChar c (scan k' ds))+ Text l s -> let k' = k+l in seq k' (SText l s (scan k' ds))+ Line _ -> SLine 0 (scan 0 ds)+ Cat x y -> scan k (x:y:ds)+ Nest j x -> scan k (x:ds)+ Union x y -> scan k (y:ds)+ Column f -> scan k (f k:ds)+ Nesting f -> scan k (f 0:ds)++++-----------------------------------------------------------+-- Displayers: displayS and displayIO+-----------------------------------------------------------+++-- | @(displayS simpleDoc)@ takes the output @simpleDoc@ from a+-- rendering function and transforms it to a 'ShowS' type (for use in+-- the 'Show' class).+--+-- > showWidth :: Int -> Doc -> String+-- > showWidth w x = displayS (renderPretty 0.4 w x) ""+displayS :: SimpleDoc -> ShowS+displayS SEmpty = id+displayS (SChar c x) = showChar c . displayS x+displayS (SText l s x) = showString s . displayS x+displayS (SLine i x) = showString ('\n':indentation i) . displayS x+++-- | @(displayIO handle simpleDoc)@ writes @simpleDoc@ to the file+-- handle @handle@. This function is used for example by 'hPutDoc':+--+-- > hPutDoc handle doc = displayIO handle (renderPretty 0.4 100 doc)+displayIO :: Handle -> SimpleDoc -> IO ()+displayIO handle simpleDoc+ = display simpleDoc+ where+ display SEmpty = return ()+ display (SChar c x) = do{ hPutChar handle c; display x}+ display (SText l s x) = do{ hPutStr handle s; display x}+ display (SLine i x) = do{ hPutStr handle ('\n':indentation i); display x}+++-----------------------------------------------------------+-- default pretty printers: show, putDoc and hPutDoc+-----------------------------------------------------------+instance Show Doc where+ showsPrec d doc = displayS (renderPretty 0.4 80 doc)++-- | The action @(putDoc doc)@ pretty prints document @doc@ to the+-- standard output, with a page width of 100 characters and a ribbon+-- width of 40 characters.+--+-- > main :: IO ()+-- > main = do{ putDoc (text "hello" <+> text "world") }+--+-- Which would output+--+-- @+-- hello world+-- @+putDoc :: Doc -> IO ()+putDoc doc = hPutDoc stdout doc++-- | @(hPutDoc handle doc)@ pretty prints document @doc@ to the file+-- handle @handle@ with a page width of 100 characters and a ribbon+-- width of 40 characters.+--+-- > main = do{ handle <- openFile "MyFile" WriteMode+-- > ; hPutDoc handle (vcat (map text+-- > ["vertical","text"]))+-- > ; hClose handle+-- > }+hPutDoc :: Handle -> Doc -> IO ()+hPutDoc handle doc = displayIO handle (renderPretty 0.4 80 doc)++++-----------------------------------------------------------+-- insert spaces+-- "indentation" used to insert tabs but tabs seem to cause+-- more trouble than they solve :-)+-----------------------------------------------------------+spaces n | n <= 0 = ""+ | otherwise = replicate n ' '++indentation n = spaces n++--indentation n | n >= 8 = '\t' : indentation (n-8)+-- | otherwise = spaces n++-- LocalWords: PPrint combinators Wadler Wadler's encloseSep