add first-class functions to brush language

This commit is contained in:
sheaf 2021-05-25 13:45:21 +02:00
parent 5ff935b4b2
commit eba08a6edd
8 changed files with 190 additions and 149 deletions

View file

@ -102,7 +102,7 @@ import Math.Vector2D
import MetaBrush.Action import MetaBrush.Action
( ActionOrigin(..) ) ( ActionOrigin(..) )
import qualified MetaBrush.Asset.Brushes as Asset.Brushes import qualified MetaBrush.Asset.Brushes as Asset.Brushes
( circle ) ( EllipseBrushFields, ellipse )
import MetaBrush.Asset.Colours import MetaBrush.Asset.Colours
( getColours ) ( getColours )
import MetaBrush.Asset.Logo import MetaBrush.Asset.Logo
@ -164,7 +164,7 @@ runApplication application = do
uniqueSupply <- newUniqueSupply uniqueSupply <- newUniqueSupply
circleBrush <- Asset.Brushes.circle uniqueSupply ellipseBrush <- Asset.Brushes.ellipse uniqueSupply
docUnique <- runReaderT freshUnique uniqueSupply docUnique <- runReaderT freshUnique uniqueSupply
strokeUnique <- runReaderT freshUnique uniqueSupply strokeUnique <- runReaderT freshUnique uniqueSupply
@ -179,14 +179,14 @@ runApplication application = do
{ strokeName = "Stroke 1" { strokeName = "Stroke 1"
, strokeVisible = True , strokeVisible = True
, strokeUnique = strokeUnique , strokeUnique = strokeUnique
, strokeBrush = Just $ adaptBrush @'[ "r" SuperRecord.:= Double ] circleBrush , strokeBrush = Just $ adaptBrush @Asset.Brushes.EllipseBrushFields ellipseBrush
, strokeSpline = , strokeSpline =
Spline Spline
{ splineStart = mkPoint ( Point2D 10 -20 ) 2 { splineStart = mkPoint ( Point2D 10 -20 ) 2 1 0
, splineCurves = OpenCurves $ Seq.fromList , splineCurves = OpenCurves $ Seq.fromList
[ LineTo { curveEnd = NextPoint ( mkPoint ( Point2D 10 10 ) 10 ), curveData = invalidateCache undefined } [ LineTo { curveEnd = NextPoint ( mkPoint ( Point2D 10 10 ) 10 5 ( pi / 4 ) ), curveData = invalidateCache undefined }
, LineTo { curveEnd = NextPoint ( mkPoint ( Point2D -10 10 ) 5 ), curveData = invalidateCache undefined } , LineTo { curveEnd = NextPoint ( mkPoint ( Point2D -10 10 ) 8 5 ( pi / 4 ) ), curveData = invalidateCache undefined }
, LineTo { curveEnd = NextPoint ( mkPoint ( Point2D -10 -20 ) 15 ), curveData = invalidateCache undefined } , LineTo { curveEnd = NextPoint ( mkPoint ( Point2D -10 -20 ) 10 7 ( pi / 2 ) ), curveData = invalidateCache undefined }
] ]
} }
} }
@ -194,8 +194,9 @@ runApplication application = do
) )
] ]
where where
mkPoint :: Point2D Double -> Double -> PointData ( Super.Rec '[ "r" SuperRecord.:= Double ] ) mkPoint :: Point2D Double -> Double -> Double -> Double -> PointData ( Super.Rec Asset.Brushes.EllipseBrushFields )
mkPoint pt r = PointData pt Normal ( #r SuperRecord.:= r SuperRecord.& SuperRecord.rnil ) mkPoint pt a b phi = PointData pt Normal
( #a SuperRecord.:= a SuperRecord.& #b SuperRecord.:= b SuperRecord.& #phi SuperRecord.:= phi SuperRecord.& SuperRecord.rnil )
recomputeStrokesTVar <- STM.newTVarIO @Bool False recomputeStrokesTVar <- STM.newTVarIO @Bool False
documentRenderTVar <- STM.newTVarIO @( ( Int32, Int32 ) -> Cairo.Render () ) ( const $ pure () ) documentRenderTVar <- STM.newTVarIO @( ( Int32, Int32 ) -> Cairo.Render () ) ( const $ pure () )

View file

@ -39,11 +39,10 @@ import MetaBrush.Unique
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
circle type CircleBrushFields = '[ "r" SuperRecord.:= Double ]
:: forall circleBrushFields
. ( circleBrushFields ~ '[ "r" SuperRecord.:= Double ] ) circle :: UniqueSupply -> IO ( Brush CircleBrushFields )
=> UniqueSupply -> IO ( Brush circleBrushFields ) circle uniqueSupply = mkBrush @CircleBrushFields uniqueSupply name code
circle uniqueSupply = mkBrush @circleBrushFields uniqueSupply name code
where where
name, code :: Text name, code :: Text
name = "Circle" name = "Circle"
@ -59,11 +58,8 @@ circle uniqueSupply = mkBrush @circleBrushFields uniqueSupply name code
\ -- (-r ,-r*c) -- (-r*c,-r ) -> ( 0,-r)\n\ \ -- (-r ,-r*c) -- (-r*c,-r ) -> ( 0,-r)\n\
\ -- ( r*c,-r ) -- ( r ,-r*c) -> . ]" \ -- ( r*c,-r ) -- ( r ,-r*c) -> . ]"
circleCW circleCW :: UniqueSupply -> IO ( Brush CircleBrushFields )
:: forall circleBrushFields circleCW uniqueSupply = mkBrush @CircleBrushFields uniqueSupply name code
. ( circleBrushFields ~ '[ "r" SuperRecord.:= Double ] )
=> UniqueSupply -> IO ( Brush circleBrushFields )
circleCW uniqueSupply = mkBrush @circleBrushFields uniqueSupply name code
where where
name, code :: Text name, code :: Text
name = "Circle CW" name = "Circle CW"
@ -79,6 +75,31 @@ circleCW uniqueSupply = mkBrush @circleBrushFields uniqueSupply name code
\ -- (-r , r*c) -- (-r*c, r ) -> ( 0, r)\n\ \ -- (-r , r*c) -- (-r*c, r ) -> ( 0, r)\n\
\ -- ( r*c, r ) -- ( r , r*c) -> . ]" \ -- ( r*c, r ) -- ( r , r*c) -> . ]"
type EllipseBrushFields = '[ "a" SuperRecord.:= Double, "b" SuperRecord.:= Double, "phi" SuperRecord.:= Double ]
ellipse :: UniqueSupply -> IO ( Brush EllipseBrushFields )
ellipse uniqueSupply = mkBrush @EllipseBrushFields uniqueSupply name code
where
name, code :: Text
name = "Ellipse"
code =
"with\n\
\ a = 1\n\
\ b = 1\n\
\ phi = 0\n\
\satisfying\n\
\ a > 0 && b > 0\n\
\define\n\
\ let\n\
\ c = kappa\n\
\ applyRotation pt = rotate pt CCW by phi\n\
\ in\n\
\ map applyRotation over\n\
\ [ (a,0) -- ( a , b*c) -- ( a*c, b ) -> ( 0, b)\n\
\ -- (-a*c, b ) -- (-a , b*c) -> (-a, 0)\n\
\ -- (-a ,-b*c) -- (-a*c,-b ) -> ( 0,-b)\n\
\ -- ( a*c,-b ) -- ( a ,-b*c) -> . ]"
{- {-
rounded rounded
:: forall roundedBrushFields :: forall roundedBrushFields

View file

@ -370,9 +370,18 @@ data Term ( p :: Pass ) ( kind :: K p ) where
CExt :: !( X_Ext p ( T p a ) ) -> Term p ( T p a ) CExt :: !( X_Ext p ( T p a ) ) -> Term p ( T p a )
data Decl ( p :: Pass ) where data Decl ( p :: Pass ) where
Decl :: C p ( STypeI a ) ValDecl
=> !( Loc p () ) :: C p ( STypeI a )
-> !( Pat p ( T p a ) ) -> !( Term p ( T p a ) ) => !( Pat p ( T p a ) )
-> !( Loc p () )
-> !( Term p ( T p a ) )
-> Decl p
FunDecl
:: ( C p ( STypeI a ), C p ( STypeI b ) )
=> !( Loc p ( Name p ) )
-> !( Pat p ( T p a ) )
-> !( Loc p () )
-> !( Term p ( T p b ) )
-> Decl p -> Decl p
data Pat ( p :: Pass ) ( kind :: K p ) where data Pat ( p :: Pass ) ( kind :: K p ) where
@ -617,7 +626,8 @@ toTreeDecl
. ( Show ( Name p ), forall x. Ext p x, forall (kvs :: Ks p). Ext_With p kvs ) . ( Show ( Name p ), forall x. Ext p x, forall (kvs :: Ks p). Ext_With p kvs )
=> Decl p => Decl p
-> Tree String -> Tree String
toTreeDecl ( Decl _ lhs rhs ) = Node "(=)" [ toTreePat lhs, toTreeTerm rhs ] toTreeDecl ( ValDecl lhs _ rhs ) = Node "(=)" [ toTreePat lhs, toTreeTerm rhs ]
toTreeDecl ( FunDecl nm arg _ rhs ) = Node "(=)" [ Node ( show nm ) [ toTreePat arg ], toTreeTerm rhs ]
toTreePat :: Show ( Name p ) => Pat p a -> Tree String toTreePat :: Show ( Name p ) => Pat p a -> Tree String
toTreePat ( PName nm ) = Node ( show nm ) [ ] toTreePat ( PName nm ) = Node ( show nm ) [ ]

View file

@ -6,6 +6,7 @@
{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-} {-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
@ -20,7 +21,7 @@ module MetaBrush.MetaParameter.Eval
-- base -- base
import Data.Foldable import Data.Foldable
( for_ ) ( for_, traverse_ )
import Data.Functor.Compose import Data.Functor.Compose
( Compose(..) ) ( Compose(..) )
import Data.Type.Equality import Data.Type.Equality
@ -107,7 +108,7 @@ eval ( PolyBez _ spline ) =
( const $ bitraverseCurve ( const $ pure () ) ( const eval ) ) ( const $ bitraverseCurve ( const $ pure () ) ( const eval ) )
eval eval
spline spline
eval ( Let _ decls a ) = declare decls *> eval a eval ( Let _ decls a ) = traverse_ declare decls *> eval a
eval ( With _ ( Tc_With ( withDeclsRecord :: Super.Rec ( MapFields UniqueTerm brushFields ) ) ) _ ( body :: Term Tc r ) ) = do eval ( With _ ( Tc_With ( withDeclsRecord :: Super.Rec ( MapFields UniqueTerm brushFields ) ) ) _ ( body :: Term Tc r ) ) = do
defaultParamsRecord <- defaultParamsRecord <-
SuperRecord.traverseC @IsUniqueTerm2 @( State EvalState ) @( MapFields UniqueTerm brushFields ) @( MapFields UniqueField brushFields ) SuperRecord.traverseC @IsUniqueTerm2 @( State EvalState ) @( MapFields UniqueTerm brushFields ) @( MapFields UniqueField brushFields )
@ -154,16 +155,18 @@ eval ( Var var@( Located _ ( UniqueName _ varUniq ) ) ) = do
) )
eval ( CExt ( Val v ) ) = pure v eval ( CExt ( Val v ) ) = pure v
declare :: [ Decl Tc ] -> State EvalState () declare :: Decl Tc -> State EvalState ( Maybe UniqueName )
declare [] = pure () declare ( ValDecl pat _ t ) =
declare ( Decl _ pat t : next ) = go pat t *> declare next declareVal pat t
where declare ( FunDecl ( Located { located = nm } ) args _ t ) =
go :: forall a. STypeI a => Pat Tc a -> Term Tc a -> State EvalState ( Maybe UniqueName ) Just <$> declareFun nm args t
go ( PName ( Located _ patUniqName@( UniqueName _ patUniq ) ) ) r = do
declareVal :: forall a. STypeI a => Pat Tc a -> Term Tc a -> State EvalState ( Maybe UniqueName )
declareVal ( PName ( Located { located = patUniqName@( UniqueName { nameUnique = patUniq } ) } ) ) r = do
modifying ( field' @"evalHeap" ) modifying ( field' @"evalHeap" )
( Map.insert patUniq $ TypedTerm r ) ( Map.insert patUniq $ TypedTerm r )
pure ( Just patUniqName ) pure ( Just patUniqName )
go ( PPoint _ lpat rpat ) r = do declareVal ( PPoint _ lpat rpat ) r = do
case sTypeI @a of case sTypeI @a of
sTyPoint@STyPoint sTyPoint@STyPoint
| ( _ :: SType ( Point2D x ) ) <- sTyPoint | ( _ :: SType ( Point2D x ) ) <- sTyPoint
@ -194,16 +197,30 @@ declare ( Decl _ pat t : next ) = go pat t *> declare next
, ( uniq3, TypedTerm $ ( Op @( a -> x ) [] "snd" ( \ ~( Point2D _ y ) -> y ) ) :$ r ) , ( uniq3, TypedTerm $ ( Op @( a -> x ) [] "snd" ( \ ~( Point2D _ y ) -> y ) ) :$ r )
] ]
) )
go lpat var_l _ <- declareVal lpat var_l
go rpat var_r _ <- declareVal rpat var_r
pure ( Just pairName ) pure ( Just pairName )
go ( AsPat _ ( Located _ asUniqName@( UniqueName _ asUniq ) ) patt ) r = do declareVal ( AsPat _ ( Located { located = asUniqName@( UniqueName { nameUnique = asUniq } ) } ) patt ) r = do
mbNm <- go patt r mbNm <- declareVal patt r
for_ mbNm \ nm -> for_ mbNm \ nm ->
modifying ( field' @"evalHeap" ) modifying ( field' @"evalHeap" )
( Map.insert asUniq ( TypedTerm $ Var @Tc @a ( Located noSpan nm ) ) ) ( Map.insert asUniq ( TypedTerm $ Var @Tc @a ( Located noSpan nm ) ) )
pure ( Just asUniqName ) pure ( Just asUniqName )
go ( PWild _ ) _ = pure Nothing declareVal ( PWild _ ) _ = pure Nothing
declareFun
:: forall a b. ( STypeI a, STypeI b )
=> UniqueName -> Pat Tc a -> Term Tc b -> State EvalState UniqueName
declareFun uniq@( UniqueName { nameUnique = funUnique } ) argPat rhs = do
st <- get
let
fun :: a -> b
fun arg = ( `evalState` st ) do
_ <- declareVal argPat ( CExt @Tc @a ( Val arg ) )
eval rhs
modifying ( field' @"evalHeap" )
( Map.insert funUnique ( TypedTerm $ CExt @Tc @( a -> b ) ( Val fun ) ) )
pure uniq
bindRecordValues bindRecordValues
:: forall brushFields usedFields defaultFields :: forall brushFields usedFields defaultFields

View file

@ -80,6 +80,7 @@ import MetaBrush.MetaParameter.PrimOp
, scale_around_by, scale_by , scale_around_by, scale_by
, shear_from_by, shear_by , shear_from_by, shear_by
, translate_by , translate_by
, map_over
) )
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -101,61 +102,6 @@ showParses x = do
tree = toTreeTerm expr tree = toTreeTerm expr
drawTree tree drawTree tree
examples :: [ Located Token ] -> Int -> IO ()
examples inputToks n =
for_ ( Earley.exactly n ( Earley.generator grammar inputToks ) ) \ ( expr, toks ) -> do
for_ toks ( located >>> showToken >>> ( <> " " ) >>> putStr )
putStrLn ""
drawTree ( toTreeTerm expr )
putStrLn "\n\n"
someToks :: [ Located Token ]
someToks = map ( Located mempty )
[ TokAlphabetic "x"
, TokAlphabetic "let"
, TokAlphabetic "in"
, TokSpecial '['
, TokSpecial ']'
, TokSpecial '('
, TokSpecial ')'
, TokSymbolic "="
, TokSymbolic "--"
, TokSymbolic "->"
, TokSymbolic "."
]
test1 :: Text
test1 =
" let\n\
\ q = rotate p around c CW by theta + 3 * theta2\n\
\ r = scale ( translate q by t ) by (7,11)\n\
\ in rotate q around p CW by phi"
test2 :: Text
test2 =
" let\n\
\ p = (3,3)\n\
\ q = (1,1)\n\
\ in\n\
\ rotate p\n\
\ around q\n\
\ CCW by\n\
\ let\n\
\ q = pi / 2 \n\
\ in q"
test3 :: Text
test3 =
" let\n\
\ p = (1,1)\n\
\ in\n\
\ [ p -- c1 -- c2 -> q\n\
\ -- c3 -- c4 -> r\n\
\ -> s -> .\n\
\ ]"
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Language grammar. -- Language grammar.
@ -227,14 +173,24 @@ grammar = mdo
anyPattern <- Earley.rule ( ( basicPattern <|> asPattern ) <?> "pattern" ) anyPattern <- Earley.rule ( ( basicPattern <|> asPattern ) <?> "pattern" )
declaration <- declaration <-
Earley.rule Earley.rule $
( do ( do
p <- anyPattern funName <- alphabeticName
anyWhitespace
argPat <- anyPattern
anyWhitespace anyWhitespace
eqLoc <- symbol "=" eqLoc <- symbol "="
e <- expr rhs <- expr
pure ( Location ( location eqLoc ), p, e ) pure ( FunDecl funName argPat ( Location ( location eqLoc ) ) rhs )
<?> "declaration" <?> "function declaration"
) <|>
( do
lhs <- anyPattern
anyWhitespace
eqLoc <- symbol "="
rhs <- expr
pure ( ValDecl lhs ( Location ( location eqLoc ) ) rhs )
<?> "variable declaration"
) )
moreDeclarations <- Earley.rule moreDeclarations <- Earley.rule
@ -242,7 +198,7 @@ grammar = mdo
separator separator
decl <- declaration decl <- declaration
more <- moreDeclarations more <- moreDeclarations
pure $ ( \ ( l, p, e ) -> Decl l p e : more ) decl pure ( decl : more )
<|> pure [] <|> pure []
) )
@ -251,7 +207,7 @@ grammar = mdo
( do ( do
decl <- declaration decl <- declaration
more <- moreDeclarations more <- moreDeclarations
pure $ ( \ ( l, p, e ) -> Decl l p e : more ) decl pure ( decl : more )
<|> pure [] <|> pure []
) )
@ -361,6 +317,7 @@ reserved
[ "let", "in" [ "let", "in"
, "with", "set", "satisfying" , "with", "set", "satisfying"
, "around", "by", "rotate", "scale", "shear", "translate", "transform" , "around", "by", "rotate", "scale", "shear", "translate", "transform"
, "map", "over"
, "cw", "ccw" , "cw", "ccw"
, "pi", "tau", "kappa" , "pi", "tau", "kappa"
] ]
@ -520,6 +477,13 @@ mixfixTable
"translate_by_" translate_by "translate_by_" translate_by
:$ p :$ t :$ p :$ t
) )
, ( [ Just $ ws_tokAlpha "map", Nothing, Just $ ws_tokAlpha "over", Nothing ]
, Earley.NonAssoc
, \ [ Just ( Located lt _ ), _, Just ( Located lb _ ), _ ] [ f, v ] ->
Op [ Location lt, Location lb ]
"map_over_" map_over
:$ f :$ v
)
] ]
, [ ( [ Nothing, Just $ ws_tokSymbol "||", Nothing ] , [ ( [ Nothing, Just $ ws_tokSymbol "||", Nothing ]
, Earley.RightAssoc , Earley.RightAssoc

View file

@ -1,8 +1,11 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE DerivingStrategies #-}
module MetaBrush.MetaParameter.PrimOp where module MetaBrush.MetaParameter.PrimOp where
-- MetaBrush -- MetaBrush
import Math.Bezier.Spline
( SplineType(Closed), SplinePts )
import Math.Vector2D import Math.Vector2D
( Point2D(..) ) ( Point2D(..) )
@ -40,3 +43,6 @@ shear_by ( Point2D px py ) ( Point2D vx vy ) = undefined
translate_by :: Point2D Double -> Point2D Double -> Point2D Double translate_by :: Point2D Double -> Point2D Double -> Point2D Double
translate_by ( Point2D px py ) ( Point2D tx ty ) = Point2D ( px + tx ) ( py + ty ) translate_by ( Point2D px py ) ( Point2D tx ty ) = Point2D ( px + tx ) ( py + ty )
map_over :: ( Point2D Double -> Point2D Double ) -> ( SplinePts Closed -> SplinePts Closed )
map_over = fmap

View file

@ -117,13 +117,22 @@ renameDecls decls = do
where where
go :: Map Text Unique -> [ Decl P ] -> m [ Decl Rn ] go :: Map Text Unique -> [ Decl P ] -> m [ Decl Rn ]
go outerLocalVars ( Decl loc lhs rhs : next ) = do go outerLocalVars ( ValDecl lhs eqLoc rhs : next ) = do
-- Collect all the declarations from the left-hand sides. -- Collect all the declarations from the left-hand sides.
lhs' <- renameLhs outerLocalVars lhs lhs' <- renameLhs outerLocalVars lhs
next' <- go outerLocalVars next next' <- go outerLocalVars next
-- Now rename each right-hand side with the full LHS info. -- Now rename the right-hand side with the full LHS info.
rhs' <- locally ( rename rhs ) rhs' <- locally ( rename rhs )
pure $ Decl loc lhs' rhs' : next' pure $ ValDecl lhs' eqLoc rhs' : next'
go outerLocalVars ( FunDecl funName argPat eqLoc rhs : next ) = do
-- Collect all the declarations from the left-hand sides.
funName' <- patName <$> renameLhs outerLocalVars ( PName funName )
next' <- go outerLocalVars next
-- Now rename the right-hand side with the full LHS info,
-- taking care to bring into scope the names bound by the function
-- when renaming the RHS.
( lhs', rhs' ) <- locally ( (,) <$> renameLhs outerLocalVars argPat <*> rename rhs )
pure $ FunDecl funName' lhs' eqLoc rhs' : next'
go outerLocalVars [] = do go outerLocalVars [] = do
-- Finished handling all the left-hand sides: -- Finished handling all the left-hand sides:
-- add all the declared names to the existing (outer) names, -- add all the declared names to the existing (outer) names,

View file

@ -263,10 +263,20 @@ typeCheckDecls = go []
catchOutOfScope _ err = throwError err catchOutOfScope _ err = throwError err
typeCheckDecl :: MonadTc m => Decl Rn -> m ( Decl Tc ) typeCheckDecl :: MonadTc m => Decl Rn -> m ( Decl Tc )
typeCheckDecl ( Decl loc lhs rhs ) = do typeCheckDecl ( ValDecl lhs eqLoc rhs ) = do
TypedTerm ( rhs' :: Term Tc a ) <- typeCheck rhs TypedTerm ( rhs' :: Term Tc a ) <- typeCheck rhs
lhs' <- typeCheckPatAt @a lhs lhs' <- typeCheckPatAt @a lhs
pure ( Decl loc lhs' rhs' ) pure ( ValDecl lhs' eqLoc rhs' )
-- TODO: this assumes all user-declared functions are of type @ Point2D Double -> Point2D Double @.
-- A better solution would be to introduce a unification variable for the argument type,
-- and throw an error (or default) if there remain uninstantiated unification variables after typechecking the RHS.
typeCheckDecl ( FunDecl funName@( Located _ ( UniqueName _ uniq ) ) argPat eqLoc rhs ) = do
argPat' <- typeCheckPatAt @( Point2D Double ) argPat
rhs' <- typeCheckAt @( Point2D Double ) "Expected function of type `Point2D Double -> Point2D Double'" rhs
assign
( field' @"globalEnv" . field' @"tcGlobalVarTys" . at uniq )
( Just $ SomeSType ( proxy# :: Proxy# ( Point2D Double -> Point2D Double ) ) )
pure ( FunDecl funName argPat' eqLoc rhs' )
typeCheckPatAt :: forall ( a :: Type ) m. ( STypeI a, MonadTc m ) => Pat Rn '() -> m ( Pat Tc a ) typeCheckPatAt :: forall ( a :: Type ) m. ( STypeI a, MonadTc m ) => Pat Rn '() -> m ( Pat Tc a )
typeCheckPatAt ( PName nm@( Located _ ( UniqueName _ uniq ) ) ) = do typeCheckPatAt ( PName nm@( Located _ ( UniqueName _ uniq ) ) ) = do
@ -307,10 +317,11 @@ withDeclsRecord decls f = do
revSortDecls :: [ Decl Tc ] -> m [ ( Text, ( UniqueName, TypedTerm ) ) ] revSortDecls :: [ Decl Tc ] -> m [ ( Text, ( UniqueName, TypedTerm ) ) ]
revSortDecls = fmap ( sortOn ( Down . fst ) ) . traverse getDeclName revSortDecls = fmap ( sortOn ( Down . fst ) ) . traverse getDeclName
getDeclName :: Decl Tc -> m ( Text, ( UniqueName, TypedTerm ) ) getDeclName :: Decl Tc -> m ( Text, ( UniqueName, TypedTerm ) )
getDeclName ( Decl ( Located loc _ ) pat term ) = case pat of getDeclName ( ValDecl pat ( Located eqLoc _ ) term ) = case pat of
PName ( Located _ uniq@( UniqueName nm _ ) ) -> pure ( nm, ( uniq, TypedTerm term ) ) PName ( Located _ uniq@( UniqueName nm _ ) ) -> pure ( nm, ( uniq, TypedTerm term ) )
AsPat _ ( Located _ uniq@( UniqueName nm _ ) ) _ -> pure ( nm, ( uniq, TypedTerm term ) ) AsPat _ ( Located _ uniq@( UniqueName nm _ ) ) _ -> pure ( nm, ( uniq, TypedTerm term ) )
_ -> tcError $ NoPatternName loc _ -> tcError $ NoPatternName eqLoc
getDeclName ( FunDecl funName _ _ _ ) = tcError $ UnexpectedFunDecl funName
go :: TypedTermsRecord -> [ ( Text, ( UniqueName, TypedTerm ) ) ] -> TypedTermsRecord go :: TypedTermsRecord -> [ ( Text, ( UniqueName, TypedTerm ) ) ] -> TypedTermsRecord
go record [] = record go record [] = record
go ( TypedTermsRecord ( record :: Super.Rec ( MapFields UniqueTerm kvs ) ) ) go ( TypedTermsRecord ( record :: Super.Rec ( MapFields UniqueTerm kvs ) ) )
@ -413,6 +424,8 @@ data TcError
} }
| OutOfScope | OutOfScope
{ outOfScopeVar :: !( Located UniqueName ) } { outOfScopeVar :: !( Located UniqueName ) }
| UnexpectedFunDecl
{ funDeclLoc :: !( Located UniqueName ) }
deriving stock ( Show, Generic ) deriving stock ( Show, Generic )
data TcWarning = TcWarning data TcWarning = TcWarning