Commit afce504f authored by Kai Prott's avatar Kai Prott
Browse files

Started adding a parser for conditional compiling

parent e8f0f7f6
module Curry.CondCompile.Parser where
import Text.Parsec hiding (newline)
data Stmt = IFDEF String [Stmt] [Stmt]
| IF Condition [Stmt] [Stmt]
| Code String
deriving Show
type Condition = (String, CompOperator, String)
data CompOperator = EQUAL | LESS | LEQ | GREATER | GEQ | NEQ
deriving Show
type Parser a = Parsec String () a
example = "#IFDEF value\nlol\n#ENDIF"
iftoken = return () <* string "#IF" <* whitespaces
ifdeftoken = return () <* string "#IFDEF" <* whitespaces
elsetoken = return () <* newline <* string "#ELSE" <* whitespaces
endtoken = return () <* newline <* string "#ENDIF" <* whitespaces
reservedTokens = [iftoken, ifdeftoken, elsetoken, endtoken]
whitespaces :: Parser ()
whitespaces = skipMany (() <$ space)
simpleParse :: String -> Either String [Stmt]
simpleParse = either (Left . show) Right . runParser program () ""
program :: Parser [Stmt]
program = many statement <* eof
statement :: Parser Stmt
statement = ifdef <|> ifstmt <|> code
ifstmt :: Parser Stmt
ifstmt = try ifelse <|> try ifstmt'
ifelse :: Parser Stmt
ifelse = IF <$> (iftoken *> condition <* newline)
<*> many statement
<*> (elsetoken *> many statement <* endtoken)
ifstmt' :: Parser Stmt
ifstmt' = IF <$> (iftoken *> condition <* newline)
<*> many statement
<*> (return [] <* endtoken)
ifdef :: Parser Stmt
ifdef = try ifdef' <|> try ifdefelse
ifdefelse :: Parser Stmt
ifdefelse = IFDEF <$> (ifdeftoken *> identifier <* newline)
<*> many statement
<*> (elsetoken *> many statement <* endtoken)
ifdef' :: Parser Stmt
ifdef' = IFDEF <$> (ifdeftoken *> identifier <* newline)
<*> many statement
<*> (return [] <* endtoken)
newline :: Parser Char
newline = char '\n'
code :: Parser Stmt
code = Code <$> many1 (notFollowedBy (choice reservedTokens) *> anyChar)
condition :: Parser Condition
condition = do ident <- identifier
op <- operator
condVal <- many digit
whitespaces
return (ident, op, condVal)
operator :: Parser CompOperator
operator = choice [ EQUAL <$ string "="
, LESS <$ string "<"
, GREATER <$ string ">"
, LEQ <$ string "<="
, GEQ <$ string ">="
, NEQ <$ string "!="
]
identifier :: Parser String
identifier = (:) <$> firstChar <*> many nonFirstChar
where firstChar = letter <|> char '_'
nonFirstChar = digit <|> firstChar <|> char '.'
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment