changes to support translation

This commit is contained in:
2024-12-30 22:34:03 -08:00
parent 8c7f0616d2
commit f4e96d06ec
10 changed files with 126 additions and 107 deletions

View File

@@ -4,8 +4,13 @@
More comments in code! This is getting big enough that I need to re-find my bearings when fixing stuff. More comments in code! This is getting big enough that I need to re-find my bearings when fixing stuff.
- [x] tokenizer that can be ported to newt - [x] tokenizer that can be ported to newt
- [ ] Add default path for library, so we don't need symlinks everywhere and can write tests for the library
- [ ] string interpolation? - [ ] string interpolation?
- The tricky part here is the `}` - I need to run the normal tokenizer in a way that treats `}` specially.
- Idris handles `putStrLn "done \{ show $ add {x=1} 2}"` - it recurses for `{` `}` pairs. Do we want that complexity?
- The mini version would be recurse on `{`, pop on `}` (and expect caller to handle), fail if we get to the top with a tokens remaining.
- [ ] mutual recursion in where? - [ ] mutual recursion in where?
- need to scan sigs and then defs, will have to make sure Compile.idr puts them all in scope before processing each.
- [x] Move on to next decl in case of error - [x] Move on to next decl in case of error
- [x] for parse error, seek to col 0 token and process next decl - [x] for parse error, seek to col 0 token and process next decl
- [ ] record update sugar, syntax TBD - [ ] record update sugar, syntax TBD
@@ -17,6 +22,7 @@ More comments in code! This is getting big enough that I need to re-find my bear
- [x] fix "insufficient patterns", wire in M or Either String - [x] fix "insufficient patterns", wire in M or Either String
- [x] Matching _,_ when Maybe is expected should be an error - [x] Matching _,_ when Maybe is expected should be an error
- [ ] There are issues with matching inside do blocks, I think we need to guess scrutinee? I could imagine constraining metas too (e.g. if Just ... at ?m123 then ?m123 =?= Maybe ?m456) - [ ] There are issues with matching inside do blocks, I think we need to guess scrutinee? I could imagine constraining metas too (e.g. if Just ... at ?m123 then ?m123 =?= Maybe ?m456)
- `newt/Fixme.newt` - I can drop `do` _and_ put `bind {IO}` to push it along. It may need to try to solve autos earlier and better.
- Also, the root cause is tough to track down if there is a type error (this happens with `do` in Idris, too). - Also, the root cause is tough to track down if there is a type error (this happens with `do` in Idris, too).
- Part of it is the auto solutions are getting discarded because of an unrelated unification failure. Either auto shouldn't go as deep or should run earlier. Forgetting that lookupMap returns a (k,v) pair is a good example. - Part of it is the auto solutions are getting discarded because of an unrelated unification failure. Either auto shouldn't go as deep or should run earlier. Forgetting that lookupMap returns a (k,v) pair is a good example.
- [ ] add error for non-linear pattern - [ ] add error for non-linear pattern

View File

@@ -771,3 +771,15 @@ snoc xs x = xs ++ (x :: Nil)
instance a b. {{Show a}} {{Show b}} Show (a × b) where instance a b. {{Show a}} {{Show b}} Show (a × b) where
show (a,b) = "(" ++ show a ++ "," ++ show b ++ ")" show (a,b) = "(" ++ show a ++ "," ++ show b ++ ")"
-- For now, I'm not having the compiler do this automatically
Lazy : U U
Lazy a = Unit a
force : a. Lazy a a
force f = f MkUnit
-- unlike Idris, user will have to write \ _ => ...
when : f. {{Applicative f}} Bool Lazy (f Unit) f Unit
when b fa = if b then force fa else return MkUnit

View File

@@ -17,6 +17,12 @@ find src -type f -name '*.idr' | while read -r file; do
s/import public/import/g; s/import public/import/g;
s/^\s*covering//g; s/^\s*covering//g;
s/^export//g; s/^export//g;
s/pure \(\)/pure MkUnit/;
s/M \(\)/M Unit/;
s/Parser \(\)/Parser Unit/;
s/OK \(\)/OK MkUnit/;
s/\bNat\b/Int/g;
s/(\s+when [^\$]+\$)(.*)/\1 \\ _ =>\2/;
s/^public export//g; s/^public export//g;
s/\(([A-Z]\w+), ?([^)]+)\)/(\1 × \2)/g; s/\(([A-Z]\w+), ?([^)]+)\)/(\1 × \2)/g;
s/\|\|\|/--/; s/\|\|\|/--/;

View File

