okay layouts kinda
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
HAPPY = happy
|
HAPPY = happy
|
||||||
HAPPY_OPTS =
|
HAPPY_OPTS =
|
||||||
ALEX = alex
|
ALEX = alex
|
||||||
ALEX_OPTS =
|
ALEX_OPTS = -d
|
||||||
|
|
||||||
SRC = src
|
SRC = src
|
||||||
CABAL_BUILD = dist-newstyle/build/x86_64-osx/ghc-9.6.2/rlp-0.1.0.0/build
|
CABAL_BUILD = dist-newstyle/build/x86_64-osx/ghc-9.6.2/rlp-0.1.0.0/build
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ library
|
|||||||
-- required for happy
|
-- required for happy
|
||||||
, array
|
, array
|
||||||
, data-default-class
|
, data-default-class
|
||||||
|
, data-default
|
||||||
, unordered-containers
|
, unordered-containers
|
||||||
, hashable
|
, hashable
|
||||||
, pretty
|
, pretty
|
||||||
|
|||||||
BIN
src/.DS_Store
vendored
BIN
src/.DS_Store
vendored
Binary file not shown.
@@ -8,6 +8,7 @@ module Rlp.Lex
|
|||||||
, Located(..)
|
, Located(..)
|
||||||
, AlexPosn
|
, AlexPosn
|
||||||
, lexer
|
, lexer
|
||||||
|
, lexerCont
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
@@ -17,6 +18,7 @@ import Data.Monoid (First)
|
|||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
|
import Data.Default
|
||||||
import Lens.Micro.Mtl
|
import Lens.Micro.Mtl
|
||||||
import Lens.Micro
|
import Lens.Micro
|
||||||
import Lens.Micro.TH
|
import Lens.Micro.TH
|
||||||
@@ -47,21 +49,21 @@ rlp :-
|
|||||||
-- TODO: don't treat operators like (-->) as comments
|
-- TODO: don't treat operators like (-->) as comments
|
||||||
"--".* ;
|
"--".* ;
|
||||||
";" { constToken TokenSemicolon }
|
";" { constToken TokenSemicolon }
|
||||||
"{" { explicitLBrace }
|
-- "{" { explicitLBrace }
|
||||||
"}" { explicitRBrace }
|
-- "}" { explicitRBrace }
|
||||||
|
|
||||||
<0>
|
<0>
|
||||||
{
|
{
|
||||||
$whitechar+ ;
|
|
||||||
\n ;
|
\n ;
|
||||||
"{" { expectLBrace }
|
"{" { explicitLBrace `thenBegin` one }
|
||||||
|
() { doLayout `thenBegin` one }
|
||||||
}
|
}
|
||||||
|
|
||||||
<one>
|
<one>
|
||||||
{
|
{
|
||||||
\n { begin bol }
|
|
||||||
@varname { tokenWith TokenVarName }
|
@varname { tokenWith TokenVarName }
|
||||||
"=" { constToken TokenEquals }
|
"=" { constToken TokenEquals }
|
||||||
|
\n { begin bol }
|
||||||
}
|
}
|
||||||
|
|
||||||
-- consume all whitespace leaving us at the beginning of the next non-empty
|
-- consume all whitespace leaving us at the beginning of the next non-empty
|
||||||
@@ -71,11 +73,19 @@ rlp :-
|
|||||||
{
|
{
|
||||||
$whitechar ;
|
$whitechar ;
|
||||||
\n ;
|
\n ;
|
||||||
() { doBol }
|
() { doBol `andBegin` one }
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
-- | @andBegin@, with the subtle difference that the start code is set
|
||||||
|
-- /after/ the action
|
||||||
|
thenBegin :: AlexAction a -> Int -> AlexAction a
|
||||||
|
thenBegin act c inp l = do
|
||||||
|
a <- act inp l
|
||||||
|
alexSetStartCode c
|
||||||
|
pure a
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
@@ -105,20 +115,33 @@ data RlpToken
|
|||||||
| TokenSemicolon
|
| TokenSemicolon
|
||||||
| TokenLBrace
|
| TokenLBrace
|
||||||
| TokenRBrace
|
| TokenRBrace
|
||||||
-- 'virtual' control symbols, implicitly inserted by the lexer
|
-- 'virtual' control symbols, inserted by the lexer without any correlation
|
||||||
|
-- to a specific symbol
|
||||||
| TokenSemicolonV
|
| TokenSemicolonV
|
||||||
| TokenLBraceV
|
| TokenLBraceV
|
||||||
| TokenRBraceV
|
| TokenRBraceV
|
||||||
| TokenEOF
|
| TokenEOF
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
newtype P a = P {
|
newtype P a = P { runP :: ParseState -> Alex (ParseState, a) }
|
||||||
runP :: AlexUserState -> Text -> Either String (AlexUserState, a)
|
|
||||||
}
|
|
||||||
deriving (Functor)
|
deriving (Functor)
|
||||||
|
|
||||||
runPInit :: P a -> Text -> Either String (AlexUserState, a)
|
execP :: P a -> ParseState -> Text -> Either String a
|
||||||
runPInit p = runP p alexInitUserState
|
execP p st s = snd <$> runAlex s (runP p st)
|
||||||
|
|
||||||
|
data ParseState = ParseState { }
|
||||||
|
|
||||||
|
instance Default ParseState where
|
||||||
|
def = ParseState { }
|
||||||
|
|
||||||
|
instance Applicative P where
|
||||||
|
pure a = P $ \st -> pure (st,a)
|
||||||
|
liftA2 = liftM2
|
||||||
|
|
||||||
|
instance Monad P where
|
||||||
|
p >>= k = P $ \st -> do
|
||||||
|
(st',a) <- runP p st
|
||||||
|
runP (k a) st'
|
||||||
|
|
||||||
data AlexUserState = AlexUserState
|
data AlexUserState = AlexUserState
|
||||||
-- the layout context, along with a start code to return to when the layout
|
-- the layout context, along with a start code to return to when the layout
|
||||||
@@ -136,16 +159,6 @@ data Layout = Explicit
|
|||||||
| Implicit Int
|
| Implicit Int
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
instance Applicative P where
|
|
||||||
pure a = P $ \st _ -> Right (st,a)
|
|
||||||
|
|
||||||
liftA2 = liftM2
|
|
||||||
|
|
||||||
instance Monad P where
|
|
||||||
m >>= k = P $ \st s -> case runP m st s of
|
|
||||||
Right (st',a) -> runP (k a) st' s
|
|
||||||
Left e -> Left e
|
|
||||||
|
|
||||||
data Located a = Located AlexPosn a
|
data Located a = Located AlexPosn a
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
@@ -153,20 +166,21 @@ ausLayoutStack :: Lens' AlexUserState [(Layout, Int)]
|
|||||||
ausLayoutStack = lens _ausLayoutStack
|
ausLayoutStack = lens _ausLayoutStack
|
||||||
(\ s l -> s { _ausLayoutStack = l })
|
(\ s l -> s { _ausLayoutStack = l })
|
||||||
|
|
||||||
lexer :: (Located RlpToken -> P a) -> P a
|
lexer :: P (Located RlpToken)
|
||||||
lexer f = P $ \st s -> case m st s of
|
lexer = P $ \st -> (st,) <$> lexToken
|
||||||
Right (a,st',s') -> runP (f a) st' (s' ^. _4)
|
|
||||||
Left e -> error (show e)
|
|
||||||
where
|
|
||||||
m st s = runAlex s
|
|
||||||
((,,) <$> (alexSetUserState st *> alexMonadScan)
|
|
||||||
<*> alexGetUserState
|
|
||||||
<*> alexGetInput)
|
|
||||||
|
|
||||||
lexStream :: P [RlpToken]
|
lexerCont :: (Located RlpToken -> P a) -> P a
|
||||||
lexStream = lexer go where
|
lexerCont = (lexer >>=)
|
||||||
go (Located _ TokenEOF) = pure [TokenEOF]
|
|
||||||
go (Located _ t) = (t:) <$!> lexStream
|
lexStream :: Alex [RlpToken]
|
||||||
|
lexStream = do
|
||||||
|
t <- lexToken
|
||||||
|
case t of
|
||||||
|
Located _ TokenEOF -> pure [TokenEOF]
|
||||||
|
Located _ a -> (a:) <$> lexStream
|
||||||
|
|
||||||
|
lexTest :: Text -> Either String [RlpToken]
|
||||||
|
lexTest = flip runAlex lexStream
|
||||||
|
|
||||||
lexToken :: Alex (Located RlpToken)
|
lexToken :: Alex (Located RlpToken)
|
||||||
lexToken = alexMonadScan
|
lexToken = alexMonadScan
|
||||||
@@ -210,13 +224,14 @@ insertToken t = do
|
|||||||
pure (Located (inp ^. _1) t)
|
pure (Located (inp ^. _1) t)
|
||||||
|
|
||||||
insertSemicolon, insertLBrace, insertRBrace :: Alex (Located RlpToken)
|
insertSemicolon, insertLBrace, insertRBrace :: Alex (Located RlpToken)
|
||||||
insertSemicolon = insertToken TokenSemicolonV
|
insertSemicolon = traceM "inserting semi" >> insertToken TokenSemicolonV
|
||||||
insertLBrace = insertToken TokenLBraceV
|
insertLBrace = traceM "inserting lbrace" >> insertToken TokenLBraceV
|
||||||
insertRBrace = insertToken TokenRBraceV
|
insertRBrace = traceM "inserting rbrace" >> insertToken TokenRBraceV
|
||||||
|
|
||||||
-- pop the layout stack and jump to the popped return code
|
-- pop the layout stack and jump to the popped return code
|
||||||
popLayout :: Alex ()
|
popLayout :: Alex ()
|
||||||
popLayout = do
|
popLayout = do
|
||||||
|
traceM "pop layout"
|
||||||
ctx <- preuseAus (ausLayoutStack . _head)
|
ctx <- preuseAus (ausLayoutStack . _head)
|
||||||
modifyingAus ausLayoutStack (drop 1)
|
modifyingAus ausLayoutStack (drop 1)
|
||||||
case ctx of
|
case ctx of
|
||||||
@@ -225,6 +240,7 @@ popLayout = do
|
|||||||
|
|
||||||
pushLayout :: Layout -> Alex ()
|
pushLayout :: Layout -> Alex ()
|
||||||
pushLayout l = do
|
pushLayout l = do
|
||||||
|
traceM "push layout"
|
||||||
c <- alexGetStartCode
|
c <- alexGetStartCode
|
||||||
modifyingAus ausLayoutStack ((l,c):)
|
modifyingAus ausLayoutStack ((l,c):)
|
||||||
|
|
||||||
@@ -240,7 +256,7 @@ doBol inp len = do
|
|||||||
GT -> undefined -- alexSetStartCode one >> lexToken
|
GT -> undefined -- alexSetStartCode one >> lexToken
|
||||||
-- the line is indented less than the previous, pop the layout stack and
|
-- the line is indented less than the previous, pop the layout stack and
|
||||||
-- insert a closing brace.
|
-- insert a closing brace.
|
||||||
LT -> popLayout >> insertRBrace >> alexSetStartCode 0 >> lexToken
|
LT -> insertRBrace >> popLayout >> lexToken
|
||||||
|
|
||||||
explicitLBrace, explicitRBrace :: AlexAction (Located RlpToken)
|
explicitLBrace, explicitRBrace :: AlexAction (Located RlpToken)
|
||||||
|
|
||||||
@@ -258,9 +274,5 @@ doLayout _ _ = do
|
|||||||
pushLayout (Implicit i)
|
pushLayout (Implicit i)
|
||||||
insertLBrace
|
insertLBrace
|
||||||
|
|
||||||
expectLBrace :: AlexAction (Located RlpToken)
|
|
||||||
expectLBrace _ _ = do
|
|
||||||
off <- cmpLayout
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import Rlp.Parse.Types
|
|||||||
|
|
||||||
%name rlp
|
%name rlp
|
||||||
%monad { P }
|
%monad { P }
|
||||||
%lexer { lexer } { Located _ TokenEOF }
|
%lexer { lexerCont } { Located _ TokenEOF }
|
||||||
%error { parseError }
|
%error { parseError }
|
||||||
%tokentype { Located RlpToken }
|
%tokentype { Located RlpToken }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user