okay layouts kinda

This commit is contained in:
crumbtoo
2024-01-14 14:20:08 -07:00
parent 2496589346
commit e597ecbfc6
5 changed files with 58 additions and 45 deletions

View File

@@ -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

View File

@@ -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

Binary file not shown.

View File

@@ -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
} }

View File

@@ -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 }