@@ -70,15 +70,15 @@ record FC where
export export
ToJSON FC where ToJSON FC where
toJson (MkFC file (line,col)) = JsonObj [ ("file", toJson file), ("line", toJson line), ("col", toJson col)] toJson (MkFC file (line,col)) = JsonObj (("file", toJson file) :: ("line", toJson line) :: ("col", toJson col) :: Nil)
export export
(.line) : FC -> Int fcLine : FC -> Int
fc.line = fst fc.start fcLine (MkFC file (l, c)) = l
export export
(.col) : FC -> Int fcCol : FC -> Int
fc.col = snd fc.start fcCol (MkFC file (l, c)) = c
public export public export
interface HasFC a where interface HasFC a where
@@ -108,18 +108,18 @@ showError src (E fc msg) = "ERROR at \{show fc}: \{msg}\n" ++ go 0 (lines src)
go : Int -> List String -> String go : Int -> List String -> String
go l [] = "" go l [] = ""
go l (x :: xs) = go l (x :: xs) =
if l == fc.line then if l == fcLine fc then
" \{x}\n \{replicate (cast fc.col) ' '}^\n" " \{x}\n \{replicate (cast $ fcCol fc) ' '}^\n"
else if fc.line - 3 < l then " " ++ x ++ "\n" ++ go (l + 1) xs else if fcLine fc - 3 < l then " " ++ x ++ "\n" ++ go (l + 1) xs
else go (l + 1) xs else go (l + 1) xs
showError src (Postpone fc ix msg) = "ERROR at \{show fc}: Postpone \{show ix} \{msg}\n" ++ go 0 (lines src) showError src (Postpone fc ix msg) = "ERROR at \{show fc}: Postpone \{show ix} \{msg}\n" ++ go 0 (lines src)
where where
go : Int -> List String -> String go : Int -> List String -> String
go l [] = "" go l [] = ""
go l (x :: xs) = go l (x :: xs) =
if l == fc.line then if l == fcLine fc then
" \{x}\n \{replicate (cast fc.col) ' '}^\n" " \{x}\n \{replicate (cast $ fcCol fc) ' '}^\n"
else if fc.line - 3 < l then " " ++ x ++ "\n" ++ go (l + 1) xs else if fcLine fc - 3 < l then " " ++ x ++ "\n" ++ go (l + 1) xs
else go (l + 1) xs else go (l + 1) xs
public export public export

View File

