Skip to content

Commit

Permalink
add 'Parser' with basic parsing infrastructure
Browse files Browse the repository at this point in the history
also:
- TokenType: derive 'Eq' instance
  • Loading branch information
ccntrq committed Jan 6, 2018
1 parent 1eeb10e commit 6f44a50
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
50 changes: 50 additions & 0 deletions src/Parser.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
module Parser where

import Expr
import Stmt
import Token
import TokenType

import Control.Conditional

import Control.Monad.State
import Control.Monad.Except
import Control.Monad.Identity

data ParserState = ParserState
{ tokens :: [Token]
, current :: Int
} deriving (Show)

data ParserError = ScannerError Token String deriving (Show)

type Parser a = ExceptT ParserError (StateT ParserState Identity) a

runParser :: ParserState -> Parser a -> Either ParserError a
runParser st p = runIdentity $ evalStateT (runExceptT p) st

initState :: [Token] -> ParserState
initState ts = ParserState ts 0

parse :: Parser [Stmt]
parse = parse' []
where
parse' acc = ifM isAtEnd (return $ reverse acc) (declaration >>= \d -> parse' d:acc)

check :: TokenType -> Parser Bool
check tokenType = ifM isAtEnd (return False) (peek >>= \t -> return $ t_type t == tokenType)

advance :: Parser Token
advance = ifM isAtEnd (previous) (incCurrent >> previous)

isAtEnd :: Parser Bool
isAtEnd = peek >>= \t -> if' (t_type t == EOF) (return True) (return False)

peek :: Parser Token
peek = get >>= \s -> return $ tokens s !! current s

previous :: Parser Token
previous = get >>= \s -> return $ tokens s !! (current s - 1)

incCurrent :: Parser ()
incCurrent = get >>= \s -> put s {current = current s +1}
2 changes: 1 addition & 1 deletion src/TokenType.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ data TokenType
| EOF
-- Throwaway token for comment/whitespace
| WS
deriving (Show)
deriving (Show, Eq)

0 comments on commit 6f44a50

Please sign in to comment.