module Syntax.Lexer where

import Text.Parsec.String
import qualified Text.Parsec.Token as T

import Control.Monad

import Text.Parsec.Language
import Text.Parsec.Combinator
import Text.Parsec.Prim
import Text.Parsec.Char

language
  = emptyDef { T.commentStart    = "/*"
             , T.commentEnd      = "*/"
             , T.commentLine     = "//"
             , T.identStart      = letter <|> char '_'
             , T.identLetter     = alphaNum <|> char '_'
             , T.reservedNames   = [ "if"
                                   , "else"
                                   , "for"
                                   , "lambda"
                                   , "func"
                                   , "open"
                                   , "return"
                                   , "let"
                                   , "true"
                                   , "false"
                                   , "ffi"
                                   , "module"
                                   , "var"
                                   , "match"
                                   ]
             , T.reservedOpNames = [ "+", "-", "*", "/"
                                   , "=", "<", ">", "&&"
                                   , "||", "!", "~", "λ"
                                   , "÷", "×", "::"
                                   , ">=", "<=", "$"
                                   , "->" ]
             , T.nestedComments  = True
             , T.caseSensitive   = True
             }

lexer = T.makeTokenParser language
identifier = T.identifier lexer
reserved = T.reserved lexer
operator = T.operator lexer
reservedOp = T.reservedOp lexer
charLiteral = T.charLiteral lexer
stringLiteral = T.stringLiteral lexer
natOrFloat = T.naturalOrFloat lexer
symbol = T.symbol lexer
lexeme = T.lexeme lexer 
parens = T.parens lexer
braces = T.braces lexer
squares = T.brackets lexer
angles = T.angles lexer
semi = T.semi lexer
colon = T.colon lexer
comma = T.comma lexer
dot = T.dot lexer
semiSep = T.semiSep lexer
commaSep = T.commaSep lexer
semiSep1 = T.semiSep1 lexer
commaSep1 = T.commaSep1 lexer

contents :: Parser a -> Parser a
contents p = do
  T.whiteSpace lexer
  r <- p
  eof
  return r