@@ -218,45 +218,45 @@ stmtToDoc : JSStmt e -> Doc
expToDoc : JSExp -> Doc expToDoc : JSExp -> Doc
expToDoc (LitArray xs) = ?expToDoc_rhs_0 expToDoc (LitArray xs) = ?expToDoc_rhs_0
expToDoc (LitObject xs) = text "{" <+> folddoc (\ a, e => a ++ ", " <+/> e) (map entry xs) <+> text "}" expToDoc (LitObject xs) = text "{" <+> folddoc (\ a, e => a ++ text ", " <+/> e) (map entry xs) <+> text "}"
where where
entry : (String, JSExp) -> Doc entry : (String, JSExp) -> Doc
-- TODO quote if needed -- TODO quote if needed
entry (nm, exp) = jsIdent nm ++ ":" <+> expToDoc exp entry (nm, exp) = jsIdent nm ++ text ":" <+> expToDoc exp
expToDoc (LitString str) = text $ quoteString str expToDoc (LitString str) = text $ quoteString str
expToDoc (LitInt i) = text $ show i expToDoc (LitInt i) = text $ show i
-- TODO add precedence -- TODO add precedence
expToDoc (Apply x@(JLam{}) xs) = text "(" ++ expToDoc x ++ ")" ++ "(" ++ nest 2 (commaSep (map expToDoc xs)) ++ ")" expToDoc (Apply x@(JLam{}) xs) = text "(" ++ expToDoc x ++ text ")" ++ text "(" ++ nest 2 (commaSep (map expToDoc xs)) ++ text ")"
expToDoc (Apply x xs) = expToDoc x ++ "(" ++ nest 2 (commaSep (map expToDoc xs)) ++ ")" expToDoc (Apply x xs) = expToDoc x ++ text "(" ++ nest 2 (commaSep (map expToDoc xs)) ++ text ")"
expToDoc (Var nm) = jsIdent nm expToDoc (Var nm) = jsIdent nm
expToDoc (JLam nms (JReturn exp)) = text "(" <+> commaSep (map jsIdent nms) <+> ") =>" <+> "(" ++ expToDoc exp ++ ")" expToDoc (JLam nms (JReturn exp)) = text "(" <+> commaSep (map jsIdent nms) <+> text ") =>" <+> text "(" ++ expToDoc exp ++ text ")"
expToDoc (JLam nms body) = text "(" <+> commaSep (map jsIdent nms) <+> ") =>" <+> bracket "{" (stmtToDoc body) "}" expToDoc (JLam nms body) = text "(" <+> commaSep (map jsIdent nms) <+> text ") =>" <+> bracket "{" (stmtToDoc body) "}"
expToDoc JUndefined = text "undefined" expToDoc JUndefined = text "undefined"
expToDoc (Index obj ix) = expToDoc obj ++ "[" ++ expToDoc ix ++ "]" expToDoc (Index obj ix) = expToDoc obj ++ text "[" ++ expToDoc ix ++ text "]"
expToDoc (Dot obj nm) = expToDoc obj ++ "." ++ jsIdent nm expToDoc (Dot obj nm) = expToDoc obj ++ text "." ++ jsIdent nm
caseBody : JSStmt e -> Doc caseBody : JSStmt e -> Doc
caseBody stmt@(JReturn x) = nest 2 (line ++ stmtToDoc stmt) caseBody stmt@(JReturn x) = nest 2 (line ++ stmtToDoc stmt)
-- caseBody {e = Return} stmt@(JCase{}) = nest 2 (line ++ stmtToDoc stmt) -- caseBody {e = Return} stmt@(JCase{}) = nest 2 (line ++ stmtToDoc stmt)
caseBody {e} stmt@(JCase{}) = nest 2 (line ++ stmtToDoc stmt </> text "break;") caseBody {e} stmt@(JCase{}) = nest 2 (line ++ stmtToDoc stmt </> text "break;")
caseBody stmt = line ++ "{" ++ nest 2 (line ++ stmtToDoc stmt </> text "break;") </> "}" caseBody stmt = line ++ text "{" ++ nest 2 (line ++ stmtToDoc stmt </> text "break;") </> text "}"
altToDoc : JAlt -> Doc altToDoc : JAlt -> Doc
altToDoc (JConAlt nm stmt) = text "case" <+> text (quoteString nm) ++ ":" ++ caseBody stmt altToDoc (JConAlt nm stmt) = text "case" <+> text (quoteString nm) ++ text ":" ++ caseBody stmt
altToDoc (JDefAlt stmt) = text "default" ++ ":" ++ caseBody stmt altToDoc (JDefAlt stmt) = text "default" ++ text ":" ++ caseBody stmt
altToDoc (JLitAlt a stmt) = text "case" <+> expToDoc a ++ ":" ++ caseBody stmt altToDoc (JLitAlt a stmt) = text "case" <+> expToDoc a ++ text ":" ++ caseBody stmt
stmtToDoc (JSnoc x y) = stmtToDoc x </> stmtToDoc y stmtToDoc (JSnoc x y) = stmtToDoc x </> stmtToDoc y
stmtToDoc (JPlain x) = expToDoc x ++ ";" stmtToDoc (JPlain x) = expToDoc x ++ text ";"
-- I might not need these split yet. -- I might not need these split yet.
stmtToDoc (JLet nm body) = "let" <+> jsIdent nm ++ ";" </> stmtToDoc body stmtToDoc (JLet nm body) = text "let" <+> jsIdent nm ++ text ";" </> stmtToDoc body
stmtToDoc (JAssign nm expr) = jsIdent nm <+> "=" <+> expToDoc expr ++ ";" stmtToDoc (JAssign nm expr) = jsIdent nm <+> text "=" <+> expToDoc expr ++ text ";"
stmtToDoc (JConst nm x) = text "const" <+> jsIdent nm <+> nest 2 ("=" <+/> expToDoc x ++ ";") stmtToDoc (JConst nm x) = text "const" <+> jsIdent nm <+> nest 2 (text "=" <+/> expToDoc x ++ text ";")
stmtToDoc (JReturn x) = text "return" <+> expToDoc x ++ ";" stmtToDoc (JReturn x) = text "return" <+> expToDoc x ++ text ";"
stmtToDoc (JError str) = text "throw new Error(" ++ text (quoteString str) ++ ");" stmtToDoc (JError str) = text "throw new Error(" ++ text (quoteString str) ++ text ");"
stmtToDoc (JCase sc alts) = stmtToDoc (JCase sc alts) =
text "switch (" ++ expToDoc sc ++ ")" <+> bracket "{" (stack $ map altToDoc alts) "}" text "switch (" ++ expToDoc sc ++ text ")" <+> bracket "{" (stack $ map altToDoc alts) "}"
mkArgs : Nat -> List String -> List String mkArgs : Nat -> List String -> List String
mkArgs Z acc = acc mkArgs Z acc = acc
@@ -279,12 +279,12 @@ entryToDoc (MkEntry _ name ty (Fn tm)) = do
debug "compileFun \{pprint [] tm}" debug "compileFun \{pprint [] tm}"
ct <- compileFun tm ct <- compileFun tm
let exp = maybeWrap $ termToJS empty ct JReturn let exp = maybeWrap $ termToJS empty ct JReturn
pure $ text "const" <+> jsIdent (show name) <+> text "=" <+/> expToDoc exp ++ ";" pure $ text "const" <+> jsIdent (show name) <+> text "=" <+/> expToDoc exp ++ text ";"
entryToDoc (MkEntry _ name type Axiom) = pure "" entryToDoc (MkEntry _ name type Axiom) = pure $ text ""
entryToDoc (MkEntry _ name type (TCon strs)) = pure $ dcon name (piArity type) entryToDoc (MkEntry _ name type (TCon strs)) = pure $ dcon name (piArity type)
entryToDoc (MkEntry _ name type (DCon arity str)) = pure $ dcon name arity entryToDoc (MkEntry _ name type (DCon arity str)) = pure $ dcon name arity
entryToDoc (MkEntry _ name type PrimTCon) = pure $ dcon name (piArity type) entryToDoc (MkEntry _ name type PrimTCon) = pure $ dcon name (piArity type)
entryToDoc (MkEntry _ name _ (PrimFn src _)) = pure $ text "const" <+> jsIdent (show name) <+> "=" <+> text src entryToDoc (MkEntry _ name _ (PrimFn src _)) = pure $ text "const" <+> jsIdent (show name) <+> text "=" <+> text src
||| This version (call `reverse . snd <$> process "main" ([],[])`) will do dead ||| This version (call `reverse . snd <$> process "main" ([],[])`) will do dead
||| code elimination, but the Prelude js primitives are reaching for ||| code elimination, but the Prelude js primitives are reaching for
@@ -303,7 +303,7 @@ process (done,docs) nm = do
ct <- compileFun tm ct <- compileFun tm
-- If ct has zero arity and is a compount expression, this fails.. -- If ct has zero arity and is a compount expression, this fails..
let exp = maybeWrap $ termToJS empty ct JReturn let exp = maybeWrap $ termToJS empty ct JReturn
let doc = text "const" <+> jsIdent (show name) <+> text "=" <+/> expToDoc exp ++ ";" let doc = text "const" <+> jsIdent (show name) <+> text "=" <+/> expToDoc exp ++ text ";"
(done,docs) <- walkTm tm (nm :: done, docs) (done,docs) <- walkTm tm (nm :: done, docs)
pure (done, doc :: docs) pure (done, doc :: docs)
Just entry => pure (nm :: done, !(entryToDoc entry) :: docs) Just entry => pure (nm :: done, !(entryToDoc entry) :: docs)
@@ -315,7 +315,7 @@ process (done,docs) nm = do
let tag = QN [] nm let tag = QN [] nm
let False = tag `elem` done | _ => pure (done,docs) let False = tag `elem` done | _ => pure (done,docs)
(done,docs) <- process (done, docs) name (done,docs) <- process (done, docs) name
let doc = text "const" <+> jsIdent nm <+> text "=" <+> jsIdent (show name) ++ ";" let doc = text "const" <+> jsIdent nm <+> text "=" <+> jsIdent (show name) ++ text ";"
pure (tag :: done, doc :: docs) pure (tag :: done, doc :: docs)
walkTm : Tm -> (List QName, List Doc) -> M (List QName, List Doc) walkTm : Tm -> (List QName, List Doc) -> M (List QName, List Doc)

