tools/PascalParser.hs
changeset 8887 539380a498e4
parent 8792 af4ab297b2b7
parent 8884 08fe08651130
child 8889 74abe69d8569
equal deleted inserted replaced
8792:af4ab297b2b7 8887:539380a498e4
     1 module PascalParser where
       
     2 
       
     3 import Text.Parsec
       
     4 import Text.Parsec.Char
       
     5 import Text.Parsec.Token
       
     6 import Text.Parsec.Language
       
     7 import Text.Parsec.Expr
       
     8 import Text.Parsec.Prim
       
     9 import Text.Parsec.Combinator
       
    10 import Text.Parsec.String
       
    11 import Control.Monad
       
    12 import Data.Maybe
       
    13 import Data.Char
       
    14 
       
    15 import PascalBasics
       
    16 import PascalUnitSyntaxTree
       
    17 
       
    18 knownTypes = ["shortstring", "ansistring", "char", "byte"]
       
    19 
       
    20 pascalUnit = do
       
    21     comments
       
    22     u <- choice [program, unit, systemUnit, redoUnit]
       
    23     comments
       
    24     return u
       
    25 
       
    26 iD = do
       
    27     i <- liftM (flip Identifier BTUnknown) (identifier pas)
       
    28     comments
       
    29     return i
       
    30 
       
    31 unit = do
       
    32     string "unit" >> comments
       
    33     name <- iD
       
    34     semi pas
       
    35     comments
       
    36     int <- interface
       
    37     impl <- implementation
       
    38     comments
       
    39     return $ Unit name int impl Nothing Nothing
       
    40 
       
    41 
       
    42 reference = buildExpressionParser table term <?> "reference"
       
    43     where
       
    44     term = comments >> choice [
       
    45         parens pas (liftM RefExpression expression >>= postfixes) >>= postfixes
       
    46         , try $ typeCast >>= postfixes
       
    47         , char '@' >> liftM Address reference >>= postfixes
       
    48         , liftM SimpleReference iD >>= postfixes
       
    49         ] <?> "simple reference"
       
    50 
       
    51     table = [
       
    52         ]
       
    53 
       
    54     postfixes r = many postfix >>= return . foldl (flip ($)) r
       
    55     postfix = choice [
       
    56             parens pas (option [] parameters) >>= return . FunCall
       
    57           , char '^' >> return Dereference
       
    58           , (brackets pas) (commaSep1 pas $ expression) >>= return . ArrayElement
       
    59           , (char '.' >> notFollowedBy (char '.')) >> liftM (flip RecordField) reference
       
    60         ]
       
    61 
       
    62     typeCast = do
       
    63         t <- choice $ map (\s -> try $ caseInsensitiveString s >>= \i -> notFollowedBy alphaNum >> return i) knownTypes
       
    64         e <- parens pas expression
       
    65         comments
       
    66         return $ TypeCast (Identifier t BTUnknown) e
       
    67 
       
    68 varsDecl1 = varsParser sepEndBy1
       
    69 varsDecl = varsParser sepEndBy
       
    70 varsParser m endsWithSemi = do
       
    71     vs <- m (aVarDecl endsWithSemi) (semi pas)
       
    72     return vs
       
    73 
       
    74 aVarDecl endsWithSemi = do
       
    75     isVar <- liftM (== Just "var") $
       
    76         if not endsWithSemi then
       
    77             optionMaybe $ choice [
       
    78                 try $ string "var"
       
    79                 , try $ string "const"
       
    80                 , try $ string "out"
       
    81                 ]
       
    82             else
       
    83                 return Nothing
       
    84     comments
       
    85     ids <- do
       
    86         i <- (commaSep1 pas) $ (try iD <?> "variable declaration")
       
    87         char ':'
       
    88         return i
       
    89     comments
       
    90     t <- typeDecl <?> "variable type declaration"
       
    91     comments
       
    92     init <- option Nothing $ do
       
    93         char '='
       
    94         comments
       
    95         e <- initExpression
       
    96         comments
       
    97         return (Just e)
       
    98     return $ VarDeclaration isVar False (ids, t) init
       
    99 
       
   100 
       
   101 constsDecl = do
       
   102     vs <- many1 (try (aConstDecl >>= \i -> semi pas >> return i) >>= \i -> comments >> return i)
       
   103     comments
       
   104     return vs
       
   105     where
       
   106     aConstDecl = do
       
   107         comments
       
   108         i <- iD
       
   109         t <- optionMaybe $ do
       
   110             char ':'
       
   111             comments
       
   112             t <- typeDecl
       
   113             comments
       
   114             return t
       
   115         char '='
       
   116         comments
       
   117         e <- initExpression
       
   118         comments
       
   119         return $ VarDeclaration False (isNothing t) ([i], fromMaybe (DeriveType e) t) (Just e)
       
   120 
       
   121 typeDecl = choice [
       
   122     char '^' >> typeDecl >>= return . PointerTo
       
   123     , try (string "shortstring") >> return (String 255)
       
   124     , try (string "string") >> optionMaybe (brackets pas $ integer pas) >>= return . String . fromMaybe 255
       
   125     , try (string "ansistring") >> optionMaybe (brackets pas $ integer pas) >>= return . String . fromMaybe 255
       
   126     , arrayDecl
       
   127     , recordDecl
       
   128     , setDecl
       
   129     , functionType
       
   130     , sequenceDecl >>= return . Sequence
       
   131     , try iD >>= return . SimpleType
       
   132     , rangeDecl >>= return . RangeType
       
   133     ] <?> "type declaration"
       
   134     where
       
   135     arrayDecl = do
       
   136         try $ do
       
   137             optional $ (try $ string "packed") >> comments
       
   138             string "array"
       
   139         comments
       
   140         r <- option [] $ do
       
   141             char '['
       
   142             r <- commaSep pas rangeDecl
       
   143             char ']'
       
   144             comments
       
   145             return r
       
   146         string "of"
       
   147         comments
       
   148         t <- typeDecl
       
   149         if null r then
       
   150             return $ ArrayDecl Nothing t
       
   151             else
       
   152             return $ foldr (\a b -> ArrayDecl (Just a) b) (ArrayDecl (Just $ head r) t) (tail r)
       
   153     recordDecl = do
       
   154         try $ do
       
   155             optional $ (try $ string "packed") >> comments
       
   156             string "record"
       
   157         comments
       
   158         vs <- varsDecl True
       
   159         union <- optionMaybe $ do
       
   160             string "case"
       
   161             comments
       
   162             iD
       
   163             comments
       
   164             string "of"
       
   165             comments
       
   166             many unionCase
       
   167         string "end"
       
   168         return $ RecordType vs union
       
   169     setDecl = do
       
   170         try $ string "set" >> space
       
   171         comments
       
   172         string "of"
       
   173         comments
       
   174         liftM Set typeDecl
       
   175     unionCase = do
       
   176         try $ commaSep pas $ (iD >> return ()) <|> (integer pas >> return ())
       
   177         char ':'
       
   178         comments
       
   179         u <- parens pas $ varsDecl True
       
   180         char ';'
       
   181         comments
       
   182         return u
       
   183     sequenceDecl = (parens pas) $ (commaSep pas) (iD >>= \i -> optional (spaces >> char '=' >> spaces >> integer pas) >> return i)
       
   184     functionType = do
       
   185         fp <- try (string "function") <|> try (string "procedure")
       
   186         comments
       
   187         vs <- option [] $ parens pas $ varsDecl False
       
   188         comments
       
   189         ret <- if (fp == "function") then do
       
   190             char ':'
       
   191             comments
       
   192             ret <- typeDecl
       
   193             comments
       
   194             return ret
       
   195             else
       
   196             return VoidType
       
   197         optional $ try $ char ';' >> comments >> string "cdecl"
       
   198         comments
       
   199         return $ FunctionType ret vs
       
   200 
       
   201 typesDecl = many (aTypeDecl >>= \t -> comments >> return t)
       
   202     where
       
   203     aTypeDecl = do
       
   204         i <- try $ do
       
   205             i <- iD <?> "type declaration"
       
   206             comments
       
   207             char '='
       
   208             return i
       
   209         comments
       
   210         t <- typeDecl
       
   211         comments
       
   212         semi pas
       
   213         comments
       
   214         return $ TypeDeclaration i t
       
   215 
       
   216 rangeDecl = choice [
       
   217     try $ rangeft
       
   218     , iD >>= return . Range
       
   219     ] <?> "range declaration"
       
   220     where
       
   221     rangeft = do
       
   222     e1 <- initExpression
       
   223     string ".."
       
   224     e2 <- initExpression
       
   225     return $ RangeFromTo e1 e2
       
   226 
       
   227 typeVarDeclaration isImpl = (liftM concat . many . choice) [
       
   228     varSection,
       
   229     constSection,
       
   230     typeSection,
       
   231     funcDecl,
       
   232     operatorDecl
       
   233     ]
       
   234     where
       
   235     varSection = do
       
   236         try $ string "var"
       
   237         comments
       
   238         v <- varsDecl1 True <?> "variable declaration"
       
   239         comments
       
   240         return v
       
   241 
       
   242     constSection = do
       
   243         try $ string "const"
       
   244         comments
       
   245         c <- constsDecl <?> "const declaration"
       
   246         comments
       
   247         return c
       
   248 
       
   249     typeSection = do
       
   250         try $ string "type"
       
   251         comments
       
   252         t <- typesDecl <?> "type declaration"
       
   253         comments
       
   254         return t
       
   255 
       
   256     operatorDecl = do
       
   257         try $ string "operator"
       
   258         comments
       
   259         i <- manyTill anyChar space
       
   260         comments
       
   261         vs <- parens pas $ varsDecl False
       
   262         comments
       
   263         rid <- iD
       
   264         comments
       
   265         char ':'
       
   266         comments
       
   267         ret <- typeDecl
       
   268         comments
       
   269         return ret
       
   270         char ';'
       
   271         comments
       
   272         forward <- liftM isJust $ optionMaybe (try (string "forward;") >> comments)
       
   273         inline <- liftM (any (== "inline;")) $ many functionDecorator
       
   274         b <- if isImpl && (not forward) then
       
   275                 liftM Just functionBody
       
   276                 else
       
   277                 return Nothing
       
   278         return $ [OperatorDeclaration i rid inline ret vs b]
       
   279 
       
   280 
       
   281     funcDecl = do
       
   282         fp <- try (string "function") <|> try (string "procedure")
       
   283         comments
       
   284         i <- iD
       
   285         vs <- option [] $ parens pas $ varsDecl False
       
   286         comments
       
   287         ret <- if (fp == "function") then do
       
   288             char ':'
       
   289             comments
       
   290             ret <- typeDecl
       
   291             comments
       
   292             return ret
       
   293             else
       
   294             return VoidType
       
   295         char ';'
       
   296         comments
       
   297         forward <- liftM isJust $ optionMaybe (try (string "forward;") >> comments)
       
   298         inline <- liftM (any (== "inline;")) $ many functionDecorator
       
   299         b <- if isImpl && (not forward) then
       
   300                 liftM Just functionBody
       
   301                 else
       
   302                 return Nothing
       
   303         return $ [FunctionDeclaration i inline ret vs b]
       
   304 
       
   305     functionDecorator = do
       
   306         d <- choice [
       
   307             try $ string "inline;"
       
   308             , try $ caseInsensitiveString "cdecl;"
       
   309             , try $ string "overload;"
       
   310             , try $ string "export;"
       
   311             , try $ string "varargs;"
       
   312             , try (string "external") >> comments >> iD >> optional (string "name" >> comments >> stringLiteral pas)>> string ";"
       
   313             ]
       
   314         comments
       
   315         return d
       
   316 
       
   317 
       
   318 program = do
       
   319     string "program"
       
   320     comments
       
   321     name <- iD
       
   322     (char ';')
       
   323     comments
       
   324     comments
       
   325     u <- uses
       
   326     comments
       
   327     tv <- typeVarDeclaration True
       
   328     comments
       
   329     p <- phrase
       
   330     comments
       
   331     char '.'
       
   332     comments
       
   333     return $ Program name (Implementation u (TypesAndVars tv)) p
       
   334 
       
   335 interface = do
       
   336     string "interface"
       
   337     comments
       
   338     u <- uses
       
   339     comments
       
   340     tv <- typeVarDeclaration False
       
   341     comments
       
   342     return $ Interface u (TypesAndVars tv)
       
   343 
       
   344 implementation = do
       
   345     string "implementation"
       
   346     comments
       
   347     u <- uses
       
   348     comments
       
   349     tv <- typeVarDeclaration True
       
   350     string "end."
       
   351     comments
       
   352     return $ Implementation u (TypesAndVars tv)
       
   353 
       
   354 expression = do
       
   355     buildExpressionParser table term <?> "expression"
       
   356     where
       
   357     term = comments >> choice [
       
   358         builtInFunction expression >>= \(n, e) -> return $ BuiltInFunCall e (SimpleReference (Identifier n BTUnknown))
       
   359         , try (parens pas $ expression >>= \e -> notFollowedBy (comments >> char '.') >> return e)
       
   360         , brackets pas (commaSep pas iD) >>= return . SetExpression
       
   361         , try $ integer pas >>= \i -> notFollowedBy (char '.') >> (return . NumberLiteral . show) i
       
   362         , float pas >>= return . FloatLiteral . show
       
   363         , try $ integer pas >>= return . NumberLiteral . show
       
   364         , try (string "_S" >> stringLiteral pas) >>= return . StringLiteral
       
   365         , try (string "_P" >> stringLiteral pas) >>= return . PCharLiteral
       
   366         , stringLiteral pas >>= return . strOrChar
       
   367         , try (string "#$") >> many hexDigit >>= \c -> comments >> return (HexCharCode c)
       
   368         , char '#' >> many digit >>= \c -> comments >> return (CharCode c)
       
   369         , char '$' >> many hexDigit >>=  \h -> comments >> return (HexNumber h)
       
   370         --, char '-' >> expression >>= return . PrefixOp "-"
       
   371         , char '-' >> reference >>= return . PrefixOp "-" . Reference
       
   372         , (try $ string "not" >> notFollowedBy comments) >> unexpected "'not'"
       
   373         , try $ string "nil" >> return Null
       
   374         , reference >>= return . Reference
       
   375         ] <?> "simple expression"
       
   376 
       
   377     table = [
       
   378           [  Prefix (try (string "not") >> return (PrefixOp "not"))
       
   379            , Prefix (try (char '-') >> return (PrefixOp "-"))]
       
   380         ,
       
   381           [  Infix (char '*' >> return (BinOp "*")) AssocLeft
       
   382            , Infix (char '/' >> return (BinOp "/")) AssocLeft
       
   383            , Infix (try (string "div") >> return (BinOp "div")) AssocLeft
       
   384            , Infix (try (string "mod") >> return (BinOp "mod")) AssocLeft
       
   385            , Infix (try (string "in") >> return (BinOp "in")) AssocNone
       
   386            , Infix (try $ string "and" >> return (BinOp "and")) AssocLeft
       
   387            , Infix (try $ string "shl" >> return (BinOp "shl")) AssocLeft
       
   388            , Infix (try $ string "shr" >> return (BinOp "shr")) AssocLeft
       
   389           ]
       
   390         , [  Infix (char '+' >> return (BinOp "+")) AssocLeft
       
   391            , Infix (char '-' >> return (BinOp "-")) AssocLeft
       
   392            , Infix (try $ string "or" >> return (BinOp "or")) AssocLeft
       
   393            , Infix (try $ string "xor" >> return (BinOp "xor")) AssocLeft
       
   394           ]
       
   395         , [  Infix (try (string "<>") >> return (BinOp "<>")) AssocNone
       
   396            , Infix (try (string "<=") >> return (BinOp "<=")) AssocNone
       
   397            , Infix (try (string ">=") >> return (BinOp ">=")) AssocNone
       
   398            , Infix (char '<' >> return (BinOp "<")) AssocNone
       
   399            , Infix (char '>' >> return (BinOp ">")) AssocNone
       
   400           ]
       
   401         {-, [  Infix (try $ string "shl" >> return (BinOp "shl")) AssocNone
       
   402              , Infix (try $ string "shr" >> return (BinOp "shr")) AssocNone
       
   403           ]
       
   404         , [
       
   405              Infix (try $ string "or" >> return (BinOp "or")) AssocLeft
       
   406            , Infix (try $ string "xor" >> return (BinOp "xor")) AssocLeft
       
   407           ]-}
       
   408         , [
       
   409              Infix (char '=' >> return (BinOp "=")) AssocNone
       
   410           ]
       
   411         ]
       
   412     strOrChar [a] = CharCode . show . ord $ a
       
   413     strOrChar a = StringLiteral a
       
   414 
       
   415 phrasesBlock = do
       
   416     try $ string "begin"
       
   417     comments
       
   418     p <- manyTill phrase (try $ string "end" >> notFollowedBy alphaNum)
       
   419     comments
       
   420     return $ Phrases p
       
   421 
       
   422 phrase = do
       
   423     o <- choice [
       
   424         phrasesBlock
       
   425         , ifBlock
       
   426         , whileCycle
       
   427         , repeatCycle
       
   428         , switchCase
       
   429         , withBlock
       
   430         , forCycle
       
   431         , (try $ reference >>= \r -> string ":=" >> return r) >>= \r -> comments >> expression >>= return . Assignment r
       
   432         , builtInFunction expression >>= \(n, e) -> return $ BuiltInFunctionCall e (SimpleReference (Identifier n BTUnknown))
       
   433         , procCall
       
   434         , char ';' >> comments >> return NOP
       
   435         ]
       
   436     optional $ char ';'
       
   437     comments
       
   438     return o
       
   439 
       
   440 ifBlock = do
       
   441     try $ string "if" >> notFollowedBy (alphaNum <|> char '_')
       
   442     comments
       
   443     e <- expression
       
   444     comments
       
   445     string "then"
       
   446     comments
       
   447     o1 <- phrase
       
   448     comments
       
   449     o2 <- optionMaybe $ do
       
   450         try $ string "else" >> space
       
   451         comments
       
   452         o <- option NOP phrase
       
   453         comments
       
   454         return o
       
   455     return $ IfThenElse e o1 o2
       
   456 
       
   457 whileCycle = do
       
   458     try $ string "while"
       
   459     comments
       
   460     e <- expression
       
   461     comments
       
   462     string "do"
       
   463     comments
       
   464     o <- phrase
       
   465     return $ WhileCycle e o
       
   466 
       
   467 withBlock = do
       
   468     try $ string "with" >> space
       
   469     comments
       
   470     rs <- (commaSep1 pas) reference
       
   471     comments
       
   472     string "do"
       
   473     comments
       
   474     o <- phrase
       
   475     return $ foldr WithBlock o rs
       
   476 
       
   477 repeatCycle = do
       
   478     try $ string "repeat" >> space
       
   479     comments
       
   480     o <- many phrase
       
   481     string "until"
       
   482     comments
       
   483     e <- expression
       
   484     comments
       
   485     return $ RepeatCycle e o
       
   486 
       
   487 forCycle = do
       
   488     try $ string "for" >> space
       
   489     comments
       
   490     i <- iD
       
   491     comments
       
   492     string ":="
       
   493     comments
       
   494     e1 <- expression
       
   495     comments
       
   496     up <- liftM (== Just "to") $
       
   497             optionMaybe $ choice [
       
   498                 try $ string "to"
       
   499                 , try $ string "downto"
       
   500                 ]
       
   501     --choice [string "to", string "downto"]
       
   502     comments
       
   503     e2 <- expression
       
   504     comments
       
   505     string "do"
       
   506     comments
       
   507     p <- phrase
       
   508     comments
       
   509     return $ ForCycle i e1 e2 p up
       
   510 
       
   511 switchCase = do
       
   512     try $ string "case"
       
   513     comments
       
   514     e <- expression
       
   515     comments
       
   516     string "of"
       
   517     comments
       
   518     cs <- many1 aCase
       
   519     o2 <- optionMaybe $ do
       
   520         try $ string "else" >> notFollowedBy alphaNum
       
   521         comments
       
   522         o <- many phrase
       
   523         comments
       
   524         return o
       
   525     string "end"
       
   526     comments
       
   527     return $ SwitchCase e cs o2
       
   528     where
       
   529     aCase = do
       
   530         e <- (commaSep pas) $ (liftM InitRange rangeDecl <|> initExpression)
       
   531         comments
       
   532         char ':'
       
   533         comments
       
   534         p <- phrase
       
   535         comments
       
   536         return (e, p)
       
   537 
       
   538 procCall = do
       
   539     r <- reference
       
   540     p <- option [] $ (parens pas) parameters
       
   541     return $ ProcCall r p
       
   542 
       
   543 parameters = (commaSep pas) expression <?> "parameters"
       
   544 
       
   545 functionBody = do
       
   546     tv <- typeVarDeclaration True
       
   547     comments
       
   548     p <- phrasesBlock
       
   549     char ';'
       
   550     comments
       
   551     return (TypesAndVars tv, p)
       
   552 
       
   553 uses = liftM Uses (option [] u)
       
   554     where
       
   555         u = do
       
   556             string "uses"
       
   557             comments
       
   558             u <- (iD >>= \i -> comments >> return i) `sepBy1` (char ',' >> comments)
       
   559             char ';'
       
   560             comments
       
   561             return u
       
   562 
       
   563 initExpression = buildExpressionParser table term <?> "initialization expression"
       
   564     where
       
   565     term = comments >> choice [
       
   566         liftM (uncurry BuiltInFunction) $ builtInFunction initExpression
       
   567         , try $ brackets pas (commaSep pas $ initExpression) >>= return . InitSet
       
   568         , try $ parens pas (commaSep pas $ initExpression) >>= \ia -> when (null $ tail ia) mzero >> return (InitArray ia)
       
   569         , try $ parens pas (sepEndBy recField (char ';' >> comments)) >>= return . InitRecord
       
   570         , parens pas initExpression
       
   571         , try $ integer pas >>= \i -> notFollowedBy (char '.') >> (return . InitNumber . show) i
       
   572         , try $ float pas >>= return . InitFloat . show
       
   573         , try $ integer pas >>= return . InitNumber . show
       
   574         , stringLiteral pas >>= return . InitString
       
   575         , char '#' >> many digit >>= \c -> comments >> return (InitChar c)
       
   576         , char '$' >> many hexDigit >>= \h -> comments >> return (InitHexNumber h)
       
   577         , char '@' >> initExpression >>= \c -> comments >> return (InitAddress c)
       
   578         , try $ string "nil" >> return InitNull
       
   579         , itypeCast
       
   580         , iD >>= return . InitReference
       
   581         ]
       
   582 
       
   583     recField = do
       
   584         i <- iD
       
   585         spaces
       
   586         char ':'
       
   587         spaces
       
   588         e <- initExpression
       
   589         spaces
       
   590         return (i ,e)
       
   591 
       
   592     table = [
       
   593           [
       
   594              Prefix (char '-' >> return (InitPrefixOp "-"))
       
   595             ,Prefix (try (string "not") >> return (InitPrefixOp "not"))
       
   596           ]
       
   597         , [  Infix (char '*' >> return (InitBinOp "*")) AssocLeft
       
   598            , Infix (char '/' >> return (InitBinOp "/")) AssocLeft
       
   599            , Infix (try (string "div") >> return (InitBinOp "div")) AssocLeft
       
   600            , Infix (try (string "mod") >> return (InitBinOp "mod")) AssocLeft
       
   601            , Infix (try $ string "and" >> return (InitBinOp "and")) AssocLeft
       
   602            , Infix (try $ string "shl" >> return (InitBinOp "shl")) AssocNone
       
   603            , Infix (try $ string "shr" >> return (InitBinOp "shr")) AssocNone
       
   604           ]
       
   605         , [  Infix (char '+' >> return (InitBinOp "+")) AssocLeft
       
   606            , Infix (char '-' >> return (InitBinOp "-")) AssocLeft
       
   607            , Infix (try $ string "or" >> return (InitBinOp "or")) AssocLeft
       
   608            , Infix (try $ string "xor" >> return (InitBinOp "xor")) AssocLeft
       
   609           ]
       
   610         , [  Infix (try (string "<>") >> return (InitBinOp "<>")) AssocNone
       
   611            , Infix (try (string "<=") >> return (InitBinOp "<=")) AssocNone
       
   612            , Infix (try (string ">=") >> return (InitBinOp ">=")) AssocNone
       
   613            , Infix (char '<' >> return (InitBinOp "<")) AssocNone
       
   614            , Infix (char '>' >> return (InitBinOp ">")) AssocNone
       
   615            , Infix (char '=' >> return (InitBinOp "=")) AssocNone
       
   616           ]
       
   617         {--, [  Infix (try $ string "and" >> return (InitBinOp "and")) AssocLeft
       
   618            , Infix (try $ string "or" >> return (InitBinOp "or")) AssocLeft
       
   619            , Infix (try $ string "xor" >> return (InitBinOp "xor")) AssocLeft
       
   620           ]
       
   621         , [  Infix (try $ string "shl" >> return (InitBinOp "shl")) AssocNone
       
   622            , Infix (try $ string "shr" >> return (InitBinOp "shr")) AssocNone
       
   623           ]--}
       
   624         --, [Prefix (try (string "not") >> return (InitPrefixOp "not"))]
       
   625         ]
       
   626 
       
   627     itypeCast = do
       
   628         t <- choice $ map (\s -> try $ caseInsensitiveString s >>= \i -> notFollowedBy alphaNum >> return i) knownTypes
       
   629         i <- parens pas initExpression
       
   630         comments
       
   631         return $ InitTypeCast (Identifier t BTUnknown) i
       
   632 
       
   633 builtInFunction e = do
       
   634     name <- choice $ map (\s -> try $ caseInsensitiveString s >>= \i -> notFollowedBy alphaNum >> return i) builtin
       
   635     spaces
       
   636     exprs <- option [] $ parens pas $ option [] $ commaSep1 pas $ e
       
   637     spaces
       
   638     return (name, exprs)
       
   639 
       
   640 systemUnit = do
       
   641     string "system;"
       
   642     comments
       
   643     string "type"
       
   644     comments
       
   645     t <- typesDecl
       
   646     string "var"
       
   647     v <- varsDecl True
       
   648     return $ System (t ++ v)
       
   649 
       
   650 redoUnit = do
       
   651     string "redo;"
       
   652     comments
       
   653     string "type"
       
   654     comments
       
   655     t <- typesDecl
       
   656     string "var"
       
   657     v <- varsDecl True
       
   658     return $ Redo (t ++ v)
       
   659