man this sucks
This commit is contained in:
111
src/Rlp/Lex.x
111
src/Rlp/Lex.x
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
|
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
module Rlp.Lex
|
module Rlp.Lex
|
||||||
( P(..)
|
( P(..)
|
||||||
@@ -12,19 +13,34 @@ module Rlp.Lex
|
|||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Data.Functor.Identity
|
import Data.Functor.Identity
|
||||||
import Core.Syntax (Name)
|
import Core.Syntax (Name)
|
||||||
|
import Data.Monoid (First)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
|
import Lens.Micro.Mtl
|
||||||
import Lens.Micro
|
import Lens.Micro
|
||||||
|
import Lens.Micro.TH
|
||||||
}
|
}
|
||||||
|
|
||||||
%wrapper "monad-strict-text"
|
%wrapper "monadUserState-strict-text"
|
||||||
|
|
||||||
$whitechar = [ \t\n\r\f\v]
|
$whitechar = [ \t\n\r\f\v]
|
||||||
|
|
||||||
|
$lower = [a-z \_]
|
||||||
|
$upper = [A-Z]
|
||||||
|
$alpha = [$lower $upper]
|
||||||
|
$digit = 0-9
|
||||||
|
|
||||||
|
$nl = [\n\r]
|
||||||
|
$white_no_nl = $white # $nl
|
||||||
|
|
||||||
|
$namechar = [$alpha $digit \' \#]
|
||||||
|
|
||||||
|
@varname = $lower $namechar*
|
||||||
|
|
||||||
rlp :-
|
rlp :-
|
||||||
|
|
||||||
-- skip whitespace
|
-- skip whitespace
|
||||||
$white+ ;
|
$white_no_nl+ ;
|
||||||
-- TODO: don't treat operators like (-->) as comments
|
-- TODO: don't treat operators like (-->) as comments
|
||||||
"--".* ;
|
"--".* ;
|
||||||
";" { constToken TokenSemicolon }
|
";" { constToken TokenSemicolon }
|
||||||
@@ -33,7 +49,15 @@ rlp :-
|
|||||||
|
|
||||||
<0>
|
<0>
|
||||||
{
|
{
|
||||||
"a" { const $ const $ pure $ Located (AlexPn 0 0 0) (TokenVarName "a") }
|
@varname { tokenWith TokenVarName }
|
||||||
|
"=" { constToken TokenEquals }
|
||||||
|
}
|
||||||
|
|
||||||
|
<bol>
|
||||||
|
{
|
||||||
|
$whitechar ;
|
||||||
|
\n ;
|
||||||
|
() { doBol }
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -41,53 +65,71 @@ rlp :-
|
|||||||
constToken :: RlpToken -> AlexAction (Located RlpToken)
|
constToken :: RlpToken -> AlexAction (Located RlpToken)
|
||||||
constToken t inp _ = pure $ Located (inp ^. _1) t
|
constToken t inp _ = pure $ Located (inp ^. _1) t
|
||||||
|
|
||||||
|
tokenWith :: (Text -> RlpToken) -> AlexAction (Located RlpToken)
|
||||||
|
tokenWith tf (p,_,_,s) l = pure $ Located p (tf $ T.take l s)
|
||||||
|
|
||||||
alexEOF :: Alex (Located RlpToken)
|
alexEOF :: Alex (Located RlpToken)
|
||||||
alexEOF = do
|
alexEOF = do
|
||||||
inp <- alexGetInput
|
inp <- alexGetInput
|
||||||
pure (Located (inp ^. _1) TokenEOF)
|
pure (Located (inp ^. _1) TokenEOF)
|
||||||
|
|
||||||
data RlpToken = TokenEquals
|
data RlpToken
|
||||||
| TokenLitInt Int
|
-- literals
|
||||||
|
= TokenLitInt Int
|
||||||
|
-- identifiers
|
||||||
| TokenVarName Name
|
| TokenVarName Name
|
||||||
| TokenConName Name
|
| TokenConName Name
|
||||||
| TokenVarSym Name
|
| TokenVarSym Name
|
||||||
| TokenConSym Name
|
| TokenConSym Name
|
||||||
|
-- keywords
|
||||||
| TokenData
|
| TokenData
|
||||||
| TokenPipe
|
| TokenPipe
|
||||||
-- syntax control
|
| TokenLet
|
||||||
|
| TokenIn
|
||||||
|
-- control symbols
|
||||||
|
| TokenEquals
|
||||||
| TokenSemicolon
|
| TokenSemicolon
|
||||||
| TokenLBrace
|
| TokenLBrace
|
||||||
| TokenRBrace
|
| TokenRBrace
|
||||||
| TokenEOF
|
| TokenEOF
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
newtype P a = P { runP :: PState -> Text -> Either String a }
|
newtype P a = P { runP :: Text -> Either String a }
|
||||||
deriving (Functor)
|
deriving (Functor)
|
||||||
|
|
||||||
data PState = PState
|
data AlexUserState = AlexUserState
|
||||||
{ psLayoutStack :: [Layout]
|
{ _ausLayoutStack :: [Layout]
|
||||||
}
|
}
|
||||||
|
|
||||||
data Layout = ExplicitLayout
|
alexInitUserState :: AlexUserState
|
||||||
| ImplicitLayout Int
|
alexInitUserState = AlexUserState
|
||||||
deriving (Show)
|
{ _ausLayoutStack = []
|
||||||
|
}
|
||||||
|
|
||||||
|
data Layout = Explicit
|
||||||
|
| Implicit Int
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
instance Applicative P where
|
instance Applicative P where
|
||||||
pure = P . const . const . Right
|
pure = P . const . Right
|
||||||
|
|
||||||
liftA2 = liftM2
|
liftA2 = liftM2
|
||||||
|
|
||||||
instance Monad P where
|
instance Monad P where
|
||||||
m >>= k = P $ \st s -> case runP m st s of
|
m >>= k = P $ \s -> case runP m s of
|
||||||
Right a -> runP (k a) st s
|
Right a -> runP (k a) s
|
||||||
Left e -> Left e
|
Left e -> Left e
|
||||||
|
|
||||||
data Located a = Located AlexPosn a
|
data Located a = Located AlexPosn a
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
|
ausLayoutStack :: Lens' AlexUserState [Layout]
|
||||||
|
ausLayoutStack = lens _ausLayoutStack
|
||||||
|
(\ s l -> s { _ausLayoutStack = l })
|
||||||
|
|
||||||
lexer :: (Located RlpToken -> P a) -> P a
|
lexer :: (Located RlpToken -> P a) -> P a
|
||||||
lexer f = P $ \st s -> case m s of
|
lexer f = P $ \s -> case m s of
|
||||||
Right (a,s') -> runP (f a) st (s' ^. _4)
|
Right (a,s') -> runP (f a) (s' ^. _4)
|
||||||
Left e -> error (show e)
|
Left e -> error (show e)
|
||||||
where
|
where
|
||||||
m s = runAlex s ((,) <$> alexMonadScan <*> alexGetInput)
|
m s = runAlex s ((,) <$> alexMonadScan <*> alexGetInput)
|
||||||
@@ -95,6 +137,39 @@ lexer f = P $ \st s -> case m s of
|
|||||||
lexStream :: P [RlpToken]
|
lexStream :: P [RlpToken]
|
||||||
lexStream = lexer go where
|
lexStream = lexer go where
|
||||||
go (Located _ TokenEOF) = pure [TokenEOF]
|
go (Located _ TokenEOF) = pure [TokenEOF]
|
||||||
go (Located _ t) = (t:) <$> lexStream
|
go (Located _ t) = (t:) <$!> lexStream
|
||||||
|
|
||||||
|
getsAus :: (AlexUserState -> b) -> Alex b
|
||||||
|
getsAus k = alexGetUserState <&> k
|
||||||
|
|
||||||
|
useAus :: Getting a AlexUserState a -> Alex a
|
||||||
|
useAus l = do
|
||||||
|
aus <- alexGetUserState
|
||||||
|
pure (aus ^. l)
|
||||||
|
|
||||||
|
preuseAus :: Getting (First a) AlexUserState a -> Alex (Maybe a)
|
||||||
|
preuseAus l = do
|
||||||
|
aus <- alexGetUserState
|
||||||
|
pure (aus ^? l)
|
||||||
|
|
||||||
|
indentLevel :: Alex Int
|
||||||
|
indentLevel = do
|
||||||
|
inp <- alexGetInput
|
||||||
|
let col = inp ^. _1
|
||||||
|
& \ (AlexPn _ _ c) -> c
|
||||||
|
pure col
|
||||||
|
|
||||||
|
cmpLayout :: Alex Ordering
|
||||||
|
cmpLayout = do
|
||||||
|
i <- indentLevel
|
||||||
|
ctx <- preuseAus (ausLayoutStack . _head)
|
||||||
|
case ctx ^. non (Implicit 0) of
|
||||||
|
Implicit n -> pure (n `compare` i)
|
||||||
|
Explicit -> pure GT
|
||||||
|
|
||||||
|
doBol :: AlexAction (Located RlpToken)
|
||||||
|
doBol _ _ = do
|
||||||
|
undefined
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ module Rlp.Parse
|
|||||||
)
|
)
|
||||||
where
|
where
|
||||||
import Rlp.Lex
|
import Rlp.Lex
|
||||||
|
import Rlp.Syntax
|
||||||
|
import Rlp.Parse.Types
|
||||||
}
|
}
|
||||||
|
|
||||||
%name rlp
|
%name rlp
|
||||||
@@ -13,12 +15,20 @@ import Rlp.Lex
|
|||||||
%tokentype { Located RlpToken }
|
%tokentype { Located RlpToken }
|
||||||
|
|
||||||
%token
|
%token
|
||||||
t { Located _ _ }
|
varname { Located _ (TokenVarName $$) }
|
||||||
|
'=' { Located _ TokenEquals }
|
||||||
|
eof { Located _ TokenEOF }
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
P :: { () }
|
Decl :: { PartialDecl' }
|
||||||
P : { error "aa" }
|
Decl : FunDecl { undefined }
|
||||||
|
|
||||||
|
FunDecl :: { PartialDecl' }
|
||||||
|
FunDecl : varname '=' Expr { undefined }
|
||||||
|
|
||||||
|
Expr :: { RlpExpr' }
|
||||||
|
Expr : { undefined }
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user