View File

@@ -139,10 +139,10 @@ invert lvl sp = go sp []
-- we have to "lift" the renaming when we go under a lambda -- we have to "lift" the renaming when we go under a lambda
-- I think that essentially means our domain ix are one bigger, since we're looking at lvl -- I think that essentially means our domain ix are one bigger, since we're looking at lvl
-- in the codomain, so maybe we can just keep that value -- in the codomain, so maybe we can just keep that value
rename : Nat -> List Nat -> Nat -> Val -> M Tm rename : Nat -> List Nat -> Nat -> Val -> M Tm
rename meta ren lvl v = go ren lvl v rename meta ren lvl v = go ren lvl v
where where
go : List Nat -> Nat -> Val -> M Tm go : List Nat -> Nat -> Val -> M Tm
goSpine : List Nat -> Nat -> Tm -> SnocList Val -> M Tm goSpine : List Nat -> Nat -> Tm -> SnocList Val -> M Tm
goSpine ren lvl tm [<] = pure tm goSpine ren lvl tm [<] = pure tm
goSpine ren lvl tm (xs :< x) = do goSpine ren lvl tm (xs :< x) = do
@@ -192,7 +192,7 @@ unify : Env -> UnifyMode -> Val -> Val -> M UnifyResult
ctx.boundNames = map snd $ filter (\x => fst x == Bound) $ toList $ zip ctx.bds (map fst ctx.types) ctx.boundNames = map snd $ filter (\x => fst x == Bound) $ toList $ zip ctx.bds (map fst ctx.types)
export export
solve : Env -> (k : Nat) -> SnocList Val -> Val -> M () solve : Env -> (k : Nat) -> SnocList Val -> Val -> M ()
solve env m sp t = do solve env m sp t = do
meta@(Unsolved metaFC ix ctx_ ty kind cons) <- lookupMeta m meta@(Unsolved metaFC ix ctx_ ty kind cons) <- lookupMeta m
| _ => error (getFC t) "Meta \{show m} already solved! [solve]" | _ => error (getFC t) "Meta \{show m} already solved! [solve]"
@@ -408,10 +408,10 @@ primType fc nm = case lookup nm !(get) of
_ => error fc "Primitive type \{show nm} not in scope" _ => error fc "Primitive type \{show nm} not in scope"
export export
infer : Context -> Raw -> M (Tm, Val) infer : Context -> Raw -> M (Tm, Val)
export export
check : Context -> Raw -> Val -> M Tm check : Context -> Raw -> Val -> M Tm
data Bind = MkBind String Icit Val data Bind = MkBind String Icit Val
@@ -1086,7 +1086,7 @@ check ctx tm ty = case (tm, !(forceType ctx.env ty)) of
infer ctx (RVar fc nm) = go 0 ctx.types infer ctx (RVar fc nm) = go 0 ctx.types
where where
go : Nat -> Vect n (String, Val) -> M (Tm, Val) go : Nat -> Vect n (String, Val) -> M (Tm, Val)
go i [] = case lookupRaw nm !(get) of go i [] = case lookupRaw nm !(get) of
Just (MkEntry _ name ty def) => do Just (MkEntry _ name ty def) => do
debug "lookup \{name} as \{show def}" debug "lookup \{name} as \{show def}"

