remove old files
This commit is contained in:
@@ -1,315 +0,0 @@
|
||||
{
|
||||
-- TODO: layout semicolons are not inserted at EOf.
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
module Core.Lex
|
||||
( lexCore
|
||||
, lexCore'
|
||||
, CoreToken(..)
|
||||
, ParseError(..)
|
||||
, Located(..)
|
||||
, AlexPosn(..)
|
||||
)
|
||||
where
|
||||
import Data.Char (chr)
|
||||
import Debug.Trace
|
||||
import Core.Syntax
|
||||
import Compiler.RLPC
|
||||
import Lens.Micro
|
||||
import Lens.Micro.TH
|
||||
}
|
||||
|
||||
%wrapper "monadUserState"
|
||||
|
||||
$whitechar = [ \t\n\r\f\v]
|
||||
$special = [\(\)\,\;\[\]\{\}]
|
||||
|
||||
$digit = 0-9
|
||||
|
||||
$ascsymbol = [\!\#\$\%\&\*\+\.\/\<\=\>\?\@\\\^\|\-\~]
|
||||
$unisymbol = [] -- TODO
|
||||
$symbol = [$ascsymbol $unisymbol] # [$special \_\:\"\']
|
||||
|
||||
$large = [A-Z \xc0-\xd6 \xd8-\xde]
|
||||
$small = [a-z \xdf-\xf6 \xf8-\xff \_]
|
||||
$alpha = [$small $large]
|
||||
|
||||
$graphic = [$small $large $symbol $digit $special \:\"\']
|
||||
|
||||
$octit = 0-7
|
||||
$hexit = [0-9 A-F a-f]
|
||||
$namechar = [$alpha $digit \' \#]
|
||||
$symchar = [$symbol \:]
|
||||
$nl = [\n\r]
|
||||
$white_no_nl = $white # $nl
|
||||
|
||||
@reservedid =
|
||||
case|data|do|import|in|let|letrec|module|of|where
|
||||
|
||||
@reservedop =
|
||||
"=" | \\ | "->"
|
||||
|
||||
@varname = $small $namechar*
|
||||
@conname = $large $namechar*
|
||||
@varsym = $symbol $symchar*
|
||||
@consym = \: $symchar*
|
||||
|
||||
@decimal = $digit+
|
||||
|
||||
rlp :-
|
||||
|
||||
-- everywhere: skip whitespace
|
||||
$white_no_nl+ { skip }
|
||||
|
||||
-- TODO: `--` could begin an operator
|
||||
"--"[^$nl]* { skip }
|
||||
"--"\-*[^$symbol].* { skip }
|
||||
|
||||
"{-" { nestedComment }
|
||||
|
||||
-- syntactic symbols
|
||||
<0>
|
||||
{
|
||||
"(" { constTok TokenLParen }
|
||||
")" { constTok TokenRParen }
|
||||
"{" { lbrace }
|
||||
"}" { rbrace }
|
||||
";" { constTok TokenSemicolon }
|
||||
"," { constTok TokenComma }
|
||||
}
|
||||
|
||||
-- keywords
|
||||
-- see commentary on the layout system
|
||||
<0>
|
||||
{
|
||||
"let" { constTok TokenLet `andBegin` layout }
|
||||
"letrec" { constTok TokenLetrec `andBegin` layout }
|
||||
"of" { constTok TokenOf `andBegin` layout }
|
||||
"case" { constTok TokenCase }
|
||||
"module" { constTok TokenModule }
|
||||
"in" { letin }
|
||||
"where" { constTok TokenWhere `andBegin` layout }
|
||||
}
|
||||
|
||||
-- reserved symbols
|
||||
<0>
|
||||
{
|
||||
"=" { constTok TokenEquals }
|
||||
"->" { constTok TokenArrow }
|
||||
}
|
||||
|
||||
-- identifiers
|
||||
<0>
|
||||
{
|
||||
-- TODO: qualified names
|
||||
@varname { lexWith TokenVarName }
|
||||
@conname { lexWith TokenConName }
|
||||
@varsym { lexWith TokenVarSym }
|
||||
}
|
||||
|
||||
-- literals
|
||||
<0>
|
||||
{
|
||||
@decimal { lexWith (TokenLitInt . read @Int) }
|
||||
}
|
||||
|
||||
<0> \n { begin bol }
|
||||
|
||||
<initial>
|
||||
{
|
||||
$white { skip }
|
||||
\n { skip }
|
||||
() { topLevelOff `andBegin` 0 }
|
||||
}
|
||||
|
||||
<bol>
|
||||
{
|
||||
\n { skip }
|
||||
() { doBol `andBegin` 0 }
|
||||
}
|
||||
|
||||
<layout>
|
||||
{
|
||||
$white { skip }
|
||||
\{ { lbrace `andBegin` 0 }
|
||||
() { noBrace `andBegin` 0 }
|
||||
}
|
||||
|
||||
{
|
||||
data Located a = Located Int Int Int a
|
||||
deriving Show
|
||||
|
||||
constTok :: t -> AlexInput -> Int -> Alex (Located t)
|
||||
constTok t (AlexPn _ y x,_,_,_) l = pure $ Located y x l t
|
||||
|
||||
data CoreToken = TokenLet
|
||||
| TokenLetrec
|
||||
| TokenIn
|
||||
| TokenModule
|
||||
| TokenWhere
|
||||
| TokenComma
|
||||
| TokenCase
|
||||
| TokenOf
|
||||
| TokenLambda
|
||||
| TokenArrow
|
||||
| TokenLitInt Int
|
||||
| TokenVarName Name
|
||||
| TokenConName Name
|
||||
| TokenVarSym Name
|
||||
| TokenConSym Name
|
||||
| TokenEquals
|
||||
| TokenLParen
|
||||
| TokenRParen
|
||||
| TokenLBrace
|
||||
| TokenRBrace
|
||||
| TokenLBraceV -- virtual brace inserted by layout
|
||||
| TokenRBraceV -- virtual brace inserted by layout
|
||||
| TokenIndent Int
|
||||
| TokenDedent Int
|
||||
| TokenSemicolon
|
||||
| TokenEOF
|
||||
deriving Show
|
||||
|
||||
data LayoutContext = Layout Int
|
||||
| NoLayout
|
||||
deriving Show
|
||||
|
||||
data AlexUserState = AlexUserState
|
||||
{ _ausContext :: [LayoutContext]
|
||||
}
|
||||
|
||||
ausContext :: Lens' AlexUserState [LayoutContext]
|
||||
ausContext f (AlexUserState ctx)
|
||||
= fmap
|
||||
(\a -> AlexUserState a) (f ctx)
|
||||
{-# INLINE ausContext #-}
|
||||
|
||||
pushContext :: LayoutContext -> Alex ()
|
||||
pushContext c = do
|
||||
st <- alexGetUserState
|
||||
alexSetUserState $ st { _ausContext = c : _ausContext st }
|
||||
|
||||
popContext :: Alex ()
|
||||
popContext = do
|
||||
st <- alexGetUserState
|
||||
alexSetUserState $ st { _ausContext = drop 1 (_ausContext st) }
|
||||
|
||||
getContext :: Alex [LayoutContext]
|
||||
getContext = do
|
||||
st <- alexGetUserState
|
||||
pure $ _ausContext st
|
||||
|
||||
type Lexer = AlexInput -> Int -> Alex (Located CoreToken)
|
||||
|
||||
alexInitUserState :: AlexUserState
|
||||
alexInitUserState = AlexUserState []
|
||||
|
||||
nestedComment :: Lexer
|
||||
nestedComment _ _ = undefined
|
||||
|
||||
lexStream :: Alex [Located CoreToken]
|
||||
lexStream = do
|
||||
l <- alexMonadScan
|
||||
case l of
|
||||
Located _ _ _ TokenEOF -> pure [l]
|
||||
_ -> (l:) <$> lexStream
|
||||
|
||||
-- | The main lexer driver.
|
||||
lexCore :: String -> RLPC ParseError [Located CoreToken]
|
||||
lexCore s = case m of
|
||||
Left e -> addFatal err
|
||||
where err = SrcError
|
||||
{ _errSpan = (0,0,0) -- TODO: location
|
||||
, _errSeverity = Error
|
||||
, _errDiagnostic = ParErrLexical e
|
||||
}
|
||||
Right ts -> pure ts
|
||||
where
|
||||
m = runAlex s (alexSetStartCode initial *> lexStream)
|
||||
|
||||
-- | @lexCore@, but the tokens are stripped of location info. Useful for
|
||||
-- debugging
|
||||
lexCore' :: String -> RLPC ParseError [CoreToken]
|
||||
lexCore' s = fmap f <$> lexCore s
|
||||
where f (Located _ _ _ t) = t
|
||||
|
||||
data ParseError = ParErrLexical String
|
||||
| ParErrParse
|
||||
deriving Show
|
||||
|
||||
lexWith :: (String -> CoreToken) -> Lexer
|
||||
lexWith f (AlexPn _ y x,_,_,s) l = pure $ Located y x l (f $ take l s)
|
||||
|
||||
lexToken :: Alex (Located CoreToken)
|
||||
lexToken = alexMonadScan
|
||||
|
||||
getSrcCol :: Alex Int
|
||||
getSrcCol = Alex $ \ st ->
|
||||
let AlexPn _ _ col = alex_pos st
|
||||
in Right (st, col)
|
||||
|
||||
lbrace :: Lexer
|
||||
lbrace (AlexPn _ y x,_,_,_) l = do
|
||||
pushContext NoLayout
|
||||
pure $ Located y x l TokenLBrace
|
||||
|
||||
rbrace :: Lexer
|
||||
rbrace (AlexPn _ y x,_,_,_) l = do
|
||||
popContext
|
||||
pure $ Located y x l TokenRBrace
|
||||
|
||||
insRBraceV :: AlexPosn -> Alex (Located CoreToken)
|
||||
insRBraceV (AlexPn _ y x) = do
|
||||
popContext
|
||||
pure $ Located y x 0 TokenRBraceV
|
||||
|
||||
insSemi :: AlexPosn -> Alex (Located CoreToken)
|
||||
insSemi (AlexPn _ y x) = do
|
||||
pure $ Located y x 0 TokenSemicolon
|
||||
|
||||
modifyUst :: (AlexUserState -> AlexUserState) -> Alex ()
|
||||
modifyUst f = do
|
||||
st <- alexGetUserState
|
||||
alexSetUserState $ f st
|
||||
|
||||
getUst :: Alex AlexUserState
|
||||
getUst = alexGetUserState
|
||||
|
||||
newLayoutContext :: Lexer
|
||||
newLayoutContext (p,_,_,_) _ = do
|
||||
undefined
|
||||
|
||||
noBrace :: Lexer
|
||||
noBrace (AlexPn _ y x,_,_,_) l = do
|
||||
col <- getSrcCol
|
||||
pushContext (Layout col)
|
||||
pure $ Located y x l TokenLBraceV
|
||||
|
||||
getOffside :: Alex Ordering
|
||||
getOffside = do
|
||||
ctx <- getContext
|
||||
m <- getSrcCol
|
||||
case ctx of
|
||||
Layout n : _ -> pure $ m `compare` n
|
||||
_ -> pure GT
|
||||
|
||||
doBol :: Lexer
|
||||
doBol (p,c,_,s) _ = do
|
||||
off <- getOffside
|
||||
case off of
|
||||
LT -> insRBraceV p
|
||||
EQ -> insSemi p
|
||||
_ -> lexToken
|
||||
|
||||
letin :: Lexer
|
||||
letin (AlexPn _ y x,_,_,_) l = do
|
||||
popContext
|
||||
pure $ Located y x l TokenIn
|
||||
|
||||
topLevelOff :: Lexer
|
||||
topLevelOff = noBrace
|
||||
|
||||
alexEOF :: Alex (Located CoreToken)
|
||||
alexEOF = Alex $ \ st@(AlexState { alex_pos = AlexPn _ y x }) ->
|
||||
Right (st, Located y x 0 TokenEOF)
|
||||
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
{
|
||||
module Core.Parse
|
||||
( parseCore
|
||||
, parseCoreExpr
|
||||
, parseCoreProg
|
||||
, module Core.Lex -- temp convenience
|
||||
, parseTmp
|
||||
, SrcError
|
||||
, ParseError
|
||||
, Module
|
||||
)
|
||||
where
|
||||
|
||||
import Control.Monad ((>=>))
|
||||
import Data.Foldable (foldl')
|
||||
import Core.Syntax
|
||||
import Core.Lex
|
||||
import Compiler.RLPC
|
||||
import Data.Default.Class (def)
|
||||
}
|
||||
|
||||
%name parseCore Module
|
||||
%name parseCoreExpr StandaloneExpr
|
||||
%name parseCoreProg StandaloneProgram
|
||||
%tokentype { Located CoreToken }
|
||||
%error { parseError }
|
||||
%monad { RLPC ParseError }
|
||||
|
||||
%token
|
||||
let { Located _ _ _ TokenLet }
|
||||
letrec { Located _ _ _ TokenLetrec }
|
||||
module { Located _ _ _ TokenModule }
|
||||
where { Located _ _ _ TokenWhere }
|
||||
',' { Located _ _ _ TokenComma }
|
||||
in { Located _ _ _ TokenIn }
|
||||
litint { Located _ _ _ (TokenLitInt $$) }
|
||||
varname { Located _ _ _ (TokenVarName $$) }
|
||||
varsym { Located _ _ _ (TokenVarSym $$) }
|
||||
conname { Located _ _ _ (TokenConName $$) }
|
||||
consym { Located _ _ _ (TokenConSym $$) }
|
||||
'λ' { Located _ _ _ TokenLambda }
|
||||
'->' { Located _ _ _ TokenArrow }
|
||||
'=' { Located _ _ _ TokenEquals }
|
||||
'(' { Located _ _ _ TokenLParen }
|
||||
')' { Located _ _ _ TokenRParen }
|
||||
'{' { Located _ _ _ TokenLBrace }
|
||||
'}' { Located _ _ _ TokenRBrace }
|
||||
vl { Located _ _ _ TokenLBraceV }
|
||||
vr { Located _ _ _ TokenRBraceV }
|
||||
';' { Located _ _ _ TokenSemicolon }
|
||||
eof { Located _ _ _ TokenEOF }
|
||||
|
||||
%%
|
||||
|
||||
Module :: { Module }
|
||||
Module : module conname where Program Eof { Module (Just ($2, [])) $4 }
|
||||
| Program Eof { Module Nothing $1 }
|
||||
|
||||
Eof :: { () }
|
||||
Eof : eof { () }
|
||||
| error { () }
|
||||
|
||||
StandaloneProgram :: { Program }
|
||||
StandaloneProgram : Program eof { $1 }
|
||||
|
||||
Program :: { Program }
|
||||
Program : VOpen ScDefs VClose { Program $2 }
|
||||
| '{' ScDefs '}' { Program $2 }
|
||||
|
||||
VOpen :: { () }
|
||||
VOpen : vl { () }
|
||||
|
||||
VClose :: { () }
|
||||
VClose : vr { () }
|
||||
| error { () }
|
||||
|
||||
ScDefs :: { [ScDef] }
|
||||
ScDefs : ScDef ';' ScDefs { $1 : $3 }
|
||||
| {- epsilon -} { [] }
|
||||
|
||||
ScDef :: { ScDef }
|
||||
ScDef : Var ParList '=' Expr { ScDef $1 $2 $4 }
|
||||
|
||||
ParList :: { [Name] }
|
||||
ParList : Var ParList { $1 : $2 }
|
||||
| {- epsilon -} { [] }
|
||||
|
||||
StandaloneExpr :: { Expr }
|
||||
StandaloneExpr : Expr eof { $1 }
|
||||
|
||||
Expr :: { Expr }
|
||||
Expr : LetExpr { $1 }
|
||||
| 'λ' Binders '->' Expr { Lam $2 $4 }
|
||||
| Application { $1 }
|
||||
| Expr1 { $1 }
|
||||
|
||||
LetExpr :: { Expr }
|
||||
LetExpr : let VOpen Bindings VClose in Expr { Let NonRec $3 $6 }
|
||||
| letrec VOpen Bindings VClose in Expr { Let Rec $3 $6 }
|
||||
| let '{' Bindings '}' in Expr { Let NonRec $3 $6 }
|
||||
| letrec '{' Bindings '}' in Expr { Let Rec $3 $6 }
|
||||
|
||||
Binders :: { [Name] }
|
||||
Binders : Var Binders { $1 : $2 }
|
||||
| Var { [$1] }
|
||||
|
||||
Application :: { Expr }
|
||||
Application : Expr1 AppArgs { foldl' App $1 $2 }
|
||||
|
||||
-- TODO: Application can probably be written as a single rule, without AppArgs
|
||||
AppArgs :: { [Expr] }
|
||||
AppArgs : Expr1 AppArgs { $1 : $2 }
|
||||
| Expr1 { [$1] }
|
||||
|
||||
Expr1 :: { Expr }
|
||||
Expr1 : litint { IntE $1 }
|
||||
| Id { Var $1 }
|
||||
| '(' Expr ')' { $2 }
|
||||
|
||||
Bindings :: { [Binding] }
|
||||
Bindings : Binding ';' Bindings { $1 : $3 }
|
||||
| Binding ';' { [$1] }
|
||||
| Binding { [$1] }
|
||||
|
||||
Binding :: { Binding }
|
||||
Binding : Var '=' Expr { $1 := $3 }
|
||||
|
||||
Id :: { Name }
|
||||
Id : Var { $1 }
|
||||
| Con { $1 }
|
||||
|
||||
Var :: { Name }
|
||||
Var : '(' varsym ')' { $2 }
|
||||
| varname { $1 }
|
||||
|
||||
Con :: { Name }
|
||||
Con : '(' consym ')' { $2 }
|
||||
| conname { $1 }
|
||||
|
||||
{
|
||||
parseError :: [Located CoreToken] -> RLPC ParseError a
|
||||
parseError (Located y x l _ : _) = addFatal err
|
||||
where err = SrcError
|
||||
{ _errSpan = (y,x,l)
|
||||
, _errSeverity = Error
|
||||
, _errDiagnostic = ParErrParse
|
||||
}
|
||||
|
||||
parseTmp :: IO Module
|
||||
parseTmp = do
|
||||
s <- readFile "/tmp/t.hs"
|
||||
case parse s of
|
||||
Left e -> error (show e)
|
||||
Right (ts,_) -> pure ts
|
||||
where
|
||||
parse = evalRLPC def . (lexCore >=> parseCore)
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user