View File

@@ -190,8 +190,8 @@ indented (P p) = P $ \toks,com,ops,indent => case toks of
[] => p toks com ops indent [] => p toks com ops indent
(t::_) => (t::_) =>
let (tl,tc) = start t let (tl,tc) = start t
in if tc > indent.col || tl == indent.line then p toks com ops indent in if tc > fcCol indent || tl == fcLine indent then p toks com ops indent
else Fail False (error indent.file toks "unexpected outdent") toks com ops else Fail False (error (file indent) toks "unexpected outdent") toks com ops
||| expect token of given kind ||| expect token of given kind
export export

View File

@@ -58,10 +58,10 @@ be fit acc w k ((i, (Text s)) :: xs) =
if not fit || (k + length s < w) if not fit || (k + length s < w)
then (be fit (acc :< TEXT s) w (k + length s) xs) then (be fit (acc :< TEXT s) w (k + length s) xs)
else Nothing else Nothing
be fit acc w k ((i, (Nest j x)) :: xs) = be fit acc w k ((i+j,x)::xs) be fit acc w k ((i, (Nest j x)) :: xs) = be fit acc w k ((i + j, x) :: xs)
be fit acc w k ((i, (Seq x y)) :: xs) = be fit acc w k ((i,x) :: (i,y) :: xs) be fit acc w k ((i, (Seq x y)) :: xs) = be fit acc w k ((i,x) :: (i,y) :: xs)
be fit acc w k ((i, (Alt x y)) :: xs) = be fit acc w k ((i, (Alt x y)) :: xs) =
(acc <>>) <$> (be True [<] w k ((i,x)::xs) <|> be fit [<] w k ((i,y)::xs)) (acc <>>) <$> (be True [<] w k ((i,x) :: xs) <|> be fit [<] w k ((i,y) :: xs))
best : Nat -> Nat -> Doc -> List Item best : Nat -> Nat -> Doc -> List Item
best w k x = fromMaybe [] $ be False [<] w k [(0,x)] best w k x = fromMaybe [] $ be False [<] w k [(0,x)]
@@ -143,10 +143,6 @@ export
commaSep : List Doc -> Doc commaSep : List Doc -> Doc
commaSep = folddoc (\a, b => a ++ text "," <+/> b) commaSep = folddoc (\a, b => a ++ text "," <+/> b)
public export
FromString Doc where
fromString = text
||| If we stick Doc into a String, try to avoid line-breaks via `flatten` ||| If we stick Doc into a String, try to avoid line-breaks via `flatten`
public export public export
Interpolation Doc where Interpolation Doc where

View File

@@ -235,8 +235,8 @@ Pretty Pattern where
-- FIXME - wrap Implicit with {} -- FIXME - wrap Implicit with {}
pretty (PatVar _ icit nm) = text nm pretty (PatVar _ icit nm) = text nm
pretty (PatCon _ icit nm args Nothing) = text (show nm) <+> spread (map pretty args) pretty (PatCon _ icit nm args Nothing) = text (show nm) <+> spread (map pretty args)
pretty (PatCon _ icit nm args (Just as)) = text as ++ "@(" ++ text (show nm) <+> spread (map pretty args) ++ ")" pretty (PatCon _ icit nm args (Just as)) = text as ++ text "@(" ++ text (show nm) <+> spread (map pretty args) ++ text ")"
pretty (PatWild _icit) = "_" pretty (PatWild _icit) = text "_"
pretty (PatLit _ lit) = pretty lit pretty (PatLit _ lit) = pretty lit
wrap : Icit -> Doc -> Doc wrap : Icit -> Doc -> Doc
@@ -276,9 +276,9 @@ Pretty Raw where
asDoc p (RImplicit _) = text "_" asDoc p (RImplicit _) = text "_"
asDoc p (RHole _) = text "?" asDoc p (RHole _) = text "?"
asDoc p (RDo _ stmts) = text "TODO - RDo" asDoc p (RDo _ stmts) = text "TODO - RDo"
asDoc p (RIf _ x y z) = par p 0 $ text "if" <+> asDoc 0 x <+/> "then" <+> asDoc 0 y <+/> "else" <+> asDoc 0 z asDoc p (RIf _ x y z) = par p 0 $ text "if" <+> asDoc 0 x <+/> text "then" <+> asDoc 0 y <+/> text "else" <+> asDoc 0 z
asDoc p (RWhere _ dd b) = text "TODO pretty where" asDoc p (RWhere _ dd b) = text "TODO pretty where"
asDoc p (RAs _ nm x) = text nm ++ "@(" ++ asDoc 0 x ++ ")" asDoc p (RAs _ nm x) = text nm ++ text "@(" ++ asDoc 0 x ++ text ")"
prettyBind : (BindInfo, Raw) -> Doc prettyBind : (BindInfo, Raw) -> Doc
prettyBind (BI _ nm icit quant, ty) = wrap icit (text (show quant ++ nm) <+> text ":" <+> pretty ty) prettyBind (BI _ nm icit quant, ty) = wrap icit (text (show quant ++ nm) <+> text ":" <+> pretty ty)
@@ -289,19 +289,19 @@ pipeSep = folddoc (\a, b => a <+/> text "|" <+> b)
export export
Pretty Decl where Pretty Decl where
pretty (TypeSig _ nm ty) = spread (map text nm) <+> text ":" <+> nest 2 (pretty ty) pretty (TypeSig _ nm ty) = spread (map text nm) <+> text ":" <+> nest 2 (pretty ty)
pretty (Def _ nm clauses) = stack $ map (\(a,b) => pretty a <+> "=" <+> pretty b) clauses pretty (Def _ nm clauses) = stack $ map (\(a,b) => pretty a <+> text "=" <+> pretty b) clauses
pretty (Data _ nm x xs) = text "data" <+> text nm <+> text ":" <+> pretty x <+> (nest 2 $ text "where" </> stack (map pretty xs)) pretty (Data _ nm x xs) = text "data" <+> text nm <+> text ":" <+> pretty x <+> (nest 2 $ text "where" </> stack (map pretty xs))
pretty (DCheck _ x y) = text "#check" <+> pretty x <+> ":" <+> pretty y pretty (DCheck _ x y) = text "#check" <+> pretty x <+> text ":" <+> pretty y
pretty (PType _ nm ty) = text "ptype" <+> text nm <+> (maybe empty (\ty => ":" <+> pretty ty) ty) pretty (PType _ nm ty) = text "ptype" <+> text nm <+> (maybe empty (\ty => text ":" <+> pretty ty) ty)
pretty (PFunc _ nm [] ty src) = "pfunc" <+> text nm <+> ":" <+> nest 2 (pretty ty <+> ":=" <+/> text (show src)) pretty (PFunc _ nm [] ty src) = text "pfunc" <+> text nm <+> text ":" <+> nest 2 (pretty ty <+> text ":=" <+/> text (show src))
pretty (PFunc _ nm uses ty src) = "pfunc" <+> text nm <+> "uses" <+> spread (map text uses) <+> ":" <+> nest 2 (pretty ty <+> ":=" <+/> text (show src)) pretty (PFunc _ nm uses ty src) = text "pfunc" <+> text nm <+> text "uses" <+> spread (map text uses) <+> text ":" <+> nest 2 (pretty ty <+> text ":=" <+/> text (show src))
pretty (PMixFix _ names prec fix) = text (show fix) <+> text (show prec) <+> spread (map text names) pretty (PMixFix _ names prec fix) = text (show fix) <+> text (show prec) <+> spread (map text names)
pretty (Record _ nm tele cname decls) = text "record" <+> text nm <+> ":" <+> spread (map prettyBind tele) pretty (Record _ nm tele cname decls) = text "record" <+> text nm <+> text ":" <+> spread (map prettyBind tele)
<+> (nest 2 $ text "where" </> stack (maybe empty (\ nm' => text "constructor" <+> text nm') cname :: map pretty decls)) <+> (nest 2 $ text "where" </> stack (maybe empty (\ nm' => text "constructor" <+> text nm') cname :: map pretty decls))
pretty (Class _ nm tele decls) = text "class" <+> text nm <+> ":" <+> spread (map prettyBind tele) pretty (Class _ nm tele decls) = text "class" <+> text nm <+> text ":" <+> spread (map prettyBind tele)
<+> (nest 2 $ text "where" </> stack (map pretty decls)) <+> (nest 2 $ text "where" </> stack (map pretty decls))
pretty (Instance _ _ _) = text "TODO pretty Instance" pretty (Instance _ _ _) = text "TODO pretty Instance"
pretty (ShortData _ lhs sigs) = text "data" <+> pretty lhs <+> "=" <+> pipeSep (map pretty sigs) pretty (ShortData _ lhs sigs) = text "data" <+> pretty lhs <+> text "=" <+> pipeSep (map pretty sigs)
export export
Pretty Module where Pretty Module where

View File

@@ -214,47 +214,46 @@ Eq (Tm) where
-- maybe return Doc and have an Interpolation.. -- maybe return Doc and have an Interpolation..
-- If we need to flatten, case is going to get in the way. -- If we need to flatten, case is going to get in the way.
pprint' : Nat -> List String -> Tm -> Doc
pprintAlt : Nat -> List String -> CaseAlt -> Doc
pprintAlt p names (CaseDefault t) = text "_" <+> text "=>" <+> pprint' p ("_" :: names) t
pprintAlt p names (CaseCons name args t) = text (show name) <+> spread (map text args) <+> (nest 2 $ text "=>" <+/> pprint' p (reverse args ++ names) t)
-- `;` is not in surface syntax, but sometimes we print on one line
pprintAlt p names (CaseLit lit t) = text (show lit) <+> (nest 2 $ text "=>" <+/> pprint' p names t ++ text ";")
parens : Nat -> Nat -> Doc -> Doc
parens a b doc = if a < b
then text "(" ++ doc ++ text ")"
else doc
pprint' p names (Bnd _ k) = case getAt k names of
-- Either a bug or we're printing without names
Nothing => text "BND:\{show k}"
Just nm => text "\{nm}:\{show k}"
pprint' p names (Ref _ str mt) = text (show str)
pprint' p names (Meta _ k) = text "?m:\{show k}"
pprint' p names (Lam _ nm icit quant t) = parens 0 p $ nest 2 $ text "\\ \{show quant}\{nm} =>" <+/> pprint' 0 (nm :: names) t
pprint' p names (App _ t u) = parens 0 p $ pprint' 0 names t <+> pprint' 1 names u
pprint' p names (UU _) = text "U"
pprint' p names (Pi _ nm Auto rig t u) = parens 0 p $
text "{{" ++ text (show rig) <+> text nm <+> text ":" <+> pprint' 0 names t <+> text "}}" <+> text "->" <+> pprint' 0 (nm :: names) u
pprint' p names (Pi _ nm Implicit rig t u) = parens 0 p $
text "{" ++ text (show rig) <+> text nm <+> text ":" <+> pprint' 0 names t <+> text "}" <+> text "->" <+> pprint' 0 (nm :: names) u
pprint' p names (Pi _ "_" Explicit Many t u) =
parens 0 p $ pprint' 1 names t <+> text "->" <+> pprint' 0 ("_" :: names) u
pprint' p names (Pi _ nm Explicit rig t u) = parens 0 p $
text "(" ++ text (show rig) <+> text nm <+> text ":" <+> pprint' 0 names t ++ text ")" <+> text "->" <+> pprint' 0 (nm :: names) u
-- FIXME - probably way wrong on the names here. There is implicit binding going on
pprint' p names (Case _ sc alts) = parens 0 p $ text "case" <+> pprint' 0 names sc <+> text "of" ++ (nest 2 (line ++ stack (map (pprintAlt 0 names) alts)))
pprint' p names (Lit _ lit) = text (show lit)
pprint' p names (Let _ nm t u) = parens 0 p $ text "let" <+> text nm <+> text ":=" <+> pprint' 0 names t <+> text "in" </> (nest 2 $ pprint' 0 (nm :: names) u)
pprint' p names (LetRec _ nm ty t u) = parens 0 p $ text "letrec" <+> text nm <+> text ":" <+> pprint' 0 names ty <+> text ":=" <+> pprint' 0 names t <+> text "in" </> (nest 2 $ pprint' 0 (nm :: names) u)
pprint' p names (Erased _) = text "ERASED"
||| Pretty printer for Tm. ||| Pretty printer for Tm.
export export
pprint : List String -> Tm -> Doc pprint : List String -> Tm -> Doc
pprint names tm = go 0 names tm pprint names tm = pprint' 0 names tm
where
parens : Nat -> Nat -> Doc -> Doc
parens a b doc = if a < b
then text "(" ++ doc ++ text ")"
else doc
go : Nat -> List String -> Tm -> Doc
goAlt : Nat -> List String -> CaseAlt -> Doc
goAlt p names (CaseDefault t) = "_" <+> "=>" <+> go p ("_" :: names) t
goAlt p names (CaseCons name args t) = text (show name) <+> spread (map text args) <+> (nest 2 $ "=>" <+/> go p (reverse args ++ names) t)
-- `;` is not in surface syntax, but sometimes we print on one line
goAlt p names (CaseLit lit t) = text (show lit) <+> (nest 2 $ "=>" <+/> go p names t ++ ";")
go p names (Bnd _ k) = case getAt k names of
-- Either a bug or we're printing without names
Nothing => text "BND:\{show k}"
Just nm => text "\{nm}:\{show k}"
go p names (Ref _ str mt) = text (show str)
go p names (Meta _ k) = text "?m:\{show k}"
go p names (Lam _ nm icit quant t) = parens 0 p $ nest 2 $ text "\\ \{show quant}\{nm} =>" <+/> go 0 (nm :: names) t
go p names (App _ t u) = parens 0 p $ go 0 names t <+> go 1 names u
go p names (UU _) = "U"
go p names (Pi _ nm Auto rig t u) = parens 0 p $
text "{{" ++ text (show rig) <+> text nm <+> ":" <+> go 0 names t <+> "}}" <+> "->" <+> go 0 (nm :: names) u
go p names (Pi _ nm Implicit rig t u) = parens 0 p $
text "{" ++ text (show rig) <+> text nm <+> ":" <+> go 0 names t <+> "}" <+> "->" <+> go 0 (nm :: names) u
go p names (Pi _ "_" Explicit Many t u) =
parens 0 p $ go 1 names t <+> "->" <+> go 0 ("_" :: names) u
go p names (Pi _ nm Explicit rig t u) = parens 0 p $
text "(" ++ text (show rig) <+> text nm <+> ":" <+> go 0 names t ++ ")" <+> "->" <+> go 0 (nm :: names) u
-- FIXME - probably way wrong on the names here. There is implicit binding going on
go p names (Case _ sc alts) = parens 0 p $ text "case" <+> go 0 names sc <+> text "of" ++ (nest 2 (line ++ stack (map (goAlt 0 names) alts)))
go p names (Lit _ lit) = text (show lit)
go p names (Let _ nm t u) = parens 0 p $ text "let" <+> text nm <+> ":=" <+> go 0 names t <+> "in" </> (nest 2 $ go 0 (nm :: names) u)
go p names (LetRec _ nm ty t u) = parens 0 p $ text "letrec" <+> text nm <+> ":" <+> go 0 names ty <+> ":=" <+> go 0 names t <+> "in" </> (nest 2 $ go 0 (nm :: names) u)
go p names (Erased _) = "ERASED"
data Val : Type data Val : Type
@@ -532,34 +531,34 @@ get : M TopContext
get = MkM $ \ tc => pure $ Right (tc, tc) get = MkM $ \ tc => pure $ Right (tc, tc)
export export
put : TopContext -> M () put : TopContext -> M Unit
put tc = MkM $ \_ => pure $ Right (tc, ()) put tc = MkM $ \_ => pure $ Right (tc, MkUnit)
export export
modify : (TopContext -> TopContext) -> M () modify : (TopContext -> TopContext) -> M Unit
modify f = do modify f = do
tc <- get tc <- get
put (f tc) put (f tc)
||| Force argument and print if verbose is true ||| Force argument and print if verbose is true
export export
debug : Lazy String -> M () debug : Lazy String -> M Unit
debug x = do debug x = do
top <- get top <- get
when top.verbose $ putStrLn x when top.verbose $ putStrLn $ Force x
export export
info : FC -> String -> M () info : FC -> String -> M Unit
info fc msg = putStrLn "INFO at \{show fc}: \{msg}" info fc msg = putStrLn "INFO at \{show fc}: \{msg}"
||| Version of debug that makes monadic computation lazy ||| Version of debug that makes monadic computation lazy
export export
debugM : M String -> M () debugM : M String -> M Unit
debugM x = do debugM x = do
top <- get top <- get
when top.verbose $ do putStrLn !(x) when top.verbose $ do putStrLn !(x)
export partial export
Show Context where Show Context where
show ctx = "Context \{show $ map fst $ ctx.types}" show ctx = "Context \{show $ map fst $ ctx.types}"