ats-format 0.2.0.2 → 0.2.0.4
raw patch · 39 files changed
+30/−7633 lines, 39 filesdep +language-atsdep −ansi-terminaldep −arraydep −criteriondep ~ansi-wl-pprintdep ~basePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: language-ats
Dependencies removed: ansi-terminal, array, criterion, deepseq, hspec, hspec-dirstream, lens, recursion-schemes, system-filepath
Dependency ranges changed: ansi-wl-pprint, base
API changes (from Hackage documentation)
- Language.ATS: ATS :: [Declaration] -> ATS
- Language.ATS: AbsProp :: AlexPosn -> String -> [Arg] -> Declaration
- Language.ATS: AbsT0p :: AlexPosn -> String -> Type -> Declaration
- Language.ATS: AbsType :: AlexPosn -> String -> [Arg] -> (Maybe Type) -> Declaration
- Language.ATS: AbsVT0p :: AlexPosn -> String -> [Arg] -> (Maybe Type) -> Declaration
- Language.ATS: AbsView :: AlexPosn -> String -> [Arg] -> (Maybe Type) -> Declaration
- Language.ATS: AbsViewType :: AlexPosn -> String -> [Arg] -> (Maybe Type) -> Declaration
- Language.ATS: Access :: AlexPosn -> Expression -> Name -> Expression
- Language.ATS: Actions :: ATS -> Expression
- Language.ATS: Add :: BinOp
- Language.ATS: Addr :: Type
- Language.ATS: AddrAt :: AlexPosn -> Expression -> Expression
- Language.ATS: AlexPn :: !Int -> !Int -> !Int -> AlexPosn
- Language.ATS: And :: PreFunction -> Function
- Language.ATS: AndD :: Declaration -> Declaration -> Declaration
- Language.ATS: AndDecl :: (Maybe Type) -> Pattern -> Expression -> Declaration
- Language.ATS: AnonymousRecord :: AlexPosn -> [(String, Type)] -> Type
- Language.ATS: Arg :: (Paired String Type) -> Arg
- Language.ATS: Arrow :: AlexPosn -> String -> Token
- Language.ATS: AsProof :: Type -> (Maybe Type) -> Type
- Language.ATS: Assume :: Name -> [Arg] -> Expression -> Declaration
- Language.ATS: At :: AlexPosn -> (Maybe Type) -> Type -> Type
- Language.ATS: AtExpr :: Expression -> Expression -> Expression
- Language.ATS: AtPattern :: AlexPosn -> Pattern -> Pattern
- Language.ATS: Begin :: AlexPosn -> Expression -> Expression
- Language.ATS: BinList :: BinOp -> [Expression] -> Expression
- Language.ATS: Binary :: BinOp -> Expression -> Expression -> Expression
- Language.ATS: Bool :: Type
- Language.ATS: BoolLit :: Bool -> Expression
- Language.ATS: BoolTok :: AlexPosn -> Bool -> Token
- Language.ATS: Both :: a -> b -> Paired a b
- Language.ATS: CBlock :: String -> Declaration
- Language.ATS: CBlockLex :: AlexPosn -> String -> Token
- Language.ATS: Call :: Name -> [Type] -> [Type] -> (Maybe Expression) -> [Expression] -> Expression
- Language.ATS: Case :: AlexPosn -> Addendum -> Expression -> [(Pattern, LambdaType, Expression)] -> Expression
- Language.ATS: CastFn :: PreFunction -> Function
- Language.ATS: Char :: Type
- Language.ATS: CharLit :: Char -> Expression
- Language.ATS: CharTok :: AlexPosn -> Char -> Token
- Language.ATS: Comment :: String -> Declaration
- Language.ATS: CommentLex :: AlexPosn -> String -> Token
- Language.ATS: ConcreteType :: StaticExpression -> Type
- Language.ATS: DataProp :: AlexPosn -> String -> [Arg] -> [DataPropLeaf] -> Declaration
- Language.ATS: DataPropLeaf :: [Universal] -> Expression -> (Maybe Expression) -> DataPropLeaf
- Language.ATS: Define :: String -> Declaration
- Language.ATS: DepString :: StaticExpression -> Type
- Language.ATS: Dependent :: Name -> [Type] -> Type
- Language.ATS: DependentBool :: StaticExpression -> Type
- Language.ATS: DependentInt :: StaticExpression -> Type
- Language.ATS: Deref :: AlexPosn -> Expression -> Expression
- Language.ATS: Div :: BinOp
- Language.ATS: Double :: Type
- Language.ATS: DoubleBracesTok :: AlexPosn -> Token
- Language.ATS: DoubleBracketTok :: AlexPosn -> Token
- Language.ATS: DoubleParenTok :: AlexPosn -> Token
- Language.ATS: Equal :: BinOp
- Language.ATS: Ex :: Existential -> Type -> Type
- Language.ATS: Existential :: [Arg] -> Bool -> Maybe Type -> Maybe StaticExpression -> Existential
- Language.ATS: ExistentialPattern :: Existential -> Pattern -> Pattern
- Language.ATS: Extern :: AlexPosn -> Declaration -> Declaration
- Language.ATS: FieldMutate :: AlexPosn -> Expression -> String -> Expression -> Expression
- Language.ATS: First :: a -> Paired a b
- Language.ATS: FixAt :: String -> StackFunction -> Expression
- Language.ATS: FixityDecl :: Fixity -> (Maybe Int) -> [String] -> Declaration
- Language.ATS: FixityTok :: AlexPosn -> String -> Token
- Language.ATS: Float :: Type
- Language.ATS: FloatLit :: Float -> Expression
- Language.ATS: FloatTok :: AlexPosn -> Float -> Token
- Language.ATS: Fn :: PreFunction -> Function
- Language.ATS: Fnx :: PreFunction -> Function
- Language.ATS: ForA :: Universal -> Type -> Type
- Language.ATS: Free :: Pattern -> Pattern
- Language.ATS: FromVT :: Type -> Type
- Language.ATS: Full :: AlexPosn -> String -> LambdaType
- Language.ATS: Fun :: PreFunction -> Function
- Language.ATS: Func :: AlexPosn -> Function -> Declaration
- Language.ATS: FuncType :: AlexPosn -> String -> Token
- Language.ATS: FunctionType :: String -> Type -> Type -> Type
- Language.ATS: Functorial :: String -> String -> Name
- Language.ATS: GreaterThan :: BinOp
- Language.ATS: GreaterThanEq :: BinOp
- Language.ATS: Guarded :: AlexPosn -> Expression -> Pattern -> Pattern
- Language.ATS: Identifier :: AlexPosn -> String -> Token
- Language.ATS: IdentifierSpace :: AlexPosn -> String -> Token
- Language.ATS: If :: Expression -> Expression -> Maybe Expression -> Expression
- Language.ATS: Impl :: [Arg] -> Implementation -> Declaration
- Language.ATS: Implement :: AlexPosn -> [Universal] -> [Universal] -> Name -> [Arg] -> Expression -> Implementation
- Language.ATS: ImplicitType :: AlexPosn -> Type
- Language.ATS: Include :: String -> Declaration
- Language.ATS: Index :: AlexPosn -> Name -> Expression -> Expression
- Language.ATS: Int :: Type
- Language.ATS: IntLit :: Int -> Expression
- Language.ATS: IntTok :: AlexPosn -> Int -> Token
- Language.ATS: Keyword :: AlexPosn -> Keyword -> Token
- Language.ATS: KwAbsprop :: Keyword
- Language.ATS: KwAbst0p :: Addendum -> Keyword
- Language.ATS: KwAbstype :: Keyword
- Language.ATS: KwAbsview :: Keyword
- Language.ATS: KwAbsvt0p :: Addendum -> Keyword
- Language.ATS: KwAbsvtype :: Keyword
- Language.ATS: KwAddr :: Keyword
- Language.ATS: KwAddrAt :: Keyword
- Language.ATS: KwAnd :: Keyword
- Language.ATS: KwAssume :: Keyword
- Language.ATS: KwBegin :: Keyword
- Language.ATS: KwBool :: Keyword
- Language.ATS: KwCase :: Addendum -> Keyword
- Language.ATS: KwCastfn :: Keyword
- Language.ATS: KwChar :: Keyword
- Language.ATS: KwDataprop :: Keyword
- Language.ATS: KwDatatype :: Keyword
- Language.ATS: KwDataview :: Keyword
- Language.ATS: KwDatavtype :: Keyword
- Language.ATS: KwElse :: Keyword
- Language.ATS: KwEnd :: Keyword
- Language.ATS: KwExtern :: Keyword
- Language.ATS: KwFixAt :: Keyword
- Language.ATS: KwFn :: Keyword
- Language.ATS: KwFnx :: Keyword
- Language.ATS: KwFun :: Keyword
- Language.ATS: KwIf :: Keyword
- Language.ATS: KwImplement :: Keyword
- Language.ATS: KwIn :: Keyword
- Language.ATS: KwInclude :: Keyword
- Language.ATS: KwInfix :: Keyword
- Language.ATS: KwInfixl :: Keyword
- Language.ATS: KwInfixr :: Keyword
- Language.ATS: KwInt :: Keyword
- Language.ATS: KwLambda :: Keyword
- Language.ATS: KwLambdaAt :: Keyword
- Language.ATS: KwLet :: Keyword
- Language.ATS: KwLinearLambda :: Keyword
- Language.ATS: KwListLit :: String -> Keyword
- Language.ATS: KwLocal :: Keyword
- Language.ATS: KwMod :: Keyword
- Language.ATS: KwNat :: Keyword
- Language.ATS: KwOf :: Keyword
- Language.ATS: KwOverload :: Keyword
- Language.ATS: KwPraxi :: Keyword
- Language.ATS: KwPrfn :: Keyword
- Language.ATS: KwPrfun :: Keyword
- Language.ATS: KwProofImplement :: Keyword
- Language.ATS: KwPropdef :: Keyword
- Language.ATS: KwPrval :: Keyword
- Language.ATS: KwRaise :: Keyword
- Language.ATS: KwSif :: Keyword
- Language.ATS: KwSortdef :: Keyword
- Language.ATS: KwSta :: Keyword
- Language.ATS: KwStacst :: Keyword
- Language.ATS: KwStadef :: Keyword
- Language.ATS: KwStaload :: Keyword
- Language.ATS: KwString :: Keyword
- Language.ATS: KwSymintr :: Keyword
- Language.ATS: KwT0p :: Addendum -> Keyword
- Language.ATS: KwTKind :: Keyword
- Language.ATS: KwThen :: Keyword
- Language.ATS: KwType :: Keyword
- Language.ATS: KwTypedef :: Keyword
- Language.ATS: KwVal :: Addendum -> Keyword
- Language.ATS: KwVar :: Keyword
- Language.ATS: KwView :: Addendum -> Keyword
- Language.ATS: KwViewAt :: Keyword
- Language.ATS: KwViewdef :: Keyword
- Language.ATS: KwVoid :: Keyword
- Language.ATS: KwVt0p :: Addendum -> Keyword
- Language.ATS: KwVtypedef :: Keyword
- Language.ATS: KwWhen :: Keyword
- Language.ATS: KwWhere :: Keyword
- Language.ATS: KwWhile :: Keyword
- Language.ATS: KwWith :: Keyword
- Language.ATS: Lambda :: AlexPosn -> LambdaType -> Pattern -> Expression -> Expression
- Language.ATS: LambdaAt :: StackFunction -> Expression
- Language.ATS: Leaf :: [Universal] -> String -> [String] -> Maybe Type -> Leaf
- Language.ATS: LeftFix :: AlexPosn -> Fixity
- Language.ATS: LessThan :: BinOp
- Language.ATS: LessThanEq :: BinOp
- Language.ATS: Let :: AlexPosn -> ATS -> (Maybe Expression) -> Expression
- Language.ATS: LinearLambda :: AlexPosn -> LambdaType -> Pattern -> Expression -> Expression
- Language.ATS: ListLiteral :: AlexPosn -> String -> Type -> [Expression] -> Expression
- Language.ATS: Local :: AlexPosn -> ATS -> ATS -> Declaration
- Language.ATS: LogicalAnd :: BinOp
- Language.ATS: LogicalOr :: BinOp
- Language.ATS: MacroBlock :: AlexPosn -> String -> Token
- Language.ATS: MaybeVal :: Type -> Type
- Language.ATS: Minus :: Addendum
- Language.ATS: Mod :: BinOp
- Language.ATS: Mult :: BinOp
- Language.ATS: Mutate :: Expression -> Expression -> Expression
- Language.ATS: Named :: Name -> Type
- Language.ATS: NamedVal :: Name -> Expression
- Language.ATS: Nat :: Type
- Language.ATS: Negate :: UnOp
- Language.ATS: NoArgs :: Arg
- Language.ATS: None :: Addendum
- Language.ATS: NoneType :: AlexPosn -> Type
- Language.ATS: NotEqual :: BinOp
- Language.ATS: Operator :: AlexPosn -> String -> Token
- Language.ATS: OverloadIdent :: AlexPosn -> String -> Name -> (Maybe Int) -> Declaration
- Language.ATS: OverloadOp :: AlexPosn -> BinOp -> Name -> Declaration
- Language.ATS: PLiteral :: Expression -> Pattern
- Language.ATS: PName :: String -> [Pattern] -> Pattern
- Language.ATS: PSum :: String -> Pattern -> Pattern
- Language.ATS: ParenExpr :: AlexPosn -> Expression -> Expression
- Language.ATS: Plain :: AlexPosn -> LambdaType
- Language.ATS: Plus :: Addendum
- Language.ATS: Post :: AlexPosn -> Fixity
- Language.ATS: PrFn :: PreFunction -> Function
- Language.ATS: PrFun :: PreFunction -> Function
- Language.ATS: PrVal :: Pattern -> Expression -> Declaration
- Language.ATS: Praxi :: PreFunction -> Function
- Language.ATS: Pre :: AlexPosn -> Fixity
- Language.ATS: PreF :: Name -> String -> [Universal] -> [Universal] -> [Arg] -> Maybe Type -> Maybe StaticExpression -> Maybe Expression -> PreFunction
- Language.ATS: Precede :: Expression -> Expression -> Expression
- Language.ATS: PrecedeList :: [Expression] -> Expression
- Language.ATS: PrfArg :: Arg -> Arg -> Arg
- Language.ATS: Proof :: AlexPosn -> [Pattern] -> [Pattern] -> Pattern
- Language.ATS: ProofExpr :: AlexPosn -> Expression -> Expression -> Expression
- Language.ATS: ProofImpl :: Implementation -> Declaration
- Language.ATS: ProofType :: AlexPosn -> Type -> Type -> Type
- Language.ATS: PropDef :: AlexPosn -> String -> [Arg] -> Type -> Declaration
- Language.ATS: Qualified :: AlexPosn -> String -> String -> Name
- Language.ATS: RecordValue :: AlexPosn -> [(String, Expression)] -> (Maybe Type) -> Expression
- Language.ATS: RefType :: Type -> Type
- Language.ATS: RightFix :: AlexPosn -> Fixity
- Language.ATS: SCall :: Name -> [StaticExpression] -> StaticExpression
- Language.ATS: SPrecede :: StaticExpression -> StaticExpression -> StaticExpression
- Language.ATS: Second :: b -> Paired a b
- Language.ATS: Sif :: StaticExpression -> StaticExpression -> StaticExpression -> StaticExpression
- Language.ATS: SignatureTok :: AlexPosn -> String -> Token
- Language.ATS: SortDef :: AlexPosn -> String -> Type -> Declaration
- Language.ATS: Spear :: AlexPosn -> LambdaType
- Language.ATS: Special :: AlexPosn -> String -> Token
- Language.ATS: SpecialBracket :: AlexPosn -> Token
- Language.ATS: SpecialName :: AlexPosn -> String -> Name
- Language.ATS: StaVal :: [Universal] -> String -> Type -> Declaration
- Language.ATS: Stacst :: AlexPosn -> Name -> Type -> (Maybe Expression) -> Declaration
- Language.ATS: Stadef :: String -> Name -> [Type] -> Declaration
- Language.ATS: Staload :: (Maybe String) -> String -> Declaration
- Language.ATS: StaticBinary :: BinOp -> StaticExpression -> StaticExpression -> StaticExpression
- Language.ATS: StaticBool :: Bool -> StaticExpression
- Language.ATS: StaticEq :: BinOp
- Language.ATS: StaticInt :: Int -> StaticExpression
- Language.ATS: StaticVal :: Name -> StaticExpression
- Language.ATS: StaticVoid :: AlexPosn -> StaticExpression
- Language.ATS: String :: Type
- Language.ATS: StringLit :: String -> Expression
- Language.ATS: StringTok :: AlexPosn -> String -> Token
- Language.ATS: Sub :: BinOp
- Language.ATS: SumType :: String -> [Arg] -> [Leaf] -> Declaration
- Language.ATS: SumViewType :: String -> [Arg] -> [Leaf] -> Declaration
- Language.ATS: SymIntr :: AlexPosn -> Name -> Declaration
- Language.ATS: T0p :: Addendum -> Type
- Language.ATS: TKind :: AlexPosn -> Name -> String -> Declaration
- Language.ATS: TimeLit :: String -> Expression
- Language.ATS: TimeTok :: AlexPosn -> String -> Token
- Language.ATS: Tuple :: AlexPosn -> [Type] -> Type
- Language.ATS: TupleEx :: AlexPosn -> [Expression] -> Expression
- Language.ATS: TuplePattern :: [Pattern] -> Pattern
- Language.ATS: TypeDef :: AlexPosn -> String -> [Arg] -> Type -> Declaration
- Language.ATS: TypeSignature :: Expression -> Type -> Expression
- Language.ATS: Unary :: UnOp -> Expression -> Expression
- Language.ATS: Unconsumed :: Type -> Type
- Language.ATS: UnderscoreLit :: AlexPosn -> Expression
- Language.ATS: Universal :: [Arg] -> Maybe Type -> Maybe StaticExpression -> Universal
- Language.ATS: UniversalPattern :: AlexPosn -> String -> [Universal] -> Pattern -> Pattern
- Language.ATS: Unnamed :: AlexPosn -> Name
- Language.ATS: Unqualified :: String -> Name
- Language.ATS: Val :: Addendum -> (Maybe Type) -> Pattern -> Expression -> Declaration
- Language.ATS: Var :: (Maybe Type) -> Pattern -> (Maybe Expression) -> (Maybe Expression) -> Declaration
- Language.ATS: ViewAt :: AlexPosn -> Expression -> Expression
- Language.ATS: ViewDef :: AlexPosn -> String -> [Arg] -> Type -> Declaration
- Language.ATS: ViewLiteral :: Addendum -> Type
- Language.ATS: ViewType :: AlexPosn -> Type -> Type
- Language.ATS: ViewTypeDef :: AlexPosn -> String -> [Arg] -> Type -> Declaration
- Language.ATS: Void :: Type
- Language.ATS: VoidLiteral :: AlexPosn -> Expression
- Language.ATS: Vt0p :: Addendum -> Type
- Language.ATS: WhereExp :: Expression -> [Declaration] -> Expression
- Language.ATS: While :: AlexPosn -> Expression -> Expression -> Expression
- Language.ATS: Wildcard :: AlexPosn -> Pattern
- Language.ATS: [_constructorUniversals] :: Leaf -> [Universal]
- Language.ATS: [_exprs] :: Expression -> [Expression]
- Language.ATS: [_leaves] :: Declaration -> [Leaf]
- Language.ATS: [_op] :: Expression -> BinOp
- Language.ATS: [args] :: PreFunction -> [Arg]
- Language.ATS: [arms] :: Expression -> [(Pattern, LambdaType, Expression)]
- Language.ATS: [boundE] :: Existential -> [Arg]
- Language.ATS: [bound] :: Universal -> [Arg]
- Language.ATS: [cond] :: Expression -> Expression
- Language.ATS: [constructorArgs] :: Leaf -> [String]
- Language.ATS: [elseExpr] :: Expression -> Maybe Expression
- Language.ATS: [expression] :: PreFunction -> Maybe Expression
- Language.ATS: [field] :: Expression -> String
- Language.ATS: [fname] :: PreFunction -> Name
- Language.ATS: [iArgs] :: Implementation -> [Arg]
- Language.ATS: [iExpression] :: Implementation -> Expression
- Language.ATS: [isOpen] :: Existential -> Bool
- Language.ATS: [kind] :: Expression -> Addendum
- Language.ATS: [maybeType] :: Leaf -> Maybe Type
- Language.ATS: [nameI] :: Implementation -> Name
- Language.ATS: [name] :: Leaf -> String
- Language.ATS: [new] :: Expression -> Expression
- Language.ATS: [old] :: Expression -> Expression
- Language.ATS: [posE] :: Expression -> AlexPosn
- Language.ATS: [pos] :: Implementation -> AlexPosn
- Language.ATS: [preUniversalsI] :: Implementation -> [Universal]
- Language.ATS: [preUniversals] :: PreFunction -> [Universal]
- Language.ATS: [propE] :: Existential -> Maybe StaticExpression
- Language.ATS: [prop] :: Universal -> Maybe StaticExpression
- Language.ATS: [returnType] :: PreFunction -> Maybe Type
- Language.ATS: [scond] :: StaticExpression -> StaticExpression
- Language.ATS: [selseExpr] :: StaticExpression -> StaticExpression
- Language.ATS: [sig] :: PreFunction -> String
- Language.ATS: [termetric] :: PreFunction -> Maybe StaticExpression
- Language.ATS: [typeArgs] :: Declaration -> [Arg]
- Language.ATS: [typeE] :: Existential -> Maybe Type
- Language.ATS: [typeName] :: Declaration -> String
- Language.ATS: [typeU] :: Universal -> Maybe Type
- Language.ATS: [unATS] :: ATS -> [Declaration]
- Language.ATS: [universalsI] :: Implementation -> [Universal]
- Language.ATS: [universals] :: PreFunction -> [Universal]
- Language.ATS: [val] :: Expression -> Expression
- Language.ATS: [whenTrue] :: Expression -> Expression
- Language.ATS: [wwhenTrue] :: StaticExpression -> StaticExpression
- Language.ATS: constructorUniversals :: Lens' Leaf [Universal]
- Language.ATS: data ATSError a
- Language.ATS: data Addendum
- Language.ATS: data AlexPosn
- Language.ATS: data Arg
- Language.ATS: data BinOp
- Language.ATS: data DataPropLeaf
- Language.ATS: data Declaration
- Language.ATS: data Existential
- Language.ATS: data Expression
- Language.ATS: data Fixity
- Language.ATS: data Function
- Language.ATS: data Implementation
- Language.ATS: data Keyword
- Language.ATS: data LambdaType
- Language.ATS: data Leaf
- Language.ATS: data Name
- Language.ATS: data Paired a b
- Language.ATS: data Pattern
- Language.ATS: data PreFunction
- Language.ATS: data StaticExpression
- Language.ATS: data Token
- Language.ATS: data Type
- Language.ATS: data UnOp
- Language.ATS: data Universal
- Language.ATS: exec :: IO ()
- Language.ATS: getDependencies :: ATS -> [FilePath]
- Language.ATS: leaves :: Traversal' Declaration [Leaf]
- Language.ATS: lexATS :: String -> [Token]
- Language.ATS: newtype ATS
- Language.ATS: parseATS :: [Token] -> Either ATSError String ATS
- Language.ATS: printATS :: ATS -> String
- Language.ATS: printATSCustom :: Float -> Int -> ATS -> String
- Language.ATS: printATSFast :: ATS -> String
+ Language.ATS.Exec: exec :: IO ()
Files
- app/Main.hs +1/−1
- ats-format.cabal +6/−48
- bench/Bench.hs +0/−20
- src/Language/ATS.hs +0/−57
- src/Language/ATS/Exec.hs +22/−4
- src/Language/ATS/Lexer.x +0/−491
- src/Language/ATS/Parser.y +0/−697
- src/Language/ATS/PrettyPrint.hs +0/−547
- src/Language/ATS/Types.hs +0/−361
- stack.yaml +1/−0
- test/Spec.hs +0/−14
- test/data/combinatorics.dats +0/−40
- test/data/combinatorics.out +0/−43
- test/data/concurrency.dats +0/−257
- test/data/concurrency.out +0/−287
- test/data/fact.dats +0/−32
- test/data/fact.out +0/−39
- test/data/factorial.dats +0/−4
- test/data/factorial.out +0/−4
- test/data/fast-combinatorics.dats +0/−93
- test/data/fast-combinatorics.out +0/−94
- test/data/fib.dats +0/−6
- test/data/fib.out +0/−6
- test/data/filecount.dats +0/−31
- test/data/filecount.out +0/−41
- test/data/filetype.out +0/−180
- test/data/filetype.sats +0/−180
- test/data/left-pad.dats +0/−98
- test/data/left-pad.out +0/−76
- test/data/number-theory.dats +0/−167
- test/data/number-theory.out +0/−186
- test/data/numerics.dats +0/−61
- test/data/numerics.out +0/−63
- test/data/polyglot.dats +0/−1235
- test/data/polyglot.out +0/−1619
- test/data/toml-parse.dats +0/−244
- test/data/toml-parse.out +0/−260
- test/data/types.out +0/−24
- test/data/types.sats +0/−23
app/Main.hs view
@@ -1,6 +1,6 @@ module Main where -import Language.ATS (exec)+import Language.ATS.Exec (exec) main :: IO () main = exec
ats-format.cabal view
@@ -1,5 +1,5 @@ name: ats-format-version: 0.2.0.2+version: 0.2.0.4 synopsis: A source-code formatter for ATS description: An opinionated source-code formatter for [ATS](http://www.ats-lang.org/). homepage: https://hub.darcs.net/vmchale/ats-format#readme@@ -14,9 +14,6 @@ data-files: .travis.yml , appveyor.yml , Justfile- , test/data/*.dats- , test/data/*.sats- , test/data/*.out extra-source-files: stack.yaml , cabal.project.local , .atsfmt.toml@@ -41,26 +38,17 @@ library hs-source-dirs: src- exposed-modules: Language.ATS- other-modules: Language.ATS.Types- , Language.ATS.Lexer- , Language.ATS.Parser- , Language.ATS.PrettyPrint- , Language.ATS.Exec- , Paths_ats_format+ exposed-modules: Language.ATS.Exec+ other-modules: Paths_ats_format build-depends: base >= 4.10 && < 5- , array- , lens- , deepseq- , ansi-wl-pprint >= 0.6.8- , recursion-schemes+ , language-ats , optparse-applicative- , ansi-terminal , composition-prelude >= 0.1.1.2 , htoml-megaparsec >= 1.1.0.0- , unordered-containers , text+ , ansi-wl-pprint , directory+ , unordered-containers , process , file-embed build-tools: happy@@ -85,36 +73,6 @@ if impl(ghc >= 8.0) ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat ghc-options: -Wall --test-suite ats-format-test- type: exitcode-stdio-1.0- hs-source-dirs: test- main-is: Spec.hs- build-depends: base- , ats-format- , hspec- , hspec-dirstream- , system-filepath- if flag(development)- ghc-options: -Werror- if impl(ghc >= 8.0)- ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat- ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall - default-language: Haskell2010--benchmark ats-format-bench- type: exitcode-stdio-1.0- hs-source-dirs: bench- main-is: Bench.hs- build-depends: base- , ats-format- , criterion- ghc-options: -Wall - if flag(development)- ghc-options: -Werror- if impl(ghc >= 8.0)- ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat- default-language: Haskell2010 source-repository head type: git
− bench/Bench.hs
@@ -1,20 +0,0 @@-module Main where--import Criterion.Main-import Language.ATS--main :: IO ()-main =- defaultMain [ env envFiles $ \ ~(l, m) ->- bgroup "format"- [ bench "lexATS (large)" $ nf lexATS l- , bench "parseATS . lexATS (large)" $ nf (parseATS . lexATS) l- , bench "printATS . parseATS . lexATS (large)" $ nf (fmap printATS . parseATS . lexATS) l- , bench "lexATS (medium)" $ nf lexATS m- , bench "parseATS . lexATS (medium)" $ nf (parseATS . lexATS) m- , bench "printATS . parseATS . lexATS (medium)" $ nf (fmap printATS . parseATS . lexATS) m- ]- ]- where large = readFile "test/data/polyglot.dats"- medium = readFile "test/data/toml-parse.dats"- envFiles = (,) <$> large <*> medium
− src/Language/ATS.hs
@@ -1,57 +0,0 @@--- | Main module for the library-module Language.ATS ( -- * Functions for working with syntax- lexATS- , parseATS- , printATS- , printATSCustom- , printATSFast- -- * Library functions- , getDependencies- -- * Syntax Tree- , ATS (..)- , Declaration (..)- , Expression (..)- , Type (..)- , Function (..)- , Implementation (..)- , Pattern (..)- , Name (..)- , UnOp (..)- , BinOp (..)- , DataPropLeaf (..)- , Leaf (..)- , Arg (..)- , Addendum (..)- , LambdaType (..)- , Universal (..)- , Existential (..)- , PreFunction (..)- , StaticExpression (..)- , Paired (..)- , Fixity (..)- -- * Lexical types- , Token (..)- , AlexPosn (..)- , Keyword (..)- -- * Error types- , ATSError- -- * Lenses- , leaves- , constructorUniversals- -- * Library functions- -- * Executable- , exec- ) where--import Data.Maybe (catMaybes)-import Language.ATS.Exec-import Language.ATS.Lexer-import Language.ATS.Parser-import Language.ATS.PrettyPrint-import Language.ATS.Types--getDependencies :: ATS -> [FilePath]-getDependencies (ATS ds) = catMaybes (g <$> ds)- where g (Staload _ s) = Just s- g (Include s) = Just s- g _ = Nothing
src/Language/ATS/Exec.hs view
@@ -4,6 +4,7 @@ module Language.ATS.Exec ( exec ) where +import Control.Arrow hiding ((<+>)) import Control.Monad (unless, (<=<)) import Data.FileEmbed (embedStringFile) import qualified Data.HashMap.Lazy as HM@@ -11,10 +12,7 @@ import Data.Monoid ((<>)) import qualified Data.Text.IO as TIO import Data.Version-import Language.ATS.Lexer (lexATS)-import Language.ATS.Parser (ATSError, parseATS)-import Language.ATS.PrettyPrint (printATS, printATSCustom, processClang)-import Language.ATS.Types (ATS)+import Language.ATS import Options.Applicative import Paths_ats_format import System.Directory (doesFileExist)@@ -23,8 +21,28 @@ import Text.PrettyPrint.ANSI.Leijen (pretty) import Text.Toml import Text.Toml.Types hiding (Parser)+import System.Process (readCreateProcess, shell) data Program = Program { _path :: Maybe FilePath, _inplace :: Bool, _noConfig :: Bool, _defaultConfig :: Bool }++takeBlock :: String -> (String, String)+takeBlock ('%':'}':ys) = ("", ('%':) . ('}':) $ ys)+takeBlock (y:ys) = first (y:) $ takeBlock ys+takeBlock [] = ([], [])++rest :: String -> IO String+rest xs = fmap (<> (snd $ takeBlock xs)) $ printClang (fst $ takeBlock xs)++printClang :: String -> IO String+printClang = readCreateProcess (shell "clang-format")++processClang :: String -> IO String+processClang ('%':'{':'^':xs) = fmap (('%':) . ('{':) . ('^':)) $ rest xs+processClang ('%':'{':'#':xs) = fmap (('%':) . ('{':) . ('#':)) $ rest xs+processClang ('%':'{':'$':xs) = fmap (('%':) . ('{':) . ('$':)) $ rest xs+processClang ('%':'{':xs) = fmap (('%':) . ('{':)) $ rest xs+processClang (x:xs) = fmap (x:) $ processClang xs+processClang [] = pure [] file :: Parser Program file = Program
− src/Language/ATS/Lexer.x
@@ -1,491 +0,0 @@-{-- {-# OPTIONS_GHC -fno-warn-unused-matches -fno-warn-incomplete-uni-patterns #-}- {-# LANGUAGE DeriveGeneric #-}- {-# LANGUAGE DeriveAnyClass #-}- {-# LANGUAGE DeriveDataTypeable #-}- {-# LANGUAGE StandaloneDeriving #-}- {-# LANGUAGE OverloadedStrings #-}-- -- | Module exporting the lexer itself as well as several data types for- -- working with tokens.- module Language.ATS.Lexer ( AlexPosn (..)- , Token (..)- , Keyword (..)- , Addendum (..)- , lexATS- , token_posn- , to_string- , get_addendum- ) where--import Data.Data (Typeable, Data)-import Data.Char (toUpper, toLower)-import Control.Lens (over, _head)-import Control.DeepSeq (NFData)-import GHC.Generics (Generic)-import Text.PrettyPrint.ANSI.Leijen hiding (line, column, (<$>))--}--%wrapper "posn"---- Digits-$digit = 0-9-$octal = 0-7---- Characters-$special = [\+\-\&\|\[\]\{\}\(\)\_\=\!\%\^\$\@\;\~\,\.\\\#]-$alpha = [a-zA-Z]-$terminal = $printable # $white-$esc_char = \27-@escape_ch = \\ ([nt\'\\] | $octal+)-@escape_str = \\ ([nt\"\\] | $octal+)-@char = ($terminal # [\\\']) | " " | @escape_ch | $esc_char-@char_lit = \' @char \'--$br = [\<\>]---- Boolean literals-@bool = (true | false)---- Integer-@integer = $digit+-@time_lit = $digit+ u---- Floats-@decimals = $digit+-@float = @decimals \. @decimals---- Strings-@string = \" ($printable # [\"\\] | @escape_str | $esc_char | \n)* \"---- Identifiers-@identifier = ($alpha | _) ($alpha | $digit | _ | ! | ' | \$)*---- Multi-line comments-@not_close_paren = (\*+ [^\)] | [^\*] \))-@paren_comment = \(\* ([^\)\*] | @not_close_paren | \n)* \*\)-@not_close_slash = (\*+ [^\/] | [^\*] \/)-@slash_comment = \/\* ([^\/\*] | @not_close_slash | \n)* \*\/-@block_comment = @paren_comment | @slash_comment--@if_block = "#if" ([^\#] | "#then" | "#print" | \n)+ "#endif" .*---- FIXME this is a disaster lol-@ref_call = ($alpha | $digit | "(" | ")" | _ | (","))+ ">"--@not_close_c = \% [^\}]-@c_block = \%\{ ("#" | "$" | "^" | "") ([^\%] | @not_close_c | \n)* \%\}--@inner_signature = ("!wrt" | "!exn" | "!exnwrt" | "0" | "1" | "!all" | "!laz" | "lin" | "fun" | "clo" | "cloptr" | "cloref" | "!ntm" | "!ref" | "prf" | "fe" | @block_comment)-@inner_signature_mult = (@inner_signature (("," | "") @inner_signature)*) | ""--@lambda = "=>" | "=>>" | "=<" @inner_signature_mult ">"-@signature = ":<" @inner_signature_mult ">" | ":"-@func_type = "->" | "-<" @inner_signature_mult ">"--@at_brace = \@ ($white | @block_comment)* \{--@operator = "**" | "+" | "-" | "*" | "/" | ".." | "!=" | ">=" | "<=" | "==" | "=" | "~" | "%" | "&&" | "||" | ":=" | ".<" | ">." | "<" | ">" | ">>" | "?" | "?!" | "#[" -- TODO context so tilde doesn't follow--@double_parens = "(" @block_comment ")" | "()"-@double_braces = "{" @block_comment "}" | "{}"-@double_brackets = "<" @block_comment ">" | "<>"--@view = v | view--@fixity_decl = "infixr" | "infixl" | "prefix" | "postfix"--tokens :--- $white+ ;- ^ @block_comment { tok (\p s -> CommentLex p s) }- ^ "//".* { tok (\p s -> CommentLex p s) }- "//".* ;- @block_comment ;- "#define".* { tok (\p s -> MacroBlock p s) } - @if_block { tok (\p s -> MacroBlock p s) } - @c_block { tok (\p s -> CBlockLex p s) }- fun { tok (\p s -> Keyword p KwFun) }- fn { tok (\p s -> Keyword p KwFn) }- fnx { tok (\p s -> Keyword p KwFnx) }- and { tok (\p s -> Keyword p KwAnd) }- prval { tok (\p s -> Keyword p KwPrval) }- prfn { tok (\p s -> Keyword p KwPrfn) }- prfun { tok (\p s -> Keyword p KwPrfun) }- datatype { tok (\p s -> Keyword p KwDatatype) }- data @view type { tok (\p s -> Keyword p KwDatavtype) }- dataview { tok (\p s -> Keyword p KwDataview) }- dataprop { tok (\p s -> Keyword p KwDataprop) }- assume { tok (\p s -> Keyword p KwAssume) }- typedef { tok (\p s -> Keyword p KwTypedef) }- @view typedef { tok (\p s -> Keyword p KwVtypedef) }- absprop { tok (\p s -> Keyword p KwAbsprop) }- llam { tok (\p s -> Keyword p KwLinearLambda) }- lam { tok (\p s -> Keyword p KwLambda) }- staload { tok (\p s -> Keyword p KwStaload) }- let { tok (\p s -> Keyword p KwLet) }- in { tok (\p s -> Keyword p KwIn) }- end { tok (\p s -> Keyword p KwEnd) }- case"+" { tok (\p s -> Keyword p (KwCase Plus)) }- case"-" { tok (\p s -> Keyword p (KwCase Minus)) }- case { tok (\p s -> Keyword p (KwCase None)) }- castfn { tok (\p s -> Keyword p KwCastfn) }- val"+" { tok (\p s -> Keyword p (KwVal Plus)) } -- TODO also val@ ?- val"-" { tok (\p s -> Keyword p (KwVal Minus)) } - val { tok (\p s -> Keyword p (KwVal None)) }- var { tok (\p s -> Keyword p KwVar) }- int { tok (\p s -> Keyword p KwInt) }- if { tok (\p s -> Keyword p KwIf) }- sif { tok (\p s -> Keyword p KwSif) }- then { tok (\p s -> Keyword p KwThen) }- else { tok (\p s -> Keyword p KwElse) }- string { tok (\p s -> Keyword p KwString) }- bool { tok (\p s -> Keyword p KwBool) }- void { tok (\p s -> Keyword p KwVoid) }- nat { tok (\p s -> Keyword p KwNat) }- implement { tok (\p s -> Keyword p KwImplement) }- implmnt { tok (\p s -> Keyword p KwImplement) }- primplmnt { tok (\p s -> Keyword p KwProofImplement) }- primplement { tok (\p s -> Keyword p KwProofImplement) }- abst"@"ype { tok (\p s -> Keyword p (KwAbst0p None)) }- abst"@ype+" { tok (\p s -> Keyword p (KwAbst0p Plus)) }- abst"@type-" { tok (\p s -> Keyword p (KwAbst0p Minus)) }- abs@view"t@ype" { tok (\p s -> Keyword p (KwAbsvt0p None)) }- t"@"ype"+" { tok (\p s -> Keyword p (KwT0p Plus)) }- t"@"ype"-" { tok (\p s -> Keyword p (KwT0p Minus)) }- t"@"ype { tok (\p s -> Keyword p (KwT0p None)) }- @view"t@ype+" { tok (\p s -> Keyword p (KwVt0p Plus)) }- @view"t@ype-" { tok (\p s -> Keyword p (KwVt0p Minus)) }- @view"t@ype" { tok (\p s -> Keyword p (KwVt0p None)) }- abstype { tok (\p s -> Keyword p KwAbstype) }- abs @view type { tok (\p s -> Keyword p KwAbsvtype) }- absview { tok (\p s -> Keyword p KwAbsview) }- view { tok (\p s -> Keyword p (KwView None)) }- view"+" { tok (\p s -> Keyword p (KwView Plus)) }- view"-" { tok (\p s -> Keyword p (KwView Minus)) }- viewdef { tok (\p s -> Keyword p KwViewdef) }- "#"include { tok (\p s -> Keyword p KwInclude) }- when { tok (\p s -> Keyword p KwWhen) }- of { tok (\p s -> Keyword p KwOf) }- stadef { tok (\p s -> Keyword p KwStadef) }- stacst { tok (\p s -> Keyword p KwStacst) }- local { tok (\p s -> Keyword p KwLocal) }- praxi { tok (\p s -> Keyword p KwPraxi) }- while { tok (\p s -> Keyword p KwWhile) }- where { tok (\p s -> Keyword p KwWhere) }- begin { tok (\p s -> Keyword p KwBegin) }- overload { tok (\p s -> Keyword p KwOverload) }- with { tok (\p s -> Keyword p KwWith) }- char { tok (\p s -> Keyword p KwChar) }- extern { tok (\p s -> Keyword p KwExtern) }- sortdef { tok (\p s -> Keyword p KwSortdef) }- propdef { tok (\p s -> Keyword p KwPropdef) }- tkindef { tok (\p s -> Keyword p KwTKind) }- typekindef { tok (\p s -> Keyword p KwTKind) }- "$raise" { tok (\p s -> Keyword p KwRaise) }- mod { tok (\p s -> Keyword p KwMod) }- "println!" { tok (\p s -> Identifier p s) }- "prerrln!" { tok (\p s -> Identifier p s) }- "fix@" { tok (\p s -> Keyword p KwFixAt) }- "lam@" { tok (\p s -> Keyword p KwLambdaAt) }- "addr" { tok (\p s -> Keyword p KwAddr) }- "addr@" { tok (\p s -> Keyword p KwAddrAt) }- "view@" { tok (\p s -> Keyword p KwViewAt) }- sta { tok (\p s -> Keyword p KwSta) }- symintr { tok (\p s -> Keyword p KwSymintr) }- absview { tok (\p s -> Keyword p KwAbsview) }- "$list" { tok (\p s -> Keyword p (KwListLit "")) }- "$list_vt" { tok (\p s -> Keyword p (KwListLit "_vt")) }- "fold@" { tok (\p s -> IdentifierSpace p s) }- "free@" { tok (\p s -> Identifier p s) }- @fixity_decl { tok (\p s -> FixityTok p s) }- @double_parens { tok (\p s -> DoubleParenTok p) }- @double_braces { tok (\p s -> DoubleBracesTok p) }- @double_brackets { tok (\p s -> DoubleBracketTok p) }- @char_lit { tok (\p s -> CharTok p (toChar s)) }- @lambda { tok (\p s -> Arrow p s) }- @func_type { tok (\p s -> FuncType p s) }- @bool { tok (\p s -> BoolTok p (read (over _head toUpper s)))}- @time_lit { tok (\p s -> TimeTok p s) }- @integer { tok (\p s -> IntTok p (read s)) } -- FIXME shouldn't fail silenty on overflow- @float { tok (\p s -> FloatTok p (read s)) }- $br / @ref_call { tok (\p s -> SpecialBracket p) }- @at_brace { tok (\p s -> Operator p "@{") } -- FIXME this is kinda sloppy- @operator { tok (\p s -> Operator p s) }- @signature { tok (\p s -> SignatureTok p (tail s)) }- $special { tok (\p s -> Special p s) }- "effmask_all" { tok (\p s -> Identifier p s) }- "effmask_wrt" { tok (\p s -> Identifier p s) }- "extype" { tok (\p s -> Identifier p s) }- @identifier / " " { tok (\p s -> IdentifierSpace p s) }- @identifier { tok (\p s -> Identifier p s) }- @string { tok (\p s -> StringTok p s) }--{--deriving instance Generic AlexPosn-deriving instance NFData AlexPosn-deriving instance Data AlexPosn-deriving instance Typeable AlexPosn--tok f p s = f p s---- | Determines the default behavior for incomplete pattern matches-data Addendum = None- | Plus- | Minus- deriving (Eq, Show, Generic, NFData, Data, Typeable)--get_addendum (Keyword _ (KwVal a)) = a-get_addendum _ = None--data Keyword = KwFun- | KwFnx- | KwAnd- | KwDatatype- | KwDatavtype- | KwAssume- | KwTypedef- | KwVtypedef- | KwStaload- | KwLet- | KwIn- | KwLocal- | KwEnd- | KwImplement- | KwCase Addendum- | KwIf- | KwSif- | KwThen- | KwElse- | KwString- | KwBool- | KwInt- | KwVoid- | KwNat- | KwVal Addendum- | KwVar- | KwLambda- | KwLinearLambda- | KwInclude- | KwWhen- | KwOf- | KwAbsprop- | KwPrval- | KwStadef- | KwPraxi- | KwWhile- | KwWhere- | KwBegin- | KwOverload- | KwWith- | KwChar- | KwDataview- | KwDataprop- | KwView Addendum- | KwAbstype- | KwType- | KwAbst0p Addendum- | KwAbsvt0p Addendum- | KwT0p Addendum- | KwVt0p Addendum- | KwPrfun- | KwPrfn- | KwCastfn- | KwExtern- | KwAbsvtype- | KwProofImplement- | KwSortdef- | KwPropdef- | KwRaise- | KwTKind- | KwMod- | KwFixAt- | KwLambdaAt- | KwAddrAt- | KwAddr- | KwSta- | KwViewAt- | KwViewdef- | KwSymintr- | KwAbsview- | KwFn- | KwInfix- | KwInfixr- | KwInfixl- | KwStacst- | KwListLit String- deriving (Eq, Show, Generic, NFData)--data Token = Identifier AlexPosn String- | Keyword AlexPosn Keyword- | BoolTok AlexPosn Bool- | IntTok AlexPosn Int- | FloatTok AlexPosn Float- | CharTok AlexPosn Char- | StringTok AlexPosn String- | Special AlexPosn String- | CBlockLex AlexPosn String- | IdentifierSpace AlexPosn String- | Operator AlexPosn String- | Arrow AlexPosn String- | FuncType AlexPosn String- | CommentLex AlexPosn String- | MacroBlock AlexPosn String- | TimeTok AlexPosn String- | SignatureTok AlexPosn String- | DoubleParenTok AlexPosn- | DoubleBracesTok AlexPosn- | DoubleBracketTok AlexPosn- | SpecialBracket AlexPosn- | FixityTok AlexPosn String- deriving (Eq, Show, Generic, NFData)--instance Pretty Addendum where- pretty Plus = "+"- pretty Minus = "-"- pretty None = ""--instance Pretty Keyword where- pretty KwFun = "fun"- pretty KwAnd = "and"- pretty KwDatatype = "datatype"- pretty KwDatavtype = "datavtype" -- FIXME this wrongly squashes dataviewtype- pretty KwFnx = "fnx"- pretty KwAssume = "assume"- pretty KwTypedef = "typedef"- pretty KwVtypedef = "vtypedef"- pretty KwStaload = "stload"- pretty KwLet = "let"- pretty KwWhere = "where"- pretty KwLocal = "local"- pretty KwEnd = "end"- pretty KwBegin = "begin"- pretty KwIn = "in"- pretty KwImplement = "implement"- pretty (KwCase c) = "case" <> pretty c- pretty KwIf = "if"- pretty KwSif = "sif"- pretty KwThen = "then"- pretty KwElse = "else"- pretty KwString = "string"- pretty KwBool = "bool"- pretty KwInt = "int"- pretty KwVoid = "void"- pretty KwNat = "nat"- pretty (KwVal c) = "val" <> pretty c- pretty KwVar = "var"- pretty KwLambda = "lam"- pretty KwLinearLambda = "llam"- pretty KwInclude = "include"- pretty KwWhen = "when"- pretty KwOf = "of"- pretty KwAbsprop = "absprop"- pretty KwPrval = "prval"- pretty KwStadef = "stadef"- pretty KwPraxi = "praxi"- pretty KwWhile = "while"- pretty KwOverload = "overload"- pretty KwWith = "with"- pretty KwChar = "char"- pretty KwDataview = "dataview"- pretty KwDataprop = "dataprop"- pretty (KwView c) = "view" <> pretty c- pretty KwAbstype = "abstype"- pretty KwAbsvtype = "absvtype"- pretty KwType = "type"- pretty (KwAbst0p c) = "abst@ype" <> pretty c- pretty (KwAbsvt0p c) = "absvt@ype" <> pretty c- pretty (KwT0p c) = "t@ype" <> pretty c- pretty (KwVt0p c) = "vt@ype" <> pretty c- pretty KwPrfun = "prfun"- pretty KwPrfn = "prfn"- pretty KwCastfn = "castfn"- pretty KwExtern = "extern"- pretty KwRaise = "$raise"- pretty KwProofImplement = "primplmnt"- pretty KwSortdef = "sortdef"- pretty KwPropdef = "propdef"- pretty KwTKind = "tkind"- pretty KwMod = "mod"- pretty KwFixAt = "fix@"- pretty KwLambdaAt = "lam@"- pretty KwAddrAt = "addr@"- pretty KwAddr = "addr"- pretty KwSta = "sta"- pretty KwStacst = "stacst"- pretty KwViewAt = "view@"- pretty KwViewdef = "viewdef"- pretty KwSymintr = "symintr"- pretty KwAbsview = "absview"- pretty KwFn = "fn"- pretty KwInfix = "infix"- pretty KwInfixr = "infixr"- pretty KwInfixl = "infixl"- pretty (KwListLit s) = "list" <> string s--instance Pretty Token where- pretty (Identifier _ s) = text s- pretty (IdentifierSpace _ s) = text s- pretty (Keyword _ kw) = pretty kw- pretty (BoolTok _ b) = text $ over _head toLower (show b)- pretty (IntTok _ i) = pretty i- pretty (FloatTok _ x) = pretty x- pretty (CharTok _ c) = squotes (pretty c)- pretty (StringTok _ s) = dquotes (text s)- pretty (Special _ s) = text s- pretty CBlockLex{} = "%{"- pretty (Arrow _ s) = text s- pretty (CommentLex _ s) = text $ take 2 s- pretty (FuncType _ s) = text s- pretty (TimeTok _ s) = text s- pretty (SignatureTok _ s) = ":" <> text s- pretty (Operator _ s) = text s- pretty (MacroBlock _ s) = "#"- pretty DoubleParenTok{} = "()"- pretty DoubleBracesTok{} = "{}"- pretty DoubleBracketTok{} = "<>"- pretty SpecialBracket{} = "<"- pretty (FixityTok _ s) = text s--to_string (CommentLex _ s) = s-to_string (Identifier _ s) = s-to_string (IdentifierSpace _ s) = s-to_string _ = mempty--token_posn (Identifier p _) = p-token_posn (IdentifierSpace p _) = p-token_posn (Keyword p _) = p-token_posn (BoolTok p _) = p-token_posn (IntTok p _) = p-token_posn (FloatTok p _) = p-token_posn (StringTok p _) = p-token_posn (Special p _) = p-token_posn (CBlockLex p _) = p-token_posn (Operator p _) = p-token_posn (Arrow p _) = p-token_posn (FuncType p _) = p-token_posn (CharTok p _) = p-token_posn (CommentLex p _) = p-token_posn (MacroBlock p _) = p-token_posn (TimeTok p _) = p-token_posn (SignatureTok p _) = p-token_posn (DoubleParenTok p) = p-token_posn (DoubleBracesTok p) = p-token_posn (DoubleBracketTok p) = p-token_posn (SpecialBracket p) = p-token_posn (FixityTok p _) = p--toChar :: String -> Char-toChar "'\\n'" = '\n'-toChar "'\\t'" = '\t'-toChar "'\\\\'" = '\\'-toChar x = x !! 1---- | This function turns a string into a stream of tokens for the parser.-lexATS :: String -> [Token]-lexATS = alexScanTokens--}
− src/Language/ATS/Parser.y
@@ -1,697 +0,0 @@-{- {-# LANGUAGE OverloadedStrings #-}- {-# LANGUAGE DeriveGeneric #-}- {-# LANGUAGE DeriveAnyClass #-}- {-# LANGUAGE FlexibleContexts #-}-- -- | This module contains the parser.- module Language.ATS.Parser ( parseATS- , ATSError- ) where--import Language.ATS.Types-import Language.ATS.Lexer ( Token (..)- , AlexPosn (..)- , Keyword (..)- , Addendum (..)- , token_posn- , to_string- , get_addendum- )--import Data.Char (toLower)-import Control.DeepSeq (NFData)-import Control.Lens (over, _head)-import GHC.Generics (Generic)-import Prelude-import Text.PrettyPrint.ANSI.Leijen hiding ((<$>))--}--%name parseATS-%tokentype { Token }-%error { parseError }-%monad { Either (ATSError String) } { (>>=) } { pure }--%token- fun { Keyword $$ KwFun }- fn { Keyword $$ KwFn }- castfn { Keyword $$ KwCastfn }- prfun { Keyword $$ KwPrfun }- prfn { Keyword $$ KwPrfn }- fnx { Keyword $$ KwFnx }- and { Keyword $$ KwAnd }- lambda { Keyword $$ KwLambda }- llambda { Keyword $$ KwLinearLambda }- if { Keyword $$ KwIf }- sif { Keyword $$ KwSif }- stadef { Keyword $$ KwStadef }- val { $$@(Keyword _ (KwVal _)) }- prval { Keyword $$ KwPrval }- var { Keyword $$ KwVar }- then { Keyword $$ KwThen }- let { Keyword $$ KwLet }- typedef { Keyword $$ KwTypedef }- vtypedef { Keyword $$ KwVtypedef }- absview { Keyword $$ KwAbsview }- absvtype { Keyword $$ KwAbsvtype }- abstype { Keyword $$ KwAbstype }- abst0p { Keyword $$ (KwAbst0p None) }- absvt0p { Keyword $$ (KwAbsvt0p None) }- viewdef { Keyword $$ KwViewdef }- in { Keyword $$ KwIn }- end { Keyword $$ KwEnd }- stringType { Keyword $$ KwString }- charType { Keyword $$ KwChar }- voidType { Keyword $$ KwVoid }- implement { Keyword $$ KwImplement }- primplmnt { Keyword $$ KwProofImplement }- else { Keyword $$ KwElse }- bool { Keyword $$ KwBool }- int { Keyword $$ KwInt }- nat { Keyword $$ KwNat }- addr { Keyword $$ KwAddr }- when { Keyword $$ KwWhen }- begin { Keyword $$ KwBegin }- case { Keyword _ (KwCase $$) }- datatype { Keyword $$ KwDatatype }- datavtype { Keyword $$ KwDatavtype }- while { Keyword $$ KwWhile }- of { Keyword $$ KwOf }- include { Keyword $$ KwInclude }- staload { Keyword $$ KwStaload }- overload { Keyword $$ KwOverload }- with { Keyword $$ KwWith }- dataprop { Keyword $$ KwDataprop }- praxi { Keyword $$ KwPraxi }- extern { Keyword $$ KwExtern }- t0pPlain { Keyword $$ (KwT0p None) }- t0pCo { Keyword $$ (KwT0p Plus) }- vt0pCo { Keyword $$ (KwVt0p Plus) }- vt0pPlain { Keyword $$ (KwVt0p None) }- where { Keyword $$ KwWhere }- absprop { Keyword $$ KwAbsprop }- sortdef { Keyword $$ KwSortdef }- local { Keyword $$ KwLocal }- view { Keyword $$ (KwView None) }- viewPlusMinus { Keyword _ (KwView $$) }- raise { Keyword $$ KwRaise }- tkindef { Keyword $$ KwTKind }- assume { Keyword $$ KwAssume }- addrAt { Keyword $$ KwAddrAt }- viewAt { Keyword $$ KwViewAt }- symintr { Keyword $$ KwSymintr }- stacst { Keyword $$ KwStacst }- propdef { Keyword $$ KwPropdef }- list { Keyword $$ (KwListLit "") }- list_vt { Keyword $$ (KwListLit "_vt") }- boolLit { BoolTok _ $$ }- timeLit { TimeTok _ $$ }- intLit { IntTok _ $$ }- floatLit { FloatTok _ $$ }- effmaskWrt { Identifier $$ "effmask_wrt" }- effmaskAll { Identifier $$ "effmask_all" }- extype { Identifier $$ "extype" }- extfcall { Identifier $$ "extfcall" }- ldelay { Identifier $$ "ldelay" }- listVT { Identifier $$ "list_vt" }- foldAt { Identifier $$ "fold@" }- identifier { $$@Identifier{} }- identifierSpace { $$@IdentifierSpace{} }- closeParen { Special $$ ")" }- openParen { Special $$ "(" }- colon { SignatureTok $$ "" }- signature { SignatureTok _ $$ }- comma { Special $$ "," }- percent { Operator $$ "%" }- geq { Operator $$ ">=" }- leq { Operator $$ "<=" }- neq { Operator $$ "!=" }- openTermetric { Operator $$ ".<" }- closeTermetric { Operator $$ ">." }- mutateArrow { FuncType $$ "->" }- mutateEq { Operator $$ ":=" }- lbracket { Operator $$ "<" }- rbracket { Operator $$ ">" }- eq { Operator $$ "=" }- or { Operator $$ "||" }- vbar { Special $$ "|" }- lbrace { Special $$ "{" }- rbrace { Special $$ "}" }- funcArrow { FuncType _ $$ }- plainArrow { Arrow $$ "=>" }- cloref1Arrow { Arrow $$ "=<cloref1>" }- cloptr1Arrow { Arrow $$ "=<cloptr1>" }- lincloptr1Arrow { Arrow $$ "=<lincloptr1>" }- spear { Arrow $$ "=>>" }- lsqbracket { Special $$ "[" }- rsqbracket { Special $$ "]" }- string { StringTok _ $$ }- charLit { CharTok _ $$ }- underscore { Special $$ "_" }- minus { Operator $$ "-" }- plus { Operator $$ "+" }- div { Operator $$ "/" }- mult { Operator $$ "*" }- exclamation { Special $$ "!" }- dot { Special $$ "." }- at { Special $$ "@" }- tilde { Operator $$ "~" }- dollar { Special $$ "$" }- semicolon { Special $$ ";" }- andOp { Operator $$ "&&" }- doubleEq { Operator $$ "==" }- doubleDot { Operator $$ ".." }- doubleParens { DoubleParenTok $$ }- doubleBraces { DoubleBracesTok $$ }- doubleBrackets { DoubleBracketTok $$ }- prfTransform { Operator $$ ">>" } -- For types like &a >> a?!- refType { Special $$ "&" } -- For types like &a- maybeProof { Operator $$ "?" } -- For types like a?- fromVT { Operator $$ "?!" } -- For types like a?!- openExistential { Operator $$ "#[" } -- Same as `[` in ATS2- cblock { CBlockLex _ $$ }- define { MacroBlock _ $$ }- lineComment { $$@CommentLex{} }- lspecial { SpecialBracket $$ }- atbrace { Operator $$ "@{" }- exp { Operator $$ "**" }- mod { Keyword $$ KwMod }- fixAt { Keyword $$ KwFixAt }- lamAt { Keyword $$ KwLambdaAt }- infixr { FixityTok $$ "infixr" }- infixl { FixityTok $$ "infixr" }- prefix { FixityTok $$ "prefix" }- postfix { FixityTok $$ "postfix" }--%%--ATS : Declarations { ATS $1 }---- | Parse declarations in a list-Declarations : { [] } - | Declarations Declaration { $2 : $1 }- | Declarations FunDecl { $2 ++ $1 }- | Declarations local ATS in ATS end { Local $2 $3 $5 : $1 }---- | Several comma-separated types-TypeIn : Type { [$1] }- | TypeIn comma Type { $3 : $1 }---- | Several comma-separated types or static expressions-TypeInExpr : TypeIn { $1 }- | StaticExpression { [ConcreteType $1] }- | TypeInExpr comma Type { $3 : $1 }- | TypeInExpr comma StaticExpression { ConcreteType $3 : $1 }---- | Parse a type-Type : Name openParen TypeInExpr closeParen { Dependent $1 $3 }- | identifierSpace openParen TypeInExpr closeParen { Dependent (Unqualified $ to_string $1) $3 }- | bool { Bool }- | int { Int }- | nat { Nat }- | addr { Addr }- | stringType { String }- | charType { Char }- | voidType { Void }- | t0pPlain { T0p None }- | t0pCo { T0p Plus }- | vt0pPlain { Vt0p None }- | vt0pCo { Vt0p Plus }- | stringType openParen StaticExpression closeParen { DepString $3 }- | stringType StaticExpression { DepString $2 }- | int openParen StaticExpression closeParen { DependentInt $3 }- | bool openParen StaticExpression closeParen { DependentBool $3 }- | identifierSpace { Named (Unqualified $ to_string $1) }- | Name { Named $1 }- | exclamation Type { Unconsumed $2 }- | Type mutateArrow Type { FunctionType "->" $1 $3 }- | Type funcArrow Type { FunctionType $2 $1 $3 }- | refType Type { RefType $2 }- | Type maybeProof { MaybeVal $1 } - | Type fromVT { FromVT $1 }- | Type prfTransform Type { AsProof $1 (Just $3) }- | Type prfTransform underscore { AsProof $1 Nothing }- | view at Type { ViewType $1 $3 }- | viewPlusMinus { ViewLiteral $1 }- | view { ViewLiteral None }- | Existential Type { Ex $1 $2 }- | Universal Type { ForA $1 $2 }- | Type at Type { At $2 (Just $1) $3 }- | at Type { At $1 Nothing $2 }- | atbrace Records rbrace { AnonymousRecord $1 $2 }- | openParen Type vbar Type closeParen { ProofType $1 $2 $4 }- | identifierSpace identifier { Dependent (Unqualified $ to_string $1) [Named (Unqualified $ to_string $2)] }- | openParen TypeIn closeParen { Tuple $1 $2 }- | openParen Type closeParen { $2 }- | int StaticExpression { DependentInt $2 }- | doubleParens { NoneType $1 }- | minus {% Left $ Expected $1 "Type" "-" }- | dollar {% Left $ Expected $1 "Type" "$" }- | int identifier openParen {% Left $ Expected (token_posn $2) "Static integer expression" (to_string $2) }--FullArgs : Args { $1 }---- | A comma-separated list of arguments-Args : Arg { [$1] }- | FullArgs comma Arg vbar Arg { PrfArg $3 $5 : $1 }- | Args comma Arg { $3 : $1 }- | Arg vbar Arg { [ PrfArg $1 $3 ] }--TypeArg : identifier { Arg (First $ to_string $1) }- | IdentifierOr colon Type { Arg (Both $1 $3) }- | Type { Arg (Second $1) }--Arg : TypeArg { $1 }- | StaticExpression { Arg (Second (ConcreteType $1)) }---- | Parse a literal-Literal : boolLit { BoolLit $1 }- | timeLit { TimeLit $1 }- | intLit { IntLit $1 }- | floatLit { FloatLit $1 }- | string { StringLit $1 }- | charLit { CharLit $1 }- | doubleParens { VoidLiteral $1 }---- | Parse a list of comma-separated patterns-PatternIn : Pattern { [$1] }- | PatternIn comma Pattern { $3 : $1 }---- | Parse a pattern match-Pattern : identifier { PName (to_string $1) [] }- | identifierSpace { PName (to_string $1) [] }- | underscore { Wildcard $1 }- | identifier doubleParens { PName (to_string $1 ++ "()") [] }- | tilde Pattern { Free $2 }- | identifier openParen PatternIn closeParen { PName (to_string $1) $3 }- | identifier Pattern { PSum (to_string $1) $2 }- | identifierSpace Pattern { PSum (to_string $1) $2 }- | openParen PatternIn vbar PatternIn closeParen { Proof $1 $2 $4 }- | openParen PatternIn closeParen { TuplePattern $2 }- | Literal { PLiteral $1 }- | Pattern when Expression { Guarded $2 $3 $1 }- | at Pattern { AtPattern $1 $2 }- | identifier Universals Pattern { UniversalPattern (token_posn $1) (to_string $1) $2 $3 }- | identifierSpace Universals Pattern { UniversalPattern (token_posn $1) (to_string $1) $2 $3 }- | Existential Pattern { ExistentialPattern $1 $2 }- | minus {% Left $ Expected $1 "Pattern" "-" }- | plus {% Left $ Expected $1 "Pattern" "+" }---- | Parse a case expression-Case : vbar Pattern CaseArrow Expression { [($2, $3, $4)] }- | Pattern CaseArrow Expression { [($1, $2, $3)] }- | Case vbar Pattern CaseArrow Expression { ($3, $4, $5) : $1 }--ExpressionPrf : ExpressionIn { (Nothing, $1) }- | Expression vbar ExpressionIn { (Just $1, $3) } -- FIXME only passes one proof?---- | A list of comma-separated expressions-ExpressionIn : Expression { [$1] }- | ExpressionIn comma Expression { $3 : $1 }--Tuple : PreExpression comma PreExpression { [$3, $1] }- | Tuple comma PreExpression { $3 : $1 }---- | Parse an arrow in a case statement-CaseArrow : plainArrow { Plain $1 }- | spear { Spear $1 }- | minus {% Left $ Expected $1 "Arrow" "-" }- | eq {% Left $ Expected $1 "Arrow" "=" }- | minus {% Left $ Expected $1 "Arrow" "-" }--LambdaArrow : plainArrow { Plain $1 }- | cloref1Arrow { Full $1 "cloref1" } -- TODO do this more efficiently.- | cloptr1Arrow { Full $1 "cloptr1" }- | lincloptr1Arrow { Full $1 "lincloptr1" }- | minus {% Left $ Expected $1 "Arrow" "-" }- | openParen {% Left $ Expected $1 "Arrow" "(" }- | closeParen {% Left $ Expected $1 "Arrow" ")" }---- | Expression or named call to an expression-Expression : identifierSpace PreExpression { Call (Unqualified $ to_string $1) [] [] Nothing [$2] }- | PreExpression { $1 }- | openParen Tuple closeParen { TupleEx $1 $2 }- | Expression semicolon Expression { Precede $1 $3 }- | Expression semicolon { $1 }- | openParen Expression closeParen { $2 }- | Expression colon Type { TypeSignature $1 $3 } -- TODO is a more general expression sensible?- | openParen Expression vbar Expression closeParen { ProofExpr $1 $2 $4 }- | list_vt lbrace Type rbrace openParen ExpressionIn closeParen { ListLiteral $1 "vt" $3 $6 }- | list lbrace Type rbrace openParen ExpressionIn closeParen { ListLiteral $1 "" $3 $6 }- | begin Expression extern {% Left $ Expected $3 "end" "extern" }- | Expression prfTransform underscore {% Left $ Expected $2 "Rest of expression or declaration" ">>" }--TypeArgs : lbrace Type rbrace { [$2] }- | lbrace TypeIn rbrace { $2 }- | TypeArgs lbrace Type rbrace { $3 : $1 }- | lbrace doubleDot rbrace { [ ImplicitType $2 ] } -- FIXME only valid on function calls- | TypeArgs lbrace TypeIn rbrace { $3 ++ $1 }--BracketedArgs : lbracket Type rbracket { [$2] }- | lbracket TypeIn rbrace { $2 }--Call : Name doubleParens { Call $1 [] [] Nothing [] }- | identifierSpace openParen ExpressionPrf closeParen { Call (Unqualified $ to_string $1) [] [] (fst $3) (snd $3) }- | Name openParen ExpressionPrf closeParen { Call $1 [] [] (fst $3) (snd $3) }- | Name TypeArgs openParen ExpressionPrf closeParen { Call $1 [] $2 (fst $4) (snd $4) }- | Name TypeArgs { Call $1 [] $2 Nothing [] }- | Name lspecial TypeIn rbracket doubleParens { Call $1 $3 [] Nothing [VoidLiteral $5] }- | Name lspecial TypeIn rbracket openParen ExpressionPrf closeParen { Call $1 $3 [] (fst $6) (snd $6) }- | Name lspecial TypeIn rbracket { Call $1 $3 [] Nothing [] }- | raise PreExpression { Call (SpecialName $1 "raise") [] [] Nothing [$2] } -- $raise can have at most one argument- | Name openParen ExpressionPrf end {% Left $ Expected $4 ")" "end"}- | Name openParen ExpressionPrf else {% Left $ Expected $4 ")" "else"}--StaticArgs : StaticExpression { [$1] }- | StaticArgs comma StaticExpression { $3 : $1 }--StaticExpression : Name { StaticVal $1 }- | StaticExpression BinOp StaticExpression { StaticBinary $2 $1 $3 }- | intLit { StaticInt $1 }- | doubleParens { StaticVoid $1 }- | boolLit { StaticBool $1 }- | sif StaticExpression then StaticExpression else StaticExpression { Sif $2 $4 $6 } -- TODO separate type for static expressions- | identifierSpace { StaticVal (Unqualified $ to_string $1) }- | Name openParen StaticArgs closeParen { SCall $1 $3 }- | identifierSpace openParen StaticArgs closeParen { SCall (Unqualified $ to_string $1) $3 }- | StaticExpression semicolon StaticExpression { SPrecede $1 $3 }- --- | Parse an expression that can be called without parentheses-PreExpression : identifier lsqbracket PreExpression rsqbracket { Index $2 (Unqualified $ to_string $1) $3 }- | Literal { $1 }- | Call { $1 }- | case Expression of Case { Case $3 $1 $2 $4 }- | openParen Expression closeParen { ParenExpr $1 $2 }- | PreExpression BinOp PreExpression { Binary $2 $1 $3 }- | UnOp PreExpression { Unary $1 $2 } -- FIXME throw error when we try to negate a string literal/time- | PreExpression dot Name { Access $2 $1 $3 }- | PreExpression dot intLit { Access $2 $1 (Unqualified $ show $3) }- | PreExpression dot identifierSpace { Access $2 $1 (Unqualified $ to_string $3) }- | if Expression then Expression { If $2 $4 Nothing}- | if Expression then Expression else Expression { If $2 $4 (Just $6) }- | let ATS in end { Let $1 $2 Nothing }- | let ATS in Expression end { Let $1 $2 (Just $4) }- | let ATS in Expression vbar {% Left $ Expected $5 "end" "|" }- | lambda Pattern LambdaArrow Expression { Lambda $1 $3 $2 $4 }- | llambda Pattern LambdaArrow Expression { LinearLambda $1 $3 $2 $4 }- | addrAt PreExpression { AddrAt $1 $2 }- | viewAt PreExpression { ViewAt $1 $2 }- | PreExpression at PreExpression { AtExpr $1 $3 }- | atbrace RecordVal rbrace { RecordValue $1 $2 Nothing }- | atbrace RecordVal rbrace colon Type { RecordValue $1 $2 (Just $5) }- | exclamation PreExpression { Deref $1 $2 }- | PreExpression mutateArrow identifierSpace mutateEq PreExpression { FieldMutate $2 $1 (to_string $3) $5 }- | PreExpression mutateArrow identifier mutateEq PreExpression { FieldMutate $2 $1 (to_string $3) $5 }- | PreExpression mutateEq PreExpression { Mutate $1 $3 }- | PreExpression where lbrace Declarations rbrace { WhereExp $1 $4 }- | identifierSpace { NamedVal (Unqualified $ to_string $1) }- | begin Expression end { Begin $1 $2 }- | Name { NamedVal $1 }- | lbrace ATS rbrace { Actions $2 }- | while openParen PreExpression closeParen PreExpression { While $1 $3 $5 }- | include {% Left $ Expected $1 "Expression" "include" }- | staload {% Left $ Expected $1 "Expression" "staload" }- | overload {% Left $ Expected $1 "Expression" "overload" }- | var {% Left $ Expected $1 "Expression" "var" }- | Termetric {% Left $ Expected (fst $1) "Expression" "termetric" }- | fromVT {% Left $ Expected $1 "Expression" "?!" }- | prfTransform {% Left $ Expected $1 "Expression" ">>" }- | maybeProof {% Left $ Expected $1 "Expression" "?" }- | let openParen {% Left $ Expected $1 "Expression" "let (" }- | let ATS in Expression lineComment {% Left $ Expected (token_posn $5) "end" (take 2 $ to_string $5) }- | let ATS in Expression extern {% Left $ Expected $5 "end" "extern" }- | let ATS in Expression fun {% Left $ Expected $5 "end" "fun" }- | let ATS in Expression vtypedef {% Left $ Expected $5 "end" "vtypedef" }- | if Expression then Expression else else {% Left $ Expected $6 "Expression" "else" }---- | Parse a termetric-Termetric : openTermetric StaticExpression closeTermetric { ($1, $2) }- | underscore {% Left $ Expected $1 "_" "Termination metric" }- | dollar {% Left $ Expected $1 "$" "Termination metric" }---- | Parse an existential quantier on a type-Existential : lsqbracket Args vbar StaticExpression rsqbracket { Existential $2 False Nothing (Just $4) }- | lsqbracket Args rsqbracket { Existential $2 False Nothing Nothing }- | openExistential Args rsqbracket { Existential $2 True Nothing Nothing }- | openExistential Args vbar StaticExpression rsqbracket { Existential $2 True Nothing (Just $4) }- | lsqbracket Args colon Type rsqbracket { Existential $2 False (Just $4) Nothing } -- FIXME arguments should include more than just ':'- | lsqbracket StaticExpression rsqbracket { Existential [] False Nothing (Just $2) }- --- | Parse a universal quantifier on a type-Universal : lbrace Args rbrace { Universal $2 Nothing Nothing }- | lbrace Args vbar StaticExpression rbrace { Universal $2 Nothing (Just $4) }---- | Parse the details of an implementation-Implementation : FunName doubleParens eq Expression { Implement $2 [] [] $1 [] $4 }- | FunName openParen FullArgs closeParen eq Expression { Implement $2 [] [] $1 $3 $6 }- | FunName Universals openParen FullArgs closeParen eq Expression { Implement $3 [] $2 $1 $4 $7 }- | Universals FunName openParen FullArgs closeParen eq Expression { Implement $3 $1 [] $2 $4 $7 }- | Universals FunName Universals openParen FullArgs closeParen eq Expression { Implement $4 $1 $3 $2 $5 $8 }---- | Parse a function name-FunName : IdentifierOr { Unqualified $1 }- | identifier dollar identifier { Functorial (to_string $1) (to_string $3) }---- | Parse a general name-Name : identifier { Unqualified (to_string $1) }- | underscore { Unqualified "_" }- | listVT { Unqualified "list_vt" }- | foldAt { Unqualified "fold@" }- | dollar identifier dot identifier { Qualified $1 (to_string $4) (to_string $2) }- | dollar identifier dot identifierSpace { Qualified $1 (to_string $4) (to_string $2) }- | dollar effmaskWrt { SpecialName $1 "effmask_wrt" }- | dollar effmaskAll { SpecialName $1 "effmask_all" }- | dollar extype { SpecialName $1 "effmask_all" }- | dollar listVT { SpecialName $1 "list_vt" }- | dollar ldelay { SpecialName $1 "ldelay" } -- FIXME there is probably a better/more efficient way of doing this- | dollar {% Left $ Expected $1 "Name" "$" }---- | Parse a list of values in a record-RecordVal : IdentifierOr eq Expression { [($1, $3)] }- | RecordVal comma IdentifierOr eq Expression { ($3, $5) : $1 }---- | Parse a list of types in a record-Records : IdentifierOr eq Type { [($1, $3)] }- | Records comma IdentifierOr eq Type { ($3, $5) : $1 }--IdentifiersIn : IdentifierOr { [$1] }- | IdentifiersIn comma IdentifierOr { $3 : $1 }--OfType : { Nothing }- | of Type { Just $2 }---- | Parse a constructor for a sum type-SumLeaf : vbar Universals identifier { Leaf $2 (to_string $3) [] Nothing }- | vbar Universals identifierSpace of Type { Leaf $2 (to_string $3) [] (Just $5) }- | vbar Universals IdentifierOr openParen IdentifiersIn closeParen OfType { Leaf $2 $3 $5 $7 }---- | Parse all constructors of a sum type-Leaves : SumLeaf { [$1] }- | Leaves SumLeaf { $2 : $1 }- | Universals identifierSpace of Type { [Leaf $1 (to_string $2) [] (Just $4)] }- | Universals identifier { [Leaf $1 (to_string $2) [] Nothing] }- | Universals identifier openParen IdentifiersIn closeParen OfType { [Leaf $1 (to_string $2) $4 $6] } -- FIXME should take any static expression.- | dollar {% Left $ Expected $1 "|" "$" }--Universals : { [] }- | doubleBraces { [] }- | Universals Universal { $2 : $1 }---- | Optionally parse a termetric-OptTermetric : { Nothing }- | Termetric { Just (snd $1) }---- | Parse a unary operator-UnOp : tilde { Negate }---- | Parse a binary operator-BinOp : plus { Add }- | minus { Sub }- | div { Div }- | mult { Mult }- | geq { GreaterThanEq }- | leq { LessThanEq }- | lbracket { LessThan }- | rbracket { GreaterThan }- | neq { NotEqual }- | andOp { LogicalAnd }- | or { LogicalOr }- | doubleEq { StaticEq }- | eq { Equal }- | mod { Mod }- | percent { Mod }---- | Optionally parse a function body-OptExpression : { Nothing }- | eq Expression { Just $2 } -- FIXME only let this happen for external declarations---- | Parse a constructor for a 'dataprop'-DataPropLeaf : vbar Universals Expression { DataPropLeaf $2 $3 Nothing }- | Universals Expression { DataPropLeaf $1 $2 Nothing }- | vbar Universals Expression of Expression { DataPropLeaf $2 $3 (Just $5) }- | Universals Expression of Expression { DataPropLeaf $1 $2 (Just $4) }---- | Parse several constructors for a 'dataprop'-DataPropLeaves : DataPropLeaf { [$1] }- | DataPropLeaves DataPropLeaf { $2 : $1 }- | prval {% Left $ Expected $1 "Constructor" "prval" }- | var {% Left $ Expected $1 "Constructor" "var" }- | val {% Left $ Expected (token_posn $1) "Constructor" "val" }- | lambda {% Left $ Expected $1 "Constructor" "lam" }- | llambda {% Left $ Expected $1 "Constructor" "llam" }- | minus {% Left $ Expected $1 "Constructor" "-" }- | dollar {% Left $ Expected $1 "Constructor" "$" }- | fromVT {% Left $ Expected $1 "Constructor" "?!" }- | prfTransform {% Left $ Expected $1 "Constructor" ">>" }- | maybeProof {% Left $ Expected $1 "Constructor" "?" }--Signature : signature { $1 }- | colon { "" }--OptType : Type { Just $1 }- | { Nothing }---- | Parse a type signature and optional function body-PreFunction : FunName openParen FullArgs closeParen Signature OptType OptExpression { (PreF $1 $5 [] [] $3 $6 Nothing $7) }- | FunName Universals OptTermetric Signature OptType OptExpression { PreF $1 $4 [] $2 [NoArgs] $5 $3 $6 }- | FunName Universals OptTermetric doubleParens Signature OptType OptExpression { PreF $1 $5 [] $2 [] $6 $3 $7 }- | FunName Universals OptTermetric openParen FullArgs closeParen Signature OptType OptExpression { PreF $1 $7 [] $2 $5 $8 $3 $9 }- | Universals FunName Universals OptTermetric openParen FullArgs closeParen Signature OptType OptExpression { PreF $2 $8 $1 $3 $6 $9 $4 $10 }- | Universals FunName Universals OptTermetric Signature OptType OptExpression { PreF $2 $5 $1 $3 [] $6 $4 $7 }- | prval {% Left $ Expected $1 "Function signature" "prval" }- | var {% Left $ Expected $1 "Function signature" "var" }- | val {% Left $ Expected (token_posn $1) "Function signature" "val" }- | lambda {% Left $ Expected $1 "Function signature" "lam" }- | llambda {% Left $ Expected $1 "Function signature" "llam" }- | lsqbracket {% Left $ Expected $1 "Function signature" "[" }---- | Parse affiliated `sortdef`s-AndSort : AndSort and IdentifierOr eq Type { AndD $1 (SortDef $2 $3 $5) } -- TODO figure out if this is building up the slow way- | sortdef IdentifierOr eq Type { SortDef $1 $2 $4 }---- | Function declaration-FunDecl : fun PreFunction { [ Func $1 (Fun $2) ] }- | prfun PreFunction { [ Func $1 (PrFun $2) ] }- | prfn PreFunction { [ Func $1 (PrFn $2) ] }- | fnx PreFunction { [ Func $1 (Fnx $2) ] }- | castfn PreFunction { [ Func $1 (CastFn $2) ] }- | fn PreFunction identifier {% Left $ Expected (token_posn $3) "=" (to_string $3) }- | fn PreFunction { [ Func $1 (Fn $2) ] }- | FunDecl and PreFunction { Func $2 (And $3) : $1 }- | extern FunDecl { over _head (Extern $1) $2 }- | extern fun PreFunction eq {% Left $ Expected $1 "Declaration" "Function body" }- | extern fnx PreFunction eq {% Left $ Expected $1 "Declaration" "Function body" }- | extern praxi PreFunction eq {% Left $ Expected $1 "Declaration" "Function body" }- | extern prfun PreFunction eq {% Left $ Expected $1 "Declaration" "Function body" }- | extern prfn PreFunction eq {% Left $ Expected $1 "Declaration" "Function body" }- | lambda {% Left $ Expected $1 "Function declaration" "lam" }- | llambda {% Left $ Expected $1 "Function declaration" "llam" }- | fun fn {% Left $ Expected $2 "Function name" "fn" }- | fn fun {% Left $ Expected $2 "Function name" "fun" }- | extern FunDecl identifier openParen {% Left $ Expected (token_posn $3) "Static integer expression" (to_string $3) }--IdentifierOr : identifier { to_string $1 }- | identifierSpace { to_string $1 }--MaybeType : eq Type { Just $2 }- | { Nothing }---- | Parse a declaration defining a type-TypeDecl : typedef IdentifierOr eq Type { TypeDef $1 $2 [] $4 }- | typedef IdentifierOr openParen FullArgs closeParen eq Type { TypeDef $1 $2 $4 $7 }- | vtypedef IdentifierOr eq Type { ViewTypeDef $1 $2 [] $4 }- | vtypedef IdentifierOr openParen FullArgs closeParen eq Type { ViewTypeDef $1 $2 $4 $7 }- | datatype IdentifierOr eq Leaves { SumType $2 [] $4 }- | datatype IdentifierOr openParen Args closeParen eq Leaves { SumType $2 $4 $7 }- | datavtype IdentifierOr eq Leaves { SumViewType $2 [] $4 }- | datavtype IdentifierOr openParen Args closeParen eq Leaves { SumViewType $2 $4 $7 }- | abst0p IdentifierOr eq Type { AbsT0p $1 $2 $4 }- | viewdef IdentifierOr openParen FullArgs closeParen eq Type { ViewDef $1 $2 $4 $7 }- | absvt0p IdentifierOr openParen FullArgs closeParen MaybeType { AbsVT0p $1 $2 $4 $6 }- | absvt0p IdentifierOr eq Type { AbsVT0p $1 $2 [] (Just $4) }- | absview IdentifierOr openParen FullArgs closeParen MaybeType { AbsView $1 $2 $4 $6 }- | abstype IdentifierOr openParen FullArgs closeParen MaybeType { AbsType $1 $2 $4 $6 }- | absvtype IdentifierOr openParen FullArgs closeParen MaybeType { AbsViewType $1 $2 $4 $6 }- | dataprop IdentifierOr openParen FullArgs closeParen eq DataPropLeaves { DataProp $1 $2 $4 $7 }- | absprop IdentifierOr openParen FullArgs closeParen { AbsProp $1 $2 $4 }- | stadef IdentifierOr eq Name { Stadef $2 $4 [] }- | stadef IdentifierOr eq Name openParen TypeIn closeParen { Stadef $2 $4 $6 }- | stadef boolLit eq Name { Stadef (over _head toLower (show $2)) $4 [] } -- TODO identifierSpace- | sortdef IdentifierOr eq Type { SortDef $1 $2 $4 }- | AndSort { $1 }--Fixity : infixr { RightFix $1 }- | infixl { LeftFix $1 }- | prefix { Pre $1 }- | postfix { Post $1 }--Operator : identifierSpace { to_string $1 }- | exp { "**" }--Operators : Operator { [$1] }- | Operators Operator { $2 : $1 }- | Operators identifier { to_string $2 : $1 }--StackFunction : openParen Args closeParen Signature Type plainArrow Expression { StackF $4 $2 $5 $7 }---- | Parse a declaration-Declaration : include string { Include $2 }- | define { Define $1 }- | define identifierSpace string { Define ($1 ++ " " ++ to_string $2 ++ $3) } -- FIXME better approach?- | define identifierSpace intLit { Define ($1 ++ " " ++ to_string $2 ++ " " ++ show $3) }- | cblock { CBlock $1 }- | lineComment { Comment (to_string $1) }- | staload underscore eq string { Staload (Just "_") $4 }- | staload string { Staload Nothing $2 }- | staload IdentifierOr eq string { Staload (Just $2) $4 }- | extern Declaration { Extern $1 $2 }- | var Pattern colon Type with PreExpression { Var (Just $4) $2 Nothing (Just $6) } -- FIXME signature is too general.- | var Pattern colon Type eq PreExpression { Var (Just $4) $2 (Just $6) Nothing }- | val Pattern colon Type eq PreExpression { Val (get_addendum $1) (Just $4) $2 $6 }- | val Pattern eq Expression { Val (get_addendum $1) Nothing $2 $4 }- | var Pattern eq Expression { Var Nothing $2 (Just $4) Nothing }- | var Pattern colon Type { Var (Just $4) $2 Nothing Nothing }- | var Pattern eq fixAt IdentifierOr StackFunction { Var Nothing $2 (Just $ FixAt $5 $6) Nothing }- | var Pattern eq lamAt StackFunction { Var Nothing $2 (Just $ LambdaAt $5) Nothing }- | prval Pattern eq Expression { PrVal $2 $4 }- | praxi PreFunction { Func $1 (Praxi $2) }- | primplmnt Implementation { ProofImpl $2 }- | implement Implementation { Impl [] $2 }- | implement openParen Args closeParen Implementation { Impl $3 $5 }- | overload BinOp with Name { OverloadOp $1 $2 $4 }- | overload identifierSpace with Name { OverloadIdent $1 (to_string $2) $4 Nothing }- | overload tilde with identifierSpace of intLit { OverloadIdent $1 "~" (Unqualified $ to_string $4) (Just $6) } -- FIXME figure out a general solution.- | assume Name openParen Args closeParen eq Expression { Assume $2 $4 $7 }- | tkindef IdentifierOr eq string { TKind $1 (Unqualified $2) $4 }- | TypeDecl { $1 }- | symintr Name { SymIntr $1 $2 }- | stacst IdentifierOr colon Type OptExpression { Stacst $1 (Unqualified $2) $4 $5 }- | propdef IdentifierOr openParen Args closeParen eq Type { PropDef $1 $2 $4 $7 }- | Fixity intLit Operators { FixityDecl $1 (Just $2) $3 }- | val Universals IdentifierOr colon Type { StaVal $2 $3 $5 }- | lambda {% Left $ Expected $1 "Declaration" "lam" }- | llambda {% Left $ Expected $1 "Declaration" "llam" }- | minus {% Left $ Expected $1 "Declaration" "-" }- | dollar {% Left $ Expected $1 "Declaration" "$" }- | fromVT {% Left $ Expected $1 "Declaration" "?!" }- | prfTransform {% Left $ Expected $1 "Declaration" ">>" }- | maybeProof {% Left $ Expected $1 "Declaration" "?" }- | identifier {% Left $ Expected (token_posn $1) "Declaration" (to_string $1) }--{--data ATSError a = Expected AlexPosn a a- | Unknown Token -- FIXME error type for expression when a static expression was expected (?)- deriving (Eq, Show, Generic, NFData)--instance Pretty AlexPosn where- pretty (AlexPn _ line col) = pretty line <> ":" <> pretty col--instance Pretty (ATSError String) where- pretty (Expected p s1 s2) = red "Error: " <> pretty p <> linebreak <> (indent 2 $ "Unexpected" <+> squotes (string s2) <> ", expected:" <+> squotes (string s1)) <> linebreak- pretty (Unknown t) = red "Error:" <+> "unexpected token" <+> squotes (pretty t) <+> "at" <+> pretty (token_posn t) <> linebreak--parseError :: [Token] -> Either (ATSError String) a-parseError = Left . Unknown . head -}
− src/Language/ATS/PrettyPrint.hs
@@ -1,547 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}--{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE TypeSynonymInstances #-}--module Language.ATS.PrettyPrint ( printATS- , printATSCustom- , printATSFast- , processClang- ) where--import Control.Arrow hiding ((<+>))-import Control.Composition hiding ((&))-import Control.DeepSeq (NFData)-import Control.Lens hiding (op, pre)-#if __GLASGOW_HASKELL__ >= 801-import Data.Function (on)-#endif-import Data.Functor.Foldable (cata)-import GHC.Generics (Generic)-import Language.ATS.Types-import Prelude hiding ((<$>))-import System.Console.ANSI.Types-import System.Process (readCreateProcess, shell)-import Text.PrettyPrint.ANSI.Leijen-import Text.PrettyPrint.ANSI.Leijen.Internal--infixr 5 $$--deriving instance Generic Underlining-deriving instance NFData Underlining-deriving instance Generic ConsoleIntensity-deriving instance NFData ConsoleIntensity-deriving instance Generic Color-deriving instance NFData Color-deriving instance Generic ColorIntensity-deriving instance NFData ColorIntensity-deriving instance Generic ConsoleLayer-deriving instance NFData ConsoleLayer-deriving instance Generic Doc-deriving instance NFData Doc--instance Eq Doc where- (==) = on (==) show--takeBlock :: String -> (String, String)-takeBlock ('%':'}':ys) = ("", ('%':) . ('}':) $ ys)-takeBlock (y:ys) = first (y:) $ takeBlock ys-takeBlock [] = ([], [])--rest :: String -> IO String-rest xs = fmap (<> (snd $ takeBlock xs)) $ printClang (fst $ takeBlock xs)--processClang :: String -> IO String-processClang ('%':'{':'^':xs) = fmap (('%':) . ('{':) . ('^':)) $ rest xs-processClang ('%':'{':'#':xs) = fmap (('%':) . ('{':) . ('#':)) $ rest xs-processClang ('%':'{':'$':xs) = fmap (('%':) . ('{':) . ('$':)) $ rest xs-processClang ('%':'{':xs) = fmap (('%':) . ('{':)) $ rest xs-processClang (x:xs) = fmap (x:) $ processClang xs-processClang [] = pure []--printClang :: String -> IO String-printClang = readCreateProcess (shell "clang-format")---- | Pretty-print with sensible defaults.-printATS :: ATS -> String-printATS = (<> "\n") . printATSCustom 0.6 120--printATSCustom :: Float -- ^ Ribbon fraction- -> Int -- ^ Ribbon width- -> ATS -> String-printATSCustom r i (ATS x) = g mempty- where g = (displayS . renderSmart r i . pretty) (ATS $ reverse x)---- | Fast pretty-printer without indendation. Useful for generating code.-printATSFast :: ATS -> String-printATSFast (ATS x) = g mempty- where g = (displayS . renderCompact . (<> "\n") . pretty) (ATS $ reverse x)--instance Pretty Name where- pretty (Unqualified n) = text n- pretty (Qualified _ i n) = "$" <> text n <> "." <> text i- pretty (SpecialName _ s) = "$" <> text s- pretty (Functorial s s') = text s <> "$" <> text s'- pretty Unnamed{} = mempty--instance Pretty LambdaType where- pretty Plain{} = "=>"- pretty Spear{} = "=>>"- pretty (Full _ v) = "=<" <> text v <> ">"--instance Pretty BinOp where- pretty Mult = "*"- pretty Add = "+"- pretty Div = "/"- pretty Sub = "-"- pretty GreaterThan = ">"- pretty LessThan = "<"- pretty Equal = "="- pretty NotEqual = "!="- pretty LogicalAnd = "&&"- pretty LogicalOr = "||"- pretty LessThanEq = "<="- pretty GreaterThanEq = ">="- pretty StaticEq = "=="- pretty Mod = "%"--splits :: BinOp -> Bool-splits Mult = True-splits Add = True-splits Div = True-splits Sub = True-splits LogicalAnd = True-splits LogicalOr = True-splits _ = False--startsParens :: Doc -> Bool-startsParens d = f (show d) where- f ('(':_) = True- f _ = False--prettySmall :: Doc -> [Doc] -> Doc-prettySmall op es = mconcat (punctuate (" " <> op <> " ") es)--prettyBinary :: Doc -> [Doc] -> Doc-prettyBinary op es- | length (showFast $ mconcat es) < 80 = prettySmall op es- | otherwise = prettyLarge op es--prettyLarge :: Doc -> [Doc] -> Doc-prettyLarge _ [] = mempty-prettyLarge op (e:es) = e <$> vsep (fmap (op <+>) es)---- FIXME we really need a monadic pretty printer lol.-lengthAlt :: Doc -> Doc -> Doc-lengthAlt d1 d2- | length (showFast d2) >= 30 = d1 <$> indent 4 d2- | otherwise = d1 <+> d2--instance Pretty Expression where- pretty = cata a . rewriteATS where- a (IfF e e' (Just e'')) = "if" <+> e <+> "then" <$> indent 2 e' <$> "else" <$> indent 2 e''- a (IfF e e' Nothing) = "if" <+> e <+> "then" <$> indent 2 e'- a (LetF _ e (Just e')) = flatAlt- ("let" <$> indent 2 (pretty ((\(ATS x) -> ATS $ reverse x) e)) <$> "in" <$> indent 2 e' <$> "end")- ("let" <+> pretty ((\(ATS x) -> ATS $ reverse x) e) <$> "in" <+> e' <$> "end")- a (LetF _ e Nothing) = flatAlt- ("let" <$> indent 2 (pretty ((\(ATS x) -> ATS $ reverse x) e)) <$> "in end")- ("let" <+> pretty ((\(ATS x) -> ATS $ reverse x) e) <$> "in end")- a (BoolLitF True) = "true"- a (BoolLitF False) = "false"- a (TimeLitF s) = text s- a (IntLitF i) = pretty i- a (LambdaF _ lt p e) = let pre = "lam" <+> pretty p <+> pretty lt in flatAlt (lengthAlt pre e) (pre <+> e)- a (LinearLambdaF _ lt p e) = let pre = "llam" <+> pretty p <+> pretty lt in flatAlt (lengthAlt pre e) (pre <+> e)- a (FloatLitF f) = pretty f- a (StringLitF s) = text s -- FIXME escape indentation in multi-line strings.- a (ParenExprF _ e) = parens e- a (BinListF op@Add es) = prettyBinary (pretty op) es- a (BinaryF op e e')- | splits op = e </> pretty op <+> e'- | otherwise = e <+> pretty op <+> e'- a (IndexF _ n e) = pretty n <> "[" <> e <> "]"- a (UnaryF Negate e) = "~" <> e- a (NamedValF nam) = pretty nam- a (CallF nam [] [] Nothing []) = pretty nam <> "()"- a (CallF nam [] [] (Just e) xs) = pretty nam <> prettyArgsG ("(" <> pretty e <+> "| ") ")" xs -- FIXME split eagerly on "|"- a (CallF nam [] [] Nothing xs) = pretty nam <> prettyArgs xs- a (CallF nam [] us Nothing []) = pretty nam <> prettyArgsU "{" "}" us- a (CallF nam [] us Nothing xs) = pretty nam <> prettyArgsU "{" "}" us <> prettyArgsG "(" ")" xs- a (CallF nam is [] Nothing []) = pretty nam <> prettyArgsU "<" ">" is- a (CallF nam is [] Nothing [x])- | startsParens x = pretty nam <> prettyArgsU "<" ">" is <> pretty x- a (CallF nam is [] Nothing xs) = pretty nam <> prettyArgsU "<" ">" is <> prettyArgs xs- a (CaseF _ add e cs) = "case" <> pretty add <+> e <+> "of" <$> indent 2 (prettyCases cs)- a (VoidLiteralF _) = "()"- a (RecordValueF _ es Nothing) = prettyRecord es- a (RecordValueF _ es (Just x)) = prettyRecord es <+> ":" <+> pretty x- a (PrecedeF e e') = parens (e <+> ";" </> e')- a (PrecedeListF es) = lineAlt (prettyArgsList "; " "(" ")" es) ("(" <> mconcat (punctuate " ; " es) <> ")")- a (FieldMutateF _ o f v) = pretty o <> "->" <> string f <+> ":=" <+> v- a (MutateF e e') = e <+> ":=" <+> e'- a (DerefF _ e) = "!" <> e- a (AccessF _ e n)- | noParens e = e <> "." <> pretty n- | otherwise = parens e <> "." <> pretty n- a (CharLitF '\\') = "'\\\\'"- a (CharLitF '\n') = "'\\n'"- a (CharLitF '\t') = "'\\t'"- a (CharLitF c) = "'" <> char c <> "'"- a (ProofExprF _ e e') = "(" <> e <+> "|" <+> e' <> ")"- a (TypeSignatureF e t) = e <+> ":" <+> pretty t- a (WhereExpF e d) = e <+> "where" <$> braces (" " <> nest 2 (pretty (ATS $ reverse d)) <> " ")- a (TupleExF _ es) = parens (mconcat $ punctuate ", " (reverse es))- a (WhileF _ e e') = "while" <> parens e <> e'- a (ActionsF as) = "{" <$> indent 2 (pretty ((\(ATS x) -> ATS $ reverse x) as)) <$> "}"- a UnderscoreLitF{} = "_"- a (AtExprF e e') = e <> "@" <> e'- a (BeginF _ e)- | not (startsParens e) = linebreak <> indent 2 ("begin" <$> indent 2 e <$> "end")- | otherwise = e- a (FixAtF n (StackF s as t e)) = "fix@" <+> text n <+> prettyArgs as <+> ":" <> pretty s <+> pretty t <+> "=>" <$> indent 2 (pretty e)- a (LambdaAtF (StackF s as t e)) = "lam@" <+> prettyArgs as <+> ":" <> pretty s <+> pretty t <+> "=>" <$> indent 2 (pretty e)- a (AddrAtF _ e) = "addr@" <> e- a (ViewAtF _ e) = "view@" <> e- a (ListLiteralF _ s t es) = "list" <> string s <> "{" <> pretty t <> "}" <> prettyArgs es- a BinListF{} = undefined- a CallF{} = undefined- prettyCases [] = mempty- prettyCases [(s, l, t)] = "|" <+> pretty s <+> pretty l <+> t- prettyCases ((s, l, t): xs) = prettyCases xs $$ "|" <+> pretty s <+> pretty l <+> t -- FIXME can leave space with e.g. => \n begin ...--noParens :: Doc -> Bool-noParens = all (`notElem` ("()" :: String)) . show--patternHelper :: [Doc] -> Doc-patternHelper ps = mconcat (punctuate ", " (reverse ps))--instance Pretty Pattern where- pretty = cata a where- a (WildcardF _) = "_"- a (PSumF s x) = string s <+> x- a (PLiteralF e) = pretty e- a (PNameF s []) = string s- a (PNameF s [x]) = string s <> parens x- a (PNameF s ps) = string s <> parens (patternHelper ps)- a (FreeF p) = "~" <> p- a (GuardedF _ e p) = p <+> "when" <+> pretty e- a (ProofF _ p p') = parens (patternHelper p <+> "|" <+> patternHelper p')- a (TuplePatternF ps) = parens (patternHelper ps)- a (AtPatternF _ p) = "@" <> p- a (UniversalPatternF _ n us p) = text n <> prettyArgsU "" "" us <> p- a (ExistentialPatternF e p) = pretty e <> p--singleArg :: Arg -> Doc-singleArg x@Arg{} = argHelper (<>) x-singleArg x = pretty x--argHelper :: (Doc -> Doc -> Doc) -> Arg -> Doc-argHelper _ (Arg (First s)) = pretty s-argHelper _ (Arg (Second t)) = pretty t-argHelper op (Arg (Both s t)) = pretty s `op` colon `op` pretty t-argHelper op (PrfArg a a') = pretty a `op` "|" `op` pretty a'-argHelper _ NoArgs = undefined -- in theory we handle this elsewhere.--instance Pretty Arg where- pretty = argHelper (<+>)--squish :: BinOp -> Bool-squish Add = True-squish Sub = True-squish Mult = True-squish _ = False--instance Pretty StaticExpression where- pretty = cata a where- a (StaticValF n) = pretty n- a (StaticBinaryF op se se')- | squish op = se <> pretty op <> se'- | otherwise = se <+> pretty op <+> se'- a (StaticIntF i) = pretty i- a StaticVoidF{} = "()"- a (SifF e e' e'') = "sif" <+> e <+> "then" <$> indent 2 e' <$> "else" <$> indent 2 e''- a (StaticBoolF True) = "true"- a (StaticBoolF False) = "false"- a (SCallF n cs) = pretty n <> parens (mconcat (punctuate "," . reverse . fmap pretty $ cs))- a (SPrecedeF e e') = e <> ";" <+> e'--instance Pretty Type where- pretty = cata a where- a IntF = "int"- a StringF = "string"- a BoolF = "bool"- a VoidF = "void"- a NatF = "nat"- a AddrF = "addr"- a CharF = "char"- a (NamedF n) = pretty n- a (ExF e t) = pretty e <+> t- a (DependentIntF e) = "int(" <> pretty e <> ")"- a (DependentBoolF e) = "bool(" <> pretty e <> ")"- a (DepStringF e) = "string(" <> pretty e <> ")"- a (DependentF n ts) = pretty n <> parens (mconcat (punctuate ", " (fmap pretty (reverse ts))))- a DoubleF = "double"- a FloatF = "float"- a (ForAF u t) = pretty u <+> t- a (UnconsumedF t) = "!" <> t- a (AsProofF t (Just t')) = t <+> ">>" <+> t'- a (AsProofF t Nothing) = t <+> ">> _"- a (FromVTF t) = t <> "?!"- a (MaybeValF t) = t <> "?"- a (T0pF ad) = "t@ype" <> pretty ad- a (Vt0pF ad) = "vt@ype" <> pretty ad- a (AtF _ (Just t) t') = t <+> "@" <+> t'- a (AtF _ Nothing t) = "@" <> t- a (ProofTypeF _ t t') = parens (t <+> "|" <+> t')- a (ConcreteTypeF e) = pretty e- a (TupleF _ ts) = parens (mconcat (punctuate ", " (fmap pretty (reverse ts))))- a (RefTypeF t) = "&" <> t- a (ViewTypeF _ t) = "view@" <> parens t- a (FunctionTypeF s t t') = t <+> string s <+> t'- a (ViewLiteralF c) = "view" <> pretty c- a NoneTypeF{} = "()"- a ImplicitTypeF{} = ".."- a (AnonymousRecordF _ rs) = prettyRecord rs--gan :: Maybe Type -> Doc-gan (Just t) = " : " <> pretty t <> " "-gan Nothing = ""--withHashtag :: Bool -> Doc-withHashtag True = "#["-withHashtag _ = lbracket--instance Pretty Existential where- pretty (Existential [] b Nothing (Just e)) = withHashtag b <+> pretty e <+> rbracket- pretty (Existential [x@Arg{}] b Nothing Nothing) = withHashtag b <> singleArg x <> rbracket- pretty (Existential bs b ty Nothing) = withHashtag b <+> mconcat (punctuate ", " (fmap pretty (reverse bs))) <> gan ty <+> rbracket- pretty (Existential bs b ty (Just e)) = withHashtag b <+> mconcat (punctuate ", " (fmap go (reverse bs))) <> gan ty <+> "|" <+> pretty e <+> rbracket- where go (Arg (First s)) = pretty s- go (Arg (Both s t)) = pretty s <+> colon <+> pretty t- go (Arg (Second t)) = pretty t- go _ = undefined--instance Pretty Universal where- pretty (Universal [x@PrfArg{}] Nothing Nothing) = lbrace <+> pretty x <+> rbrace -- FIXME universals can now be length-one arguments- pretty (Universal [x] Nothing Nothing) = lbrace <> singleArg x <> rbrace -- FIXME universals can now be length-one arguments- pretty (Universal bs ty Nothing) = lbrace <+> mconcat (punctuate ", " (fmap pretty (reverse bs))) <> gan ty <+> rbrace- pretty (Universal bs ty (Just e)) = lbrace <+> mconcat (punctuate ", " (fmap go (reverse bs))) <> gan ty <+> "|" <+> pretty e <+> rbrace- where go (Arg (First s)) = pretty s- go (Arg (Both s t)) = pretty s <+> colon <+> pretty t- go (Arg (Second t)) = pretty t- go _ = undefined--instance Pretty ATS where- pretty (ATS xs) = concatSame (fmap rewriteDecl xs)--instance Pretty Implementation where- pretty (Implement _ [] [] n [] e) = "implement" <+> pretty n <+> "() =" <$> indent 2 (pretty e)- pretty (Implement _ [] [] n ias e) = "implement" <+> pretty n <+> prettyArgs ias <+> "=" <$> indent 2 (pretty e)- pretty (Implement _ [] us n ias e) = "implement" <+> pretty n <+> foldMap pretty us </> prettyArgs ias <+> "=" <$> indent 2 (pretty e)- pretty (Implement _ ps [] n ias e) = "implement" <+> foldMap pretty ps </> pretty n <+> prettyArgs ias <+> "=" <$> indent 2 (pretty e)- pretty (Implement _ ps us n ias e) = "implement" <+> foldMap pretty ps </> pretty n </> foldMap pretty us <+> prettyArgs ias <+> "=" <$> indent 2 (pretty e)--isVal :: Declaration -> Bool-isVal Val{} = True-isVal Var{} = True-isVal PrVal{} = True-isVal _ = False--glue :: Declaration -> Declaration -> Bool-glue x y- | isVal x && isVal y = True-glue Staload{} Staload{} = True-glue Include{} Include{} = True-glue ViewTypeDef{} ViewTypeDef{} = True-glue TypeDef{} TypeDef{} = True-glue Comment{} _ = True-glue (Func _ Fnx{}) (Func _ And{}) = True-glue _ _ = False--{-# INLINE glue #-}--concatSame :: [Declaration] -> Doc-concatSame [] = mempty-concatSame [x] = pretty x-concatSame (x:x':xs)- | glue x x' = pretty x <$> concatSame (x':xs)- | otherwise = pretty x <> line <$> concatSame (x':xs)---- TODO - soft break-($$) :: Doc -> Doc -> Doc-x $$ y = align (x <$> y)--lineAlt :: Doc -> Doc -> Doc-lineAlt = group .* flatAlt--showFast :: Doc -> String-showFast d = displayS (renderCompact d) mempty--prettyRecord :: (Pretty a) => [(String, a)] -> Doc-prettyRecord es- | any ((>40) . length . showFast . pretty) es = prettyRecordF True es- | otherwise = lineAlt (prettyRecordF True es) (prettyRecordS True es)--prettyRecordS :: (Pretty a) => Bool -> [(String, a)] -> Doc-prettyRecordS _ [] = mempty-prettyRecordS True [(s, t)] = "@{" <+> text s <+> "=" <+> pretty t <+> "}"-prettyRecordS _ [(s, t)] = "@{" <+> text s <+> "=" <+> pretty t-prettyRecordS True ((s, t):xs) = prettyRecordS False xs <> "," <+> text s <+> ("=" <+> pretty t) <+> "}"-prettyRecordS x ((s, t):xs) = prettyRecordS x xs <> "," <+> text s <+> ("=" <+> pretty t)--prettyRecordF :: (Pretty a) => Bool -> [(String, a)] -> Doc-prettyRecordF _ [] = mempty-prettyRecordF True [(s, t)] = "@{" <+> text s <+> align ("=" <+> pretty t) <+> "}"-prettyRecordF _ [(s, t)] = "@{" <+> text s <+> align ("=" <+> pretty t)-prettyRecordF True ((s, t):xs) = prettyRecordF False xs $$ indent 1 ("," <+> text s <+> align ("=" <+> pretty t) <$> "}")-prettyRecordF x ((s, t):xs) = prettyRecordF x xs $$ indent 1 ("," <+> text s <+> align ("=" <+> pretty t))--prettyDL :: [DataPropLeaf] -> Doc-prettyDL [] = mempty-prettyDL [DataPropLeaf [] e Nothing] = indent 2 ("|" <+> pretty e)-prettyDL [DataPropLeaf [] e (Just e')] = indent 2 ("|" <+> pretty e <+> "of" <+> pretty e')-prettyDL (DataPropLeaf [] e Nothing:xs) = prettyDL xs $$ indent 2 ("|" <+> pretty e)-prettyDL (DataPropLeaf [] e (Just e'):xs) = prettyDL xs $$ indent 2 ("|" <+> pretty e <+> "of" <+> pretty e')-prettyDL [DataPropLeaf us e Nothing] = indent 2 ("|" <+> foldMap pretty us <+> pretty e)-prettyDL [DataPropLeaf us e (Just e')] = indent 2 ("|" <+> foldMap pretty us <+> pretty e <+> "of" <+> pretty e')-prettyDL (DataPropLeaf us e Nothing:xs) = prettyDL xs $$ indent 2 ("|" <+> foldMap pretty us <+> pretty e)-prettyDL (DataPropLeaf us e (Just e'):xs) = prettyDL xs $$ indent 2 ("|" <+> foldMap pretty us <+> pretty e <+> "of" <+> pretty e')--universalHelper :: [Universal] -> Doc-universalHelper = mconcat . fmap pretty . reverse--prettyLeaf :: [Leaf] -> Doc-prettyLeaf [] = mempty-prettyLeaf [Leaf [] s [] Nothing] = indent 2 ("|" <+> text s)-prettyLeaf [Leaf [] s [] (Just e)] = indent 2 ("|" <+> text s <+> "of" <+> pretty e)-prettyLeaf (Leaf [] s [] Nothing:xs) = prettyLeaf xs $$ indent 2 ("|" <+> text s)-prettyLeaf (Leaf [] s [] (Just e):xs) = prettyLeaf xs $$ indent 2 ("|" <+> text s <+> "of" <+> pretty e)-prettyLeaf [Leaf [] s as Nothing] = indent 2 ("|" <+> text s <> prettyArgs as)-prettyLeaf [Leaf [] s as (Just e)] = indent 2 ("|" <+> text s <> prettyArgs as <+> "of" <+> pretty e)-prettyLeaf (Leaf [] s as Nothing:xs) = prettyLeaf xs $$ indent 2 ("|" <+> text s <> prettyArgs as)-prettyLeaf (Leaf [] s as (Just e):xs) = prettyLeaf xs $$ indent 2 ("|" <+> text s <> prettyArgs as <+> "of" <+> pretty e)-prettyLeaf [Leaf us s [] Nothing] = indent 2 ("|" <+> universalHelper us <+> text s)-prettyLeaf [Leaf us s [] (Just e)] = indent 2 ("|" <+> universalHelper us <+> text s <+> "of" <+> pretty e)-prettyLeaf (Leaf us s [] Nothing:xs) = prettyLeaf xs $$ indent 2 ("|" <+> universalHelper us <+> text s)-prettyLeaf (Leaf us s [] (Just e):xs) = prettyLeaf xs $$ indent 2 ("|" <+> universalHelper us <+> text s <+> "of" <+> pretty e)-prettyLeaf [Leaf us s as Nothing] = indent 2 ("|" <+> universalHelper us <+> text s <> prettyArgs as)-prettyLeaf [Leaf us s as (Just e)] = indent 2 ("|" <+> universalHelper us <+> text s <> prettyArgs as <+> "of" <+> pretty e)-prettyLeaf (Leaf us s as Nothing:xs) = prettyLeaf xs $$ indent 2 ("|" <+> universalHelper us <+> text s <> prettyArgs as)-prettyLeaf (Leaf us s as (Just e):xs) = prettyLeaf xs $$ indent 2 ("|" <+> universalHelper us <+> text s <> prettyArgs as <+> "of" <+> pretty e)--prettyHelper :: Doc -> [Doc] -> [Doc]-prettyHelper _ [x] = [x]-prettyHelper c (x:xs) = flatAlt (" " <> x) x : fmap (c <>) xs-prettyHelper _ x = x--prettyBody :: Doc -> Doc -> [Doc] -> Doc-prettyBody c1 c2 [d] = c1 <> d <> c2-prettyBody c1 c2 ds = (c1 <>) . align . indent (-1) . cat . (<> pure c2) $ ds--prettyArgsG' :: Doc -> Doc -> Doc -> [Doc] -> Doc-prettyArgsG' c3 c1 c2 = prettyBody c1 c2 . prettyHelper c3 . reverse--prettyArgsList :: Doc -> Doc -> Doc -> [Doc] -> Doc-prettyArgsList c3 c1 c2 = prettyBody c1 c2 . va . prettyHelper c3--va :: [Doc] -> [Doc]-va = (& _tail.traverse %~ group)--prettyArgsG :: Doc -> Doc -> [Doc] -> Doc-prettyArgsG = prettyArgsG' ", "--prettyArgsU :: (Pretty a) => Doc -> Doc -> [a] -> Doc-prettyArgsU = prettyArgs' ","--prettyArgs' :: (Pretty a) => Doc -> Doc -> Doc -> [a] -> Doc-prettyArgs' = fmap pretty -.*** prettyArgsG'--prettyArgs :: (Pretty a) => [a] -> Doc-prettyArgs = prettyArgs' ", " "(" ")"--fancyU :: [Universal] -> Doc-fancyU = foldMap pretty . reverse--(<#>) :: Doc -> Doc -> Doc-(<#>) a b = lineAlt (a <$> indent 2 b) (a <+> b)---- FIXME figure out a nicer algorithm for when/how to split lines.--- aka don't use '</>' in places.-instance Pretty PreFunction where- pretty (PreF i si [] [] [NoArgs] (Just rt) Nothing (Just e)) = pretty i <+> ":" <> text si <#> pretty rt <+> "=" <$> indent 2 (pretty e) -- FIXME this is an awful hack- pretty (PreF i si [] [] as (Just rt) Nothing (Just e)) = pretty i <> prettyArgs as <+> ":" <> text si <#> pretty rt <+> "=" <$> indent 2 (pretty e)- pretty (PreF i si [] [] as (Just rt) (Just t) (Just e)) = pretty i </> ".<" <> pretty t <> ">." </> prettyArgs as <+> ":" <> text si <#> pretty rt <+> "=" <$> indent 2 (pretty e)- pretty (PreF i si [] us as (Just rt) (Just t) (Just e)) = pretty i </> fancyU us </> ".<" <> pretty t <> ">." </> prettyArgs as <+> ":" <> text si <#> pretty rt <+> "=" <$> indent 2 (pretty e)- pretty (PreF i si [] us [NoArgs] (Just rt) Nothing (Just e)) = pretty i </> fancyU us <+> ":" <> text si <#> pretty rt <+> "=" <$> indent 2 (pretty e)- pretty (PreF i si [] us as (Just rt) Nothing (Just e)) = pretty i </> fancyU us </> prettyArgs as <+> ":" <> text si <#> pretty rt <+> "=" <$> indent 2 (pretty e)- pretty (PreF i si pus [] as (Just rt) Nothing (Just e)) = fancyU pus </> pretty i <> prettyArgs as <+> ":" <> text si <#> pretty rt <+> "=" <$> indent 2 (pretty e)- pretty (PreF i si pus [] as (Just rt) (Just t) (Just e)) = fancyU pus </> pretty i <+> ".<" <> pretty t <> ">." </> prettyArgs as <+> ":" <> text si <#> pretty rt <+> "=" <$> indent 2 (pretty e)- pretty (PreF i si pus us as (Just rt) (Just t) (Just e)) = fancyU pus </> pretty i </> fancyU us </> ".<" <> pretty t <> ">." </> prettyArgs as <+> ":" <> text si <#> pretty rt <+> "=" <$> indent 2 (pretty e)- pretty (PreF i si pus us as (Just rt) Nothing (Just e)) = fancyU pus </> pretty i </> fancyU us </> prettyArgs as <+> ":" <> text si <#> pretty rt <+> "=" <$> indent 2 (pretty e)- pretty (PreF i si [] [] as (Just rt) Nothing Nothing) = pretty i <> prettyArgs as <+> ":" <> text si <#> pretty rt- pretty (PreF i si [] us [] (Just rt) Nothing Nothing) = pretty i </> fancyU us <+> ":" <> text si <#> pretty rt- pretty (PreF i si [] us as (Just rt) Nothing Nothing) = pretty i </> fancyU us </> prettyArgs as <+> ":" <> text si <#> pretty rt- pretty (PreF i si pus us as (Just rt) Nothing Nothing) = fancyU pus </> pretty i </> fancyU us </> prettyArgs as <+> ":" <> text si <#> pretty rt- pretty _ = undefined--instance Pretty DataPropLeaf where- pretty (DataPropLeaf us e Nothing) = "|" <+> foldMap pretty (reverse us) <+> pretty e- pretty (DataPropLeaf us e (Just e')) = "|" <+> foldMap pretty (reverse us) <+> pretty e <+> "of" <+> pretty e'--instance Pretty Declaration where- pretty (AbsType _ s as Nothing) = "abstype" <+> text s <> prettyArgs as- pretty (AbsViewType _ s as Nothing) = "absvtype" <+> text s <> prettyArgs as- pretty (AbsViewType _ s as (Just t)) = "absvtype" <+> text s <> prettyArgs as <+> "=" <+> pretty t- pretty (SumViewType s [] ls) = "datavtype" <+> text s <+> "=" <$> prettyLeaf ls- pretty (SumViewType s as ls) = "datavtype" <+> text s <> prettyArgs as <+> "=" <$> prettyLeaf ls- pretty (SumType s [] ls) = "datatype" <+> text s <+> "=" <$> prettyLeaf ls- pretty (SumType s as ls) = "datatype" <+> text s <> prettyArgs as <+> "=" <$> prettyLeaf ls- pretty (Impl [] i) = pretty i- pretty (PrVal p e) = "prval" <+> pretty p <+> "=" <+> pretty e- pretty (Val a Nothing p e) = "val" <> pretty a <+> pretty p <+> "=" <+> pretty e- pretty (Val a (Just t) p e) = "val" <> pretty a <+> pretty p <> ":" <+> pretty t <+> "=" <+> pretty e- pretty (Var (Just t) p Nothing e) = "var" <+> pretty p <> ":" <+> pretty t <+> "with" <+> pretty e- pretty (Var Nothing p e Nothing) = "var" <+> pretty p <+> "=" <+> pretty e- pretty (Var (Just t) p e Nothing) = "var" <+> pretty p <> ":" <+> pretty t <+> "=" <+> pretty e- pretty (Include s) = "#include" <+> pretty s- pretty (Staload Nothing s) = "staload" <+> pretty s- pretty (Staload (Just q) s) = "staload" <+> pretty q <+> "=" <+> pretty s- pretty (CBlock s) = string s- pretty (Comment s) = string s- pretty (OverloadOp _ o n) = "overload" <+> pretty o <+> "with" <+> pretty n- pretty (OverloadIdent _ i n Nothing) = "overload" <+> text i <+> "with" <+> pretty n- pretty (OverloadIdent _ i n (Just n')) = "overload" <+> text i <+> "with" <+> pretty n <+> "of" <+> pretty n'- -- We use 'text' here, which means indentation might get fucked up for- -- C preprocessor macros, but you absolutely deserve it if you indent your- -- macros.- pretty (Define s) = text s- pretty (Func _ (Fn pref)) = "fn" </> pretty pref- pretty (Func _ (Fun pref)) = "fun" </> pretty pref- pretty (Func _ (CastFn pref)) = "castfn" </> pretty pref- pretty (Func _ (Fnx pref)) = "fnx" </> pretty pref- pretty (Func _ (And pref)) = "and" </> pretty pref- pretty (Func _ (Praxi pref)) = "praxi" </> pretty pref- pretty (Func _ (PrFun pref)) = "prfun" </> pretty pref- pretty (Func _ (PrFn pref)) = "prfn" </> pretty pref- pretty (Extern _ d) = "extern" <$> pretty d- pretty (DataProp _ s as ls) = "dataprop" <+> text s <> prettyArgs as <+> "=" <$> prettyDL ls- pretty (ViewTypeDef _ s [] t) = "vtypedef" <+> text s <+> "=" <#> pretty t- pretty (ViewTypeDef _ s as t) = "vtypedef" <+> text s <> prettyArgs as <+> "=" <#> pretty t- pretty (TypeDef _ s [] t) = "typedef" <+> text s <+> "=" <+> pretty t- pretty (TypeDef _ s as t) = "typedef" <+> text s <> prettyArgs as <+> "=" <+> pretty t- pretty (AbsProp _ n as) = "absprop" <+> text n <+> prettyArgs as- pretty (Assume n as e) = "assume" </> pretty n <> prettyArgs as <+> "=" </> pretty e- pretty (SymIntr _ n) = "symintr" <+> pretty n- pretty (Stacst _ n t Nothing) = "stacst" </> pretty n <+> ":" </> pretty t- pretty (Stacst _ n t (Just e)) = "stacst" </> pretty n <+> ":" </> pretty t <+> "=" </> pretty e- pretty (PropDef _ s as t) = "propdef" </> text s <+> prettyArgs as <+> "=" </> pretty t- pretty (Local _ d d') = "local" <$> indent 2 (pretty d) <$> "in" <$> indent 2 (pretty d') <$> "end"- pretty _ = undefined
− src/Language/ATS/Types.hs
@@ -1,361 +0,0 @@-{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveFoldable #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveTraversable #-}-{-# LANGUAGE DerivingStrategies #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}---- | This is a module containing types to model the ATS syntax tree. As it is--- collapsed by the pretty printer, you may see that in some places it is--- focused on the lexical side of things.-module Language.ATS.Types- ( ATS (..)- , Declaration (..)- , Type (..)- , Name (..)- , Pattern (..)- , PatternF (..)- , Arg (..)- , Universal (..)- , Function (..)- , Expression (..)- , ExpressionF (..)- , Implementation (..)- , BinOp (..)- , UnOp (..)- , TypeF (..)- , Existential (..)- , LambdaType (..)- , Addendum (..)- , DataPropLeaf (..)- , PreFunction (..)- , Paired (..)- , Leaf (..)- , StaticExpression (..)- , StaticExpressionF (..)- , Fixity (..)- , StackFunction (..)- , rewriteATS- , rewriteDecl- -- * Lenses- , leaves- , constructorUniversals- ) where--import Control.DeepSeq (NFData)-import Control.Lens-import Data.Functor.Foldable (ListF (Cons), ana, cata, embed, project)-import Data.Functor.Foldable.TH (makeBaseFunctor)-import Data.Maybe (isJust)-import Data.Semigroup (Semigroup)-import GHC.Generics (Generic)-import Language.ATS.Lexer (Addendum (..), AlexPosn)--data Fixity = RightFix AlexPosn- | LeftFix AlexPosn- | Pre AlexPosn- | Post AlexPosn- deriving (Show, Eq, Generic, NFData)---- | Newtype wrapper containing a list of declarations-newtype ATS = ATS { unATS :: [Declaration] }- deriving (Show, Eq, Generic)- deriving newtype (NFData, Semigroup, Monoid)--data Leaf = Leaf { _constructorUniversals :: [Universal], name :: String, constructorArgs :: [String], maybeType :: Maybe Type }- deriving (Show, Eq, Generic, NFData)---- | Declare something in a scope (a function, value, action, etc.)-data Declaration = Func AlexPosn Function- | Impl [Arg] Implementation- | ProofImpl Implementation -- primplmnt -- TODO add args- | Val Addendum (Maybe Type) Pattern Expression- | StaVal [Universal] String Type- | PrVal Pattern Expression- | Var (Maybe Type) Pattern (Maybe Expression) (Maybe Expression) -- TODO AlexPosn- | AndDecl (Maybe Type) Pattern Expression- | Include String- | Staload (Maybe String) String- | Stadef String Name [Type]- | CBlock String- | TypeDef AlexPosn String [Arg] Type- | ViewTypeDef AlexPosn String [Arg] Type- | SumType { typeName :: String, typeArgs :: [Arg], _leaves :: [Leaf] }- | SumViewType { typeName :: String, typeArgs :: [Arg], _leaves :: [Leaf] }- | AbsType AlexPosn String [Arg] (Maybe Type)- | AbsViewType AlexPosn String [Arg] (Maybe Type)- | AbsView AlexPosn String [Arg] (Maybe Type)- | AbsVT0p AlexPosn String [Arg] (Maybe Type)- | AbsT0p AlexPosn String Type- | ViewDef AlexPosn String [Arg] Type- | OverloadOp AlexPosn BinOp Name- | OverloadIdent AlexPosn String Name (Maybe Int)- | Comment String- | DataProp AlexPosn String [Arg] [DataPropLeaf]- | Extern AlexPosn Declaration- | Define String- | SortDef AlexPosn String Type- | AndD Declaration Declaration- | Local AlexPosn ATS ATS- | AbsProp AlexPosn String [Arg]- | Assume Name [Arg] Expression- | TKind AlexPosn Name String- | SymIntr AlexPosn Name- | Stacst AlexPosn Name Type (Maybe Expression)- | PropDef AlexPosn String [Arg] Type- -- uses an 'Int' because you fully deserve what you get if your- -- fixity declarations overflow.- | FixityDecl Fixity (Maybe Int) [String]- deriving (Show, Eq, Generic, NFData)--data DataPropLeaf = DataPropLeaf [Universal] Expression (Maybe Expression)- deriving (Show, Eq, Generic, NFData)---- | A type for parsed ATS types-data Type = Bool- | Void- | String- | Char- | Int- | Nat- | Addr- | DependentInt StaticExpression- | DependentBool StaticExpression- | DepString StaticExpression- | Double- | Float- | Tuple AlexPosn [Type]- | Named Name- | Ex Existential Type- | ForA Universal Type- | Dependent Name [Type]- | Unconsumed Type -- !a- | AsProof Type (Maybe Type) -- a >> b- | FromVT Type -- For a viewtype VT, we can prove there exist a view V and type T such that `VT` is equivalent to `(V | T)` - that T is `VT?!`- | MaybeVal Type -- This is just `a?` or the like- | T0p Addendum -- t@ype- | Vt0p Addendum -- vt@ype- | At AlexPosn (Maybe Type) Type- | ProofType AlexPosn Type Type -- Aka (prf | val)- | ConcreteType StaticExpression- | RefType Type- | ViewType AlexPosn Type- | FunctionType String Type Type- | NoneType AlexPosn- | ImplicitType AlexPosn- | ViewLiteral Addendum- | AnonymousRecord AlexPosn [(String, Type)]- deriving (Show, Eq, Generic, NFData)---- | A type for the various lambda arrows (@=>@, @=\<cloref1>@, etc.)-data LambdaType = Plain AlexPosn- | Full AlexPosn String- | Spear AlexPosn- deriving (Show, Eq, Generic, NFData)---- | A name can be qualified (@$UN.unsafefn@) or not-data Name = Unqualified String- | Qualified AlexPosn String String- | SpecialName AlexPosn String- | Functorial String String- | Unnamed AlexPosn- deriving (Show, Eq, Generic, NFData)---- | A data type for patterns.-data Pattern = Wildcard AlexPosn- | PName String [Pattern]- | PSum String Pattern- | PLiteral Expression- | Guarded AlexPosn Expression Pattern- | Free Pattern- | Proof AlexPosn [Pattern] [Pattern]- | TuplePattern [Pattern]- | AtPattern AlexPosn Pattern- | UniversalPattern AlexPosn String [Universal] Pattern- | ExistentialPattern Existential Pattern- deriving (Show, Eq, Generic, NFData)--data Paired a b = Both a b- | First a- | Second b- deriving (Show, Eq, Generic, NFData)---- | An argument to a function.-data Arg = Arg (Paired String Type)- | PrfArg Arg Arg- | NoArgs- deriving (Show, Eq, Generic, NFData)---- | Wrapper for universal quantifiers (refinement types)-data Universal = Universal { bound :: [Arg], typeU :: Maybe Type, prop :: Maybe StaticExpression } -- TODO NonEmpty type?- deriving (Show, Eq, Generic, NFData)---- | Wrapper for existential quantifiers/types-data Existential = Existential { boundE :: [Arg], isOpen :: Bool, typeE :: Maybe Type, propE :: Maybe StaticExpression }- deriving (Show, Eq, Generic, NFData)---- | @~@ is used to negate numbers in ATS-data UnOp = Negate- deriving (Show, Eq, Generic, NFData)---- | Binary operators on expressions-data BinOp = Add- | Mult- | Div- | Sub- | GreaterThan- | GreaterThanEq- | LessThan- | LessThanEq- | Equal- | NotEqual- | LogicalAnd- | LogicalOr- | StaticEq- | Mod- deriving (Show, Eq, Generic, NFData)---- FIXME add position information?-data StaticExpression = StaticVal Name- | StaticBinary BinOp StaticExpression StaticExpression- | StaticInt Int- | SPrecede StaticExpression StaticExpression- | StaticBool Bool- | StaticVoid AlexPosn- | Sif { scond :: StaticExpression, wwhenTrue :: StaticExpression, selseExpr :: StaticExpression } -- Static if (for proofs)- | SCall Name [StaticExpression]- deriving (Show, Eq, Generic, NFData)---- | A (possibly effectful) expression.-data Expression = Let AlexPosn ATS (Maybe Expression)- | VoidLiteral -- The '()' literal representing inaction.- AlexPosn- -- function call: <a>, then {n}- | Call Name [Type] [Type] (Maybe Expression) [Expression]- | NamedVal Name- | ListLiteral AlexPosn String Type [Expression]- | If { cond :: Expression -- ^ Expression evaluating to a boolean value- , whenTrue :: Expression -- ^ Expression to be returned when true- , elseExpr :: Maybe Expression -- ^ Expression to be returned when false- }- | BoolLit Bool- | TimeLit String- | FloatLit Float- | IntLit Int- | UnderscoreLit AlexPosn- | Lambda AlexPosn LambdaType Pattern Expression- | LinearLambda AlexPosn LambdaType Pattern Expression- | Index AlexPosn Name Expression- | Access AlexPosn Expression Name- | StringLit String- | CharLit Char- | AtExpr Expression Expression- | AddrAt AlexPosn Expression- | ViewAt AlexPosn Expression- | Binary BinOp Expression Expression- | Unary UnOp Expression- | Case { posE :: AlexPosn- , kind :: Addendum- , val :: Expression- , arms :: [(Pattern, LambdaType, Expression)] -- ^ Each @(Pattern, Expression)@ pair corresponds to a branch of the 'case' statement- }- | RecordValue AlexPosn [(String, Expression)] (Maybe Type)- | Precede Expression Expression- | FieldMutate { posE :: AlexPosn- , old :: Expression -- ^ Record to modify- , field :: String -- ^ Field being modified- , new :: Expression -- ^ New value of the field- }- | Mutate Expression Expression- | Deref AlexPosn Expression- | ProofExpr AlexPosn Expression Expression- | TypeSignature Expression Type- | WhereExp Expression [Declaration]- | TupleEx AlexPosn [Expression]- | While AlexPosn Expression Expression- | Actions ATS- | Begin AlexPosn Expression- | BinList { _op :: BinOp, _exprs :: [Expression] }- | PrecedeList { _exprs :: [Expression] }- | FixAt String StackFunction- | LambdaAt StackFunction- | ParenExpr AlexPosn Expression- deriving (Show, Eq, Generic, NFData)---- | An 'implement' declaration-data Implementation = Implement { pos :: AlexPosn- , preUniversalsI :: [Universal]- , universalsI :: [Universal] -- ^ Universal quantifiers- , nameI :: Name -- ^ Name of the template being implemented- , iArgs :: [Arg] -- ^ Arguments- , iExpression :: Expression -- ^ Expression holding the function body.- }- deriving (Show, Eq, Generic, NFData)---- | A function declaration accounting for all three keywords (???) ATS uses to--- define them.-data Function = Fun PreFunction- | Fn PreFunction- | Fnx PreFunction- | And PreFunction- | PrFun PreFunction- | PrFn PreFunction- | Praxi PreFunction- | CastFn PreFunction- deriving (Show, Eq, Generic, NFData)--data StackFunction = StackF { stSig :: String- , stArgs :: [Arg]- , stReturnType :: Type- , stExpression :: Expression- }- deriving (Show, Eq, Generic, NFData)--data PreFunction = PreF { fname :: Name -- ^ Function name- , sig :: String -- ^ e.g. <> or \<!wrt>- , preUniversals :: [Universal] -- ^ Universal quantifiers making a function generic- , universals :: [Universal] -- ^ Universal quantifiers/refinement type- , args :: [Arg] -- ^ Actual function arguments- , returnType :: Maybe Type -- ^ Return type- , termetric :: Maybe StaticExpression -- ^ Optional termination metric- , expression :: Maybe Expression -- ^ Expression holding the actual function body (not present in static templates)- }- deriving (Show, Eq, Generic, NFData)--makeBaseFunctor ''Pattern-makeBaseFunctor ''Expression-makeBaseFunctor ''StaticExpression-makeBaseFunctor ''Type-makeLenses ''Leaf-makeLenses ''Declaration--rewriteDecl :: Declaration -> Declaration-rewriteDecl x@SumViewType{} = g x- where g = over (leaves.mapped.constructorUniversals) h- h :: [Universal] -> [Universal]- h = ana c where- c (y:y':ys)- | typeU y == typeU y' && isJust (typeU y) =- Cons (Universal (bound y ++ bound y') (typeU y) (StaticBinary LogicalAnd <$> prop y <*> prop y')) ys- c y = project y-rewriteDecl x = x---- precedence: rewrite n + 2 * x to n + (2 * x)--- TODO: rewrite multiple universals when it's the right context?-rewriteATS :: Expression -> Expression-rewriteATS = cata a where- a (CallF n ts ts' me [ParenExpr _ e@NamedVal{}]) = Call n ts ts' me [e]- a (CallF n ts ts' me [ParenExpr _ e@Call{}]) = Call n ts ts' me [e]- a (PrecedeF e e'@PrecedeList{}) = PrecedeList (e : _exprs e')- a (PrecedeF e e') = PrecedeList [e, e']- a (BinaryF Mult (Binary Add e e') e'') = Binary Add e (Binary Mult e' e'')- a (BinaryF Add e (BinList Add es)) = BinList Add (e : es)- a (BinaryF Add e e') = BinList Add [e, e']- a (ParenExprF _ e@Precede{}) = e- a (ParenExprF _ e@PrecedeList{}) = e- a x = embed x
stack.yaml view
@@ -9,6 +9,7 @@ - dirstream-1.0.3 - hspec-dirstream-0.3.0.0 - cli-setup-0.1.0.3+ - language-ats-0.1.0.0 flags: ats-format: development: false
− test/Spec.hs
@@ -1,14 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--import qualified Filesystem.Path.CurrentOS as F-import Language.ATS-import Test.Hspec-import Test.Hspec.Dirstream--isATS :: F.FilePath -> Bool-isATS x = (extension x `elem`) (pure <$> ["ats", "dats", "sats", "hats", "cats"])--main :: IO ()-main = hspec $- describe "pretty-print" $ parallel $- testFiles "test/data" isATS (fmap printATS . parseATS . lexATS)
− test/data/combinatorics.dats
@@ -1,40 +0,0 @@-#define ATS_MAINATSFLAG 1--#include "share/atspre_staload.hats"--staload "contrib/atscntrb-hx-intinf/SATS/intinf_t.sats"-staload "libats/libc/SATS/math.sats"-staload "contrib/atscntrb-hx-intinf/SATS/intinf.sats"-staload UN = "prelude/SATS/unsafe.sats"--fnx fact {n : nat} .<n>. (k : int(n)) : [ n : nat | n > 0 ] intinf(n) =- case+ k of- | 0 => int2intinf(1)- | 1 => int2intinf(1)- | k =>> $UN.cast(fact(k - 1) * k)--// double factorial http://mathworld.wolfram.com/DoubleFactorial.html-fnx dfact {n : nat} .<n>. (k : int(n)) : Intinf =- case+ k of- | 0 => int2intinf(1)- | 1 => int2intinf(1)- | k =>> k * dfact(k - 2)--// Number of permutations on n objects using k at a time.-fn permutatsions {n : nat}{ k : nat | k <= n } (n : int(n), k : int(k)) : Intinf =- ndiv(fact(n), fact(n - k))--// Number of permutations on n objects using k at a time.-fn choose {n : nat}{ m : nat | m <= n } (n : int(n), k : int(m)) : Intinf =- let- fun numerator_loop { m : nat | m > 1 } .<m>. (i : int(m)) : [ n : nat | n > 0 ] intinf(n) =- case+ i of- | 1 => int2intinf(n)- | 2 => $UN.cast(int2intinf(n - 1) * n)- | i =>> $UN.cast((n + 1 - i) * numerator_loop(i - 1))- in- case+ k of- | 0 => int2intinf(1)- | 1 => int2intinf(n)- | k =>> ndiv(numerator_loop(k), fact(k))- end
− test/data/combinatorics.out
@@ -1,43 +0,0 @@-#define ATS_MAINATSFLAG 1--#include "share/atspre_staload.hats"--staload "contrib/atscntrb-hx-intinf/SATS/intinf_t.sats"-staload "libats/libc/SATS/math.sats"-staload "contrib/atscntrb-hx-intinf/SATS/intinf.sats"-staload UN = "prelude/SATS/unsafe.sats"--fnx fact {n:nat} .<n>. (k : int(n)) : [ n : nat | n > 0 ] intinf(n) =- case+ k of- | 0 => int2intinf(1)- | 1 => int2intinf(1)- | k =>> $UN.cast(fact(k - 1) * k)--// double factorial http://mathworld.wolfram.com/DoubleFactorial.html-fnx dfact {n:nat} .<n>. (k : int(n)) : Intinf =- case+ k of- | 0 => int2intinf(1)- | 1 => int2intinf(1)- | k =>> k * dfact(k - 2)--// Number of permutations on n objects using k at a time.-fn permutatsions {n:nat}{ k : nat | k <= n } (n : int(n), k : int(k)) :- Intinf =- ndiv(fact(n), fact(n - k))--// Number of permutations on n objects using k at a time.-fn choose {n:nat}{ m : nat | m <= n } (n : int(n), k : int(m)) :- Intinf =- let- fun numerator_loop { m : nat | m > 1 } .<m>. (i : int(m)) :- [ n : nat | n > 0 ] intinf(n) =- case+ i of- | 1 => int2intinf(n)- | 2 => $UN.cast(int2intinf(n - 1) * n)- | i =>> $UN.cast((n + 1 - i) * numerator_loop(i - 1))- in- case+ k of- | 0 => int2intinf(1)- | 1 => int2intinf(n)- | k =>> ndiv(numerator_loop(k), fact(k))- end
− test/data/concurrency.dats
@@ -1,257 +0,0 @@-// This is mostly taken from the example in the book.--#include "share/atspre_staload.hats"-#include "share/atspre_staload_libats_ML.hats"-#include "libats/DATS/athread_posix.dats"--staload "libats/SATS/athread.sats"-staload "src/filetype.sats"-staload "libats/SATS/funarray.sats"-staload "libats/SATS/deqarray.sats"-staload _ = "libats/DATS/deqarray.dats"--absvtype queue_vtype(a: vt@ype+, int) = ptr--vtypedef queue(a: vt0p, id: int) = queue_vtype(a, id)-vtypedef queue(a: vt0p) = [id:int] queue(a, id)--absprop ISNIL(id: int, b: bool)--extern fun {a:vt0p} queue_is_nil {id:int} (!queue(a, id)) : [b:bool] (ISNIL(id, b) | bool(b))--absprop ISFULL(id: int, b: bool)--extern fun {a:vt0p} queue_is_full {id:int} (!queue(a, id)) : [b:bool] (ISFULL(id, b) | bool(b))--extern fun {a:vt0p} queue_insert {id:int} (ISFULL(id, false) | xs: !queue(a, id) >> queue(a, id2), x: a) : #[id2:int] void--extern fun {a:vt0p} queue_remove {id:int} (ISNIL(id, false) | xs: !queue(a, id) >> queue(a, id2)) : #[id2:int] a--extern fun {a:vt0p} queue_make (cap: intGt(0)) : queue(a)--extern fun {a:t@ype} queue_free(que: queue(a)) : void--assume queue_vtype(a: vt0p, id: int) = deqarray(a)-assume ISNIL(id: int, b: bool) = unit_p-assume ISFULL(id: int, b: bool) = unit_p--absvtype channel_vtype(a: vt@ype+) = ptr--vtypedef channel(a: vt0p) = channel_vtype(a)--extern fun {a:vt0p} channel_insert (!channel(a), a) : void--extern fun {a:vt0p} channel_remove (chan: !channel(a)) : a--extern fun {a:vt0p} channel_remove_helper (chan: !channel(a), !queue(a) >> _) : a--extern fun {a:vt0p} channel_insert_helper (!channel(a), !queue(a) >> _, a) : void--datavtype channel_ = {l0,l1,l2,l3:agz} CHANNEL of- @{ cap = intGt(0)- , spin = spin_vt(l0)- , refcount = intGt(0)- , mutex = mutex_vt(l1)- , CVisNil = condvar_vt(l2)- , CVisFull = condvar_vt(l3)- , queue = ptr- }--extern fun {a:vt0p} channel_make(cap: intGt(0)) : channel(a)--extern fun {a:vt0p} channel_ref(ch: !channel(a)) : channel(a)--extern fun {a:vt0p} channel_unref(ch: channel(a)) : Option_vt(queue(a))--extern fun channel_refcount{a:vt0p}(ch: !channel(a)) : intGt(0)--assume channel_vtype(a:vt0p) = channel_--implement {a} queue_is_nil(xs) = (unit_p() | deqarray_is_nil(xs))--implement {a} queue_is_full(xs) = (unit_p() | deqarray_is_full(xs))--implement {a} queue_remove(prf | xs) = - let- prval () = __assert(prf) where { extern praxi __assert {id:int} (p: ISNIL(id, false)) : [false] void }- in- deqarray_takeout_atbeg<a> (xs)- end--implement {a} queue_insert(prf | xs, x) = - { - prval () = __assert(prf) where { extern praxi __assert {id:int} (p: ISFULL(id, false)) : [false] void }- val () = deqarray_insert_atend<a>(xs, x)- }--implement {a} queue_make(cap) = deqarray_make_cap(i2sz(cap))--implement {a} queue_free(que) = deqarray_free_nil($UN.castvwtp0{deqarray(a, 1, 0)}(que))--implement {a} channel_ref(chan) =- let- val@ CHANNEL(ch) = chan- val spin = unsafe_spin_vt2t(ch.spin)- val (prf | ()) = spin_lock(spin)- val () = ch.refcount := ch.refcount + 1- val () = spin_unlock (prf | spin)- prval () = fold@(chan)- in- $UN.castvwtp1{channel(a)}(chan)- end--implement {a} channel_unref(chan) = - let- val@ CHANNEL{l0,l1,l2,l3}(ch) = chan- val spin = unsafe_spin_vt2t(ch.spin)- val (prf | ()) = spin_lock(spin)- val () = spin_unlock(prf | spin)- val refcount = ch.refcount // needed to make the theorem prover work- in- if refcount <= 1 then- let- val que = $UN.castvwtp0{queue(a)}(ch.queue)- val () = spin_vt_destroy(ch.spin)- val () = mutex_vt_destroy(ch.mutex)- val () = condvar_vt_destroy(ch.CVisNil)- val () = condvar_vt_destroy(ch.CVisFull)- val () = free@{l0,l1,l2,l3}(chan)- in- Some_vt(que)- end- else- let- val () = ch.refcount := refcount - 1- prval () = fold@chan- prval () = $UN.cast2void(chan)- in- None_vt()- end- end--implement channel_refcount{a}(chan) =- let- val@ CHANNEL{l0,l1,l2,l3}(ch) = chan- val refcount = ch.refcount- in- fold@(chan) ; refcount- end--implement {a} channel_make(cap) = - let- extern praxi __assert() : [l:agz] void-- prval [l0:addr] () = __assert()- prval [l1:addr] () = __assert()- prval [l2:addr] () = __assert()- prval [l3:addr] () = __assert()-- val chan = CHANNEL{l0,l1,l2,l3}(_)- val+ CHANNEL(ch) = chan-- val () = ch.cap := cap- val () = ch.refcount := 1- - local - val x = spin_create_exn()- in- val () = ch.spin := unsafe_spin_t2vt(x)- end-- local- val x = mutex_create_exn()- in- val () = ch.mutex := unsafe_mutex_t2vt(x)- end-- local- val x = condvar_create_exn()- in- val () = ch.CVisNil := unsafe_condvar_t2vt(x)- end-- local- val x = condvar_create_exn()- in- val () = ch.CVisFull := unsafe_condvar_t2vt(x)- end-- val () = ch.queue := $UN.castvwtp0{ptr}(queue_make<a>(cap))-- in- fold@(chan) ; chan- end--implement {a} channel_insert(chan, x) = - let- val+ CHANNEL{l0,l1,l2,l3}(ch) = chan- val mutex = unsafe_mutex_vt2t(ch.mutex)- val (prf | ()) = mutex_lock(mutex)- val xs = $UN.castvwtp0{queue(a)}((prf | ch.queue))- val () = channel_insert_helper<a>(chan, xs, x)- prval prf = $UN.castview0{locked_v(l1)}(xs)- val () = mutex_unlock(prf | mutex)- in- end--implement {a} channel_remove(chan) = x where- {- val+ CHANNEL{l0,l1,l2,l3}(ch) = chan- val mutex = unsafe_mutex_vt2t(ch.mutex)- val (prf | ()) = mutex_lock(mutex)- val xs = $UN.castvwtp0{queue(a)}((prf | ch.queue))- val x = channel_remove_helper<a> (chan, xs)- prval prf = $UN.castview0{locked_v(l1)}(xs)- val () = mutex_unlock(prf | mutex)- }--implement {a} channel_remove_helper(chan, xs) =- let- val+ CHANNEL{l0,l1,l2,l3}(ch) = chan- val (prf | is_nil) = queue_is_nil(xs)- in- if is_nil then- let- prval (pfmut, fpf) = __assert() where { extern praxi __assert(): vtakeout0(locked_v(l1)) }- val mutex = unsafe_mutex_vt2t(ch.mutex)- val CVisNil = unsafe_condvar_vt2t(ch.CVisNil)- val () = condvar_wait(pfmut | CVisNil, mutex)- prval () = fpf(pfmut)- in- channel_remove_helper(chan, xs)- end- else- let- val is_full = queue_is_full(xs)- val x_out = queue_remove(prf | xs)- val () = if is_full.1 then- condvar_broadcast(unsafe_condvar_vt2t(ch.CVisFull))- in- x_out- end- end--implement {a} channel_insert_helper(chan, xs, x) = - let- val+ CHANNEL{l0,l1,l2,l3}(ch) = chan- val (prf | is_full) = queue_is_full(xs)- in- if is_full then- let- prval (pfmut, fpf) = __assert() where { extern praxi __assert() : vtakeout0(locked_v(l1)) }- val mutex = unsafe_mutex_vt2t(ch.mutex)- val CVisFull = unsafe_condvar_vt2t(ch.CVisFull)- val () = condvar_wait(pfmut | CVisFull, mutex)- prval () = fpf(pfmut)- in- channel_insert_helper(chan, xs, x)- end- else- let- val is_nil = queue_is_nil(xs)- val () = queue_insert(prf | xs, x)- val () = if is_nil.1 then- condvar_broadcast(unsafe_condvar_vt2t(ch.CVisNil))- in- end- end
− test/data/concurrency.out
@@ -1,287 +0,0 @@-// This is mostly taken from the example in the book.-#include "share/atspre_staload.hats"-#include "share/atspre_staload_libats_ML.hats"-#include "libats/DATS/athread_posix.dats"--staload "libats/SATS/athread.sats"-staload "src/filetype.sats"-staload "libats/SATS/funarray.sats"-staload "libats/SATS/deqarray.sats"-staload _ = "libats/DATS/deqarray.dats"--absvtype queue_vtype(a : vt@ype+, int) = ptr--vtypedef queue(a : vt0p, id : int) = queue_vtype(a, id)-vtypedef queue(a : vt0p) = [id:int] queue(a, id)--absprop ISNIL (id : int, b : bool)--extern-fun {a:vt0p} queue_is_nil {id:int} (!queue(a, id)) :- [b:bool] (ISNIL(id, b) | bool(b))--absprop ISFULL (id : int, b : bool)--extern-fun {a:vt0p} queue_is_full {id:int} (!queue(a, id)) :- [b:bool] (ISFULL(id, b) | bool(b))--extern-fun {a:vt0p} queue_insert {id:int}-(ISFULL(id,false) | xs : !queue(a, id) >> queue(a, id2), x : a) :- #[id2:int] void--extern-fun {a:vt0p} queue_remove {id:int}-(ISNIL(id,false) | xs : !queue(a, id) >> queue(a, id2)) : #[id2:int] a--extern-fun {a:vt0p} queue_make (cap : intGt(0)) : queue(a)--extern-fun {a:t@ype} queue_free (que : queue(a)) : void--assume queue_vtype(a : vt0p, id : int) = deqarray(a)--assume ISNIL(id : int, b : bool) = unit_p--assume ISFULL(id : int, b : bool) = unit_p--absvtype channel_vtype(a : vt@ype+) = ptr--vtypedef channel(a : vt0p) = channel_vtype(a)--extern-fun {a:vt0p} channel_insert (!channel(a), a) : void--extern-fun {a:vt0p} channel_remove (chan : !channel(a)) : a--extern-fun {a:vt0p} channel_remove_helper ( chan : !channel(a)- , !queue(a) >> _- ) : a--extern-fun {a:vt0p} channel_insert_helper (!channel(a), !queue(a) >> _, a) :- void--datavtype channel_ =- | { l0, l1, l2, l3 : agz } CHANNEL of @{ cap = intGt(0)- , spin = spin_vt(l0)- , refcount = intGt(0)- , mutex = mutex_vt(l1)- , CVisNil = condvar_vt(l2)- , CVisFull = condvar_vt(l3)- , queue = ptr- }--extern-fun {a:vt0p} channel_make (cap : intGt(0)) : channel(a)--extern-fun {a:vt0p} channel_ref (ch : !channel(a)) : channel(a)--extern-fun {a:vt0p} channel_unref (ch : channel(a)) : Option_vt(queue(a))--extern-fun channel_refcount {a:vt0p} (ch : !channel(a)) : intGt(0)--assume channel_vtype(a : vt0p) = channel_--implement {a} queue_is_nil (xs) =- (unit_p() | deqarray_is_nil(xs))--implement {a} queue_is_full (xs) =- (unit_p() | deqarray_is_full(xs))--implement {a} queue_remove (prf | xs) =- let- prval () = __assert(prf) where- { extern- praxi __assert {id:int} (p : ISNIL(id, false)) : [ false ] void }- in- deqarray_takeout_atbeg<a>(xs)- end--implement {a} queue_insert (prf | xs, x) =- {- prval () = __assert(prf) where- { extern- praxi __assert {id:int} (p : ISFULL(id, false)) : [ false ] void }- val () = deqarray_insert_atend<a>(xs, x)- }--implement {a} queue_make (cap) =- deqarray_make_cap(i2sz(cap))--implement {a} queue_free (que) =- deqarray_free_nil($UN.castvwtp0{deqarray(a, 1, 0)}(que))--implement {a} channel_ref (chan) =- let- val @CHANNEL (ch) = chan- val spin = unsafe_spin_vt2t(ch.spin)- val (prf | ()) = spin_lock(spin)- val () = ch.refcount := ch.refcount + 1- val () = spin_unlock(prf | spin)- prval () = fold@(chan)- in- $UN.castvwtp1{channel(a)}(chan)- end--implement {a} channel_unref (chan) =- let- val @CHANNEL{ l0, l1, l2, l3 }(ch) = chan- val spin = unsafe_spin_vt2t(ch.spin)- val (prf | ()) = spin_lock(spin)- val () = spin_unlock(prf | spin)- val refcount = ch.refcount- in- if refcount <= 1 then- let- val que = $UN.castvwtp0{queue(a)}(ch.queue)- val () = spin_vt_destroy(ch.spin)- val () = mutex_vt_destroy(ch.mutex)- val () = condvar_vt_destroy(ch.CVisNil)- val () = condvar_vt_destroy(ch.CVisFull)- val () = free@{l0,l1,l2,l3}(chan)- in- Some_vt(que)- end- else- let- val () = ch.refcount := refcount - 1- prval () = fold@(chan)- prval () = $UN.cast2void(chan)- in- None_vt()- end- end--implement channel_refcount {a} (chan) =- let- val @CHANNEL{ l0, l1, l2, l3 }(ch) = chan- val refcount = ch.refcount- in- (fold@(chan) ; refcount)- end--implement {a} channel_make (cap) =- let- extern- praxi __assert() : [l:agz] void- - prval [l0:addr]() = __assert()- prval [l1:addr]() = __assert()- prval [l2:addr]() = __assert()- prval [l3:addr]() = __assert()- val chan = CHANNEL{l0,l1,l2,l3}(_)- val+ CHANNEL (ch) = chan- val () = ch.cap := cap- val () = ch.refcount := 1- - local- val x = spin_create_exn()- in- val () = ch.spin := unsafe_spin_t2vt(x)- end- - local- val x = mutex_create_exn()- in- val () = ch.mutex := unsafe_mutex_t2vt(x)- end- - local- val x = condvar_create_exn()- in- val () = ch.CVisNil := unsafe_condvar_t2vt(x)- end- - local- val x = condvar_create_exn()- in- val () = ch.CVisFull := unsafe_condvar_t2vt(x)- end- - val () = ch.queue := $UN.castvwtp0{ptr}(queue_make<a>(cap))- in- (fold@(chan) ; chan)- end--implement {a} channel_insert (chan, x) =- let- val+ CHANNEL{ l0, l1, l2, l3 }(ch) = chan- val mutex = unsafe_mutex_vt2t(ch.mutex)- val (prf | ()) = mutex_lock(mutex)- val xs = $UN.castvwtp0{queue(a)}((prf | ch.queue))- val () = channel_insert_helper<a>(chan, xs, x)- prval prf = $UN.castview0{locked_v(l1)}(xs)- val () = mutex_unlock(prf | mutex)- in end--implement {a} channel_remove (chan) =- x where- { val+ CHANNEL{ l0, l1, l2, l3 }(ch) = chan- val mutex = unsafe_mutex_vt2t(ch.mutex)- val (prf | ()) = mutex_lock(mutex)- val xs = $UN.castvwtp0{queue(a)}((prf | ch.queue))- val x = channel_remove_helper<a>(chan, xs)- prval prf = $UN.castview0{locked_v(l1)}(xs)- val () = mutex_unlock(prf | mutex) }--implement {a} channel_remove_helper (chan, xs) =- let- val+ CHANNEL{ l0, l1, l2, l3 }(ch) = chan- val (prf | is_nil) = queue_is_nil(xs)- in- if is_nil then- let- prval (pfmut, fpf) = __assert() where- { extern- praxi __assert() : vtakeout0(locked_v(l1)) }- val mutex = unsafe_mutex_vt2t(ch.mutex)- val CVisNil = unsafe_condvar_vt2t(ch.CVisNil)- val () = condvar_wait(pfmut | CVisNil, mutex)- prval () = fpf(pfmut)- in- channel_remove_helper(chan, xs)- end- else- let- val is_full = queue_is_full(xs)- val x_out = queue_remove(prf | xs)- val () = if is_full.1 then- condvar_broadcast(unsafe_condvar_vt2t(ch.CVisFull))- in- x_out- end- end--implement {a} channel_insert_helper (chan, xs, x) =- let- val+ CHANNEL{ l0, l1, l2, l3 }(ch) = chan- val (prf | is_full) = queue_is_full(xs)- in- if is_full then- let- prval (pfmut, fpf) = __assert() where- { extern- praxi __assert() : vtakeout0(locked_v(l1)) }- val mutex = unsafe_mutex_vt2t(ch.mutex)- val CVisFull = unsafe_condvar_vt2t(ch.CVisFull)- val () = condvar_wait(pfmut | CVisFull, mutex)- prval () = fpf(pfmut)- in- channel_insert_helper(chan, xs, x)- end- else- let- val is_nil = queue_is_nil(xs)- val () = queue_insert(prf | xs, x)- val () = if is_nil.1 then- condvar_broadcast(unsafe_condvar_vt2t(ch.CVisNil))- in end- end
− test/data/fact.dats
@@ -1,32 +0,0 @@-#include "share/atspre_staload.hats"-#include "share/HATS/atslib_staload_libats_libc.hats"--fnx fact_boring(n: int) : int =- case+ n of- | 0 => 1- | n => n * fact_boring(n-1)--(* fnx collatz{n:nat} *)-(* (n: int(n)) : int = let *)-(* fun loop{n:nat}{l:addr} .<n>. *)-(* (pf: !int @ l | n: int n, res: ptr l) : void = *)-(* if n > 1 *)--// TODO rewrite this for collatz?-fnx fact{n:nat}-(n: int (n)): int = let-fun loop{n:nat}{l:addr} .<n>.-(pf: !int @ l | n: int n, res: ptr l): void =-if n > 0 then let-val () = !res := n * !res in loop (pf | n-1, res)-end // end of [if]-// end of [loop]-var res: int with pf = 1-val () = loop (pf | n, addr@res) // addr@res: the pointer to res-in-res-end // end of [fact]--implement main0 () =- let val x = fact(30) in- println!(tostring_int(x)) end
− test/data/fact.out
@@ -1,39 +0,0 @@-#include "share/atspre_staload.hats"-#include "share/HATS/atslib_staload_libats_libc.hats"--fnx fact_boring(n : int) : int =- case+ n of- | 0 => 1- | n => n * fact_boring(n - 1)--(* fnx collatz{n:nat} *)-(* (n: int(n)) : int = let *)-(* fun loop{n:nat}{l:addr} .<n>. *)-(* (pf: !int @ l | n: int n, res: ptr l) : void = *)-(* if n > 1 *)-// TODO rewrite this for collatz?-fnx fact {n:nat} (n : int(n)) : int =- let- fun loop {n:nat}{l:addr} .<n>. ( pf : !int @ l | n : int(n)- , res : ptr(l)- ) : void =- if n > 0 then- let- val () = !res := n * !res- in- loop(pf | n - 1, res)- end- - // end of [loop]- var res: int with pf = 1- val () = loop(pf | n, addr@res)- in- res- end--implement main0 () =- let- val x = fact(30)- in- println!(tostring_int(x))- end
− test/data/factorial.dats
@@ -1,4 +0,0 @@-fun factorial_recursion {n:nat} .<n>. (n: int(n)) : int =-case+ n of-| 0 => 1-| n =>> factorial_recursion(n-1) * n
− test/data/factorial.out
@@ -1,4 +0,0 @@-fun factorial_recursion {n:nat} .<n>. (n : int(n)) : int =- case+ n of- | 0 => 1- | n =>> factorial_recursion(n - 1) * n
− test/data/fast-combinatorics.dats
@@ -1,93 +0,0 @@-#define ATS_MAINATSFLAG 1--#include "share/atspre_staload.hats"--staload "libats/libc/SATS/math.sats"--fnx fact {n : nat} .<n>. (k : int(n)) :<> int =- case+ k of- | 0 => 1- | k =>> fact(k - 1) * k--fnx dfact {n : nat} .<n>. (k : int(n)) :<> int =- case+ k of- | 0 => 1- | 1 => 1- | k =>> k * dfact(k - 2)--// TODO make this more versatile?-fn choose {n : nat}{ m : nat | m <= n } (n : int(n), k : int(m)) : int =- let- fun numerator_loop { m : nat | m > 1 } .<m>. (i : int(m)) : int =- case+ i of- | 1 => n- | 2 => (n - 1) * n- | i =>> (n + 1 - i) * numerator_loop(i - 1)- in- case+ k of- | 0 => 1- | 1 => n- | k =>> numerator_loop(k) / fact(k)- end--// FIXME-fun bad(n : int) : [ m : nat ] int(m) =- case+ n of- | 0 => 0- | n => 1 + bad(n - 1)--fun is_prime(k : intGt(0)) : bool =- case+ k of- | 1 => false- | k => - begin- let- var pre_bound: int = g0float2int(sqrt_float(g0int2float_int_float(k)))- var bound: [ m : nat ] int(m) = bad(pre_bound)- - fun loop {n : nat}{m : nat} .<max(0,m-n)>. (i : int(n), bound : int(m)) :<> bool =- if i < bound then- if k mod i = 0 then- false- else- true && loop(i + 1, bound)- else- if i = bound then- if k mod i = 0 then- false- else- true- else- true- in- loop(2, bound)- end- end--extern-fun choose_ats {n : nat}{ m : nat | m <= n } : (int(n), int(m)) -> int =- "mac#"--extern-fun double_factorial {n : nat} : int(n) -> int =- "mac#"--extern-fun factorial_ats {n : nat} : int(n) -> int =- "mac#"--extern-fun is_prime_ats { n : nat | n > 0 } : int(n) -> bool =- "mac#"--implement choose_ats (n, k) =- choose(n, k)--implement double_factorial (m) =- dfact(m)--implement is_prime_ats (n) =- is_prime(n)--implement factorial_ats (m) =- fact(m)
− test/data/fast-combinatorics.out
@@ -1,94 +0,0 @@-#define ATS_MAINATSFLAG 1--#include "share/atspre_staload.hats"--staload "libats/libc/SATS/math.sats"--fnx fact {n:nat} .<n>. (k : int(n)) :<> int =- case+ k of- | 0 => 1- | k =>> fact(k - 1) * k--fnx dfact {n:nat} .<n>. (k : int(n)) :<> int =- case+ k of- | 0 => 1- | 1 => 1- | k =>> k * dfact(k - 2)--// TODO make this more versatile?-fn choose {n:nat}{ m : nat | m <= n } (n : int(n), k : int(m)) : int =- let- fun numerator_loop { m : nat | m > 1 } .<m>. (i : int(m)) : int =- case+ i of- | 1 => n- | 2 => (n - 1) * n- | i =>> (n + 1 - i) * numerator_loop(i - 1)- in- case+ k of- | 0 => 1- | 1 => n- | k =>> numerator_loop(k) / fact(k)- end--// FIXME-fun bad(n : int) : [m:nat] int(m) =- case+ n of- | 0 => 0- | n => 1 + bad(n - 1)--fun is_prime(k : intGt(0)) : bool =- case+ k of- | 1 => false- | k => - begin- let- var pre_bound: int = g0float2int(sqrt_float(g0int2float_int_float(k)))- var bound: [m:nat] int(m) = bad(pre_bound)- - fun loop {n:nat}{m:nat} .<max(0,m-n)>. (i : int(n), bound : int(m)) :<>- bool =- if i < bound then- if k % i = 0 then- false- else- true && loop(i + 1, bound)- else- if i = bound then- if k % i = 0 then- false- else- true- else- true- in- loop(2, bound)- end- end--extern-fun choose_ats {n:nat}{ m : nat | m <= n } : (int(n), int(m)) -> int =- "mac#"--extern-fun double_factorial {n:nat} : int(n) -> int =- "mac#"--extern-fun factorial_ats {n:nat} : int(n) -> int =- "mac#"--extern-fun is_prime_ats { n : nat | n > 0 } : int(n) -> bool =- "mac#"--implement choose_ats (n, k) =- choose(n, k)--implement double_factorial (m) =- dfact(m)--implement is_prime_ats (n) =- is_prime(n)--implement factorial_ats (m) =- fact(m)
− test/data/fib.dats
@@ -1,6 +0,0 @@-#include "prelude/DATS/integer.dats"--fnx fib { n : int | n >= 0 } .<n>. (i : int(n)) : int =-case+ i of-| _ when i - 2 >= 0 => ( fib(i-1) + fib(i-2) )-| _ => 1
− test/data/fib.out
@@ -1,6 +0,0 @@-#include "prelude/DATS/integer.dats"--fnx fib { n : int | n >= 0 } .<n>. (i : int(n)) : int =- case+ i of- | _ when i - 2 >= 0 => (fib(i - 1) + fib(i - 2))- | _ => 1
− test/data/filecount.dats
@@ -1,31 +0,0 @@-#include "share/atspre_staload.hats"-#include "libats/ML/DATS/filebas_dirent.dats"-#include "libats/libc/DATS/dirent.dats"--staload "libats/ML/DATS/string.dats"--fun good_dir(next: string) : bool = case next of | "." => false | ".." => false | _ => true-fnx step_stream(acc: int, s: string) : int =-if test_file_isdir(s) != 0 then-flow_stream(s, acc + 1)-else-acc + 1-and flow_stream(s: string, init: int) : int =-let-var files = streamize_dirname_fname(s)-var ffiles = stream_vt_filter_cloptr(files, lam x => good_dir(x))-in-stream_vt_foldleft_cloptr(ffiles, init, lam (acc, next) => step_stream(acc, s + "/" + next))-end-fun count_files(s: string) : void =-let-var n: int = step_stream(0, g1ofg0(s))-in-println!(tostring_int(n))-end--implement main0 (argc, argv) =-if argc > 1 then-count_files(argv[1])-else-count_files(".")
− test/data/filecount.out
@@ -1,41 +0,0 @@-#include "share/atspre_staload.hats"-#include "libats/ML/DATS/filebas_dirent.dats"-#include "libats/libc/DATS/dirent.dats"--staload "libats/ML/DATS/string.dats"--fun good_dir(next : string) : bool =- case next of- | "." => false- | ".." => false- | _ => true--fnx step_stream(acc : int, s : string) : int =- if test_file_isdir(s) != 0 then- flow_stream(s, acc + 1)- else- acc + 1-and flow_stream(s : string, init : int) : int =- let- var files = streamize_dirname_fname(s)- var ffiles = stream_vt_filter_cloptr(files, lam x => good_dir(x))- in- stream_vt_foldleft_cloptr( ffiles- , init- , lam (acc, next) =>- step_stream(acc, s + "/" + next)- )- end--fun count_files(s : string) : void =- let- var n: int = step_stream(0, g1ofg0(s))- in- println!(tostring_int(n))- end--implement main0 (argc, argv) =- if argc > 1 then- count_files(argv[1])- else- count_files(".")
− test/data/filetype.out
@@ -1,180 +0,0 @@-// Type for a collection of files (monoidal)-typedef file = @{ lines = int, files = int }--// Type for the parsed command-line arguments. -typedef command_line = @{ version = bool- , help = bool- , table = bool- , excludes = [m:nat] list(string, m)- , includes = [m:nat] list(string, m)- }--// Program state, tracking *all* supported file types in an unboxed structure.-typedef source_contents = @{ rust = file- , haskell = file- , ats = file- , python = file- , vimscript = file- , elm = file- , idris = file- , madlang = file- , tex = file- , markdown = file- , yaml = file- , toml = file- , cabal = file- , happy = file- , alex = file- , go = file- , html = file- , css = file- , verilog = file- , vhdl = file- , c = file- , purescript = file- , futhark = file- , brainfuck = file- , ruby = file- , julia = file- , perl = file- , ocaml = file- , agda = file- , cobol = file- , tcl = file- , r = file- , lua = file- , cpp = file- , lalrpop = file- , header = file- , sixten = file- , dhall = file- , ipkg = file- , makefile = file- , justfile = file- , ion = file- , bash = file- , hamlet = file- , cassius = file- , lucius = file- , julius = file- , mercury = file- , yacc = file- , lex = file- , coq = file- , jupyter = file- , java = file- , scala = file- , erlang = file- , elixir = file- , pony = file- , clojure = file- , cabal_project = file- , assembly = file- , nix = file- , php = file- , javascript = file- , kotlin = file- , fsharp = file- , fortran = file- , swift = file- , csharp = file- , nim = file- , cpp_header = file- , elisp = file- , plaintext = file- , rakefile = file- , llvm = file- , autoconf = file- , batch = file- , powershell = file- , m4 = file- , objective_c = file- , automake = file- }--// Reference to source_contents; used to update the structure.-vtypedef source_contents_r = ref(source_contents)--// Sum type representing all supported data types.-datavtype pl_type =- | unknown- | rust of int- | haskell of int- | perl of int- | verilog of int- | vhdl of int- | agda of int- | futhark of int- | ats of int- | idris of int- | python of int- | elm of int- | purescript of int- | vimscript of int- | ocaml of int- | madlang of int- | tex of int- | markdown of int- | yaml of int- | toml of int- | cabal of int- | happy of int- | alex of int- | go of int- | html of int- | css of int- | c of int- | brainfuck of int- | ruby of int- | julia of int- | cobol of int- | tcl of int- | r of int- | lua of int- | cpp of int- | lalrpop of int- | header of int- | sixten of int- | dhall of int- | ipkg of int- | makefile of int- | justfile of int- | ion of int- | bash of int- | hamlet of int- | cassius of int- | lucius of int- | julius of int- | mercury of int- | yacc of int- | lex of int- | coq of int- | jupyter of int- | java of int- | scala of int- | erlang of int- | elixir of int- | pony of int- | clojure of int- | cabal_project of int- | assembly of int- | nix of int- | php of int- | javascript of int- | kotlin of int- | fsharp of int- | fortran of int- | swift of int- | csharp of int- | nim of int- | cpp_header of int- | elisp of int- | rakefile of int- | plaintext of int- | llvm of int- | autoconf of int- | batch of int- | powershell of int- | m4 of int- | objective_c of int- | automake of int
− test/data/filetype.sats
@@ -1,180 +0,0 @@-// Type for a collection of files (monoidal)-typedef file = @{ lines = int, files = int }--// Type for the parsed command-line arguments. -typedef command_line = @{ version = bool-, help = bool-, table = bool-, excludes = [ m : nat ] list(string, m)-, includes = [ m : nat ] list(string, m)-}--// Program state, tracking *all* supported file types in an unboxed structure.-typedef source_contents = @{ rust = file-, haskell = file-, ats = file-, python = file-, vimscript = file-, elm = file-, idris = file-, madlang = file-, tex = file-, markdown = file-, yaml = file-, toml = file-, cabal = file-, happy = file-, alex = file-, go = file-, html = file-, css = file-, verilog = file-, vhdl = file-, c = file-, purescript = file-, futhark = file-, brainfuck = file-, ruby = file-, julia = file-, perl = file-, ocaml = file-, agda = file-, cobol = file-, tcl = file-, r = file-, lua = file-, cpp = file-, lalrpop = file-, header = file-, sixten = file-, dhall = file-, ipkg = file-, makefile = file-, justfile = file-, ion = file-, bash = file-, hamlet = file-, cassius = file-, lucius = file-, julius = file-, mercury = file-, yacc = file-, lex = file-, coq = file-, jupyter = file-, java = file-, scala = file-, erlang = file-, elixir = file-, pony = file-, clojure = file-, cabal_project = file-, assembly = file-, nix = file-, php = file-, javascript = file-, kotlin = file-, fsharp = file-, fortran = file-, swift = file-, csharp = file-, nim = file-, cpp_header = file-, elisp = file-, plaintext = file-, rakefile = file-, llvm = file-, autoconf = file-, batch = file-, powershell = file-, m4 = file-, objective_c = file-, automake = file-}--// Reference to source_contents; used to update the structure.-vtypedef source_contents_r = ref(source_contents)--// Sum type representing all supported data types.-datavtype pl_type =-| unknown-| rust of int-| haskell of int-| perl of int-| verilog of int-| vhdl of int-| agda of int-| futhark of int-| ats of int-| idris of int-| python of int-| elm of int-| purescript of int-| vimscript of int-| ocaml of int-| madlang of int-| tex of int-| markdown of int-| yaml of int-| toml of int-| cabal of int-| happy of int-| alex of int-| go of int-| html of int-| css of int-| c of int-| brainfuck of int-| ruby of int-| julia of int-| cobol of int-| tcl of int-| r of int-| lua of int-| cpp of int-| lalrpop of int-| header of int-| sixten of int-| dhall of int-| ipkg of int-| makefile of int-| justfile of int-| ion of int-| bash of int-| hamlet of int-| cassius of int-| lucius of int-| julius of int-| mercury of int-| yacc of int-| lex of int-| coq of int-| jupyter of int-| java of int-| scala of int-| erlang of int-| elixir of int-| pony of int-| clojure of int-| cabal_project of int-| assembly of int-| nix of int-| php of int-| javascript of int-| kotlin of int-| fsharp of int-| fortran of int-| swift of int-| csharp of int-| nim of int-| cpp_header of int-| elisp of int-| rakefile of int-| plaintext of int-| llvm of int-| autoconf of int-| batch of int-| powershell of int-| m4 of int-| objective_c of int-| automake of int
− test/data/left-pad.dats
@@ -1,98 +0,0 @@-#include "share/atspre_staload.hats"--dataprop PAD(int,int,int) =- | {p,l:nat} Yep(p,l,p-l)- | {p,l:nat} Nope(p,l,0)--extern fun left_pad- {p,l:nat | p>0 && l>0}- (- pad: ssize_t p,- c: charNZ,- s: strnptr l- ): [cushion:nat] (PAD(p,l,cushion) | strnptr (cushion+l))--extern fun {t:t@ype} fill_list- {n:nat}- (- size:ssize_t n,- c: t- ): list_vt(t,n)--implement {t}fill_list{n}(size,c) =- let- fun loop- {i:nat | i <= n}- .<i>.- (- size : ssize_t i,- c: t,- res: list_vt(t, n-i)- ): list_vt(t,n) =- if (size = i2ssz(0))- then res- else loop(pred size, c, list_vt_cons(c,res))- in- loop(size,c,list_vt_nil())- end--implement left_pad{p,l}(pad,c,s) =- let- val size = strnptr_length(s)- in- if (pad > size)- then- let- val padding = pad-size- val char_list = fill_list(padding,c)- val pad_string = string_make_list_vt(char_list)- val res = strnptr_append(pad_string, s)- in- begin- strnptr_free(pad_string);- strnptr_free(s);- (Yep{p,l} | res)- end- end- else- (Nope{p,l} | s)- end--implement main0(argc, argv) =- let- val args = listize_argc_argv(argc,argv)- val _ =- if list_vt_length(args) = 3- then (- let- val c = '0'- val s = g1ofg0(args[1]) : [n:nat] string n- val pad = g1ofg0(g0string2int(args[2]))- in- if length(s) > 0 && pad > 0- then (- let- prval _ = lemma_not_empty(s) where {- extern praxi- lemma_not_empty{n:int}(x:string(n)):[n > 0] void- }- prval _ = lemma_not_zero(pad) where {- extern praxi- lemma_not_zero{n:int}(x:int(n)):[n > 0] void- }- val (pf | res) = left_pad(i2ssz(pad),c, string1_copy(s))- in- begin- println! ("padding: ", res);- strnptr_free(res);- end- end- )- else- print "Usage: left-pad <string-to-pad> <pad-length>\n"- end- )- else print "Usage: left-pad <string-to-pad> <pad-length>\n"- in- list_vt_free(args)- end
− test/data/left-pad.out
@@ -1,76 +0,0 @@-#include "share/atspre_staload.hats"--dataprop PAD(int, int, int) =- | { p, l : nat } Yep(p, l, p - l)- | { p, l : nat } Nope(p, l, 0)--extern-fun left_pad { p, l : nat | p > 0 && l > 0 } ( pad : ssize_t(p)- , c : charNZ- , s : strnptr(l)- ) : [cushion:nat] (PAD(p, l, cushion) | strnptr(cushion+l))--extern-fun {t:t@ype} fill_list {n:nat} (size : ssize_t(n), c : t) :- list_vt(t, n)--implement {t} fill_list {n} (size, c) =- let- fun loop { i : nat | i <= n } .<i>. ( size : ssize_t(i)- , c : t- , res : list_vt(t, n-i)- ) : list_vt(t, n) =- if (size = i2ssz(0)) then- res- else- loop(pred(size), c, list_vt_cons(c, res))- in- loop(size, c, list_vt_nil())- end--implement left_pad { p, l } (pad, c, s) =- let- val size = strnptr_length(s)- in- if (pad > size) then- let- val padding = pad - size- val char_list = fill_list(padding, c)- val pad_string = string_make_list_vt(char_list)- val res = strnptr_append(pad_string, s)- in- (strnptr_free(pad_string) ; strnptr_free(s) ; (Yep{p,l} | res))- end- else- (Nope{p,l} | s)- end--implement main0 (argc, argv) =- let- val args = listize_argc_argv(argc, argv)- val _ = if list_vt_length(args) = 3 then- (let- val c = '0'- val s = g1ofg0(args[1]) : [n:nat] string(n)- val pad = g1ofg0(g0string2int(args[2]))- in- if length(s) > 0 && pad > 0 then- (let- prval _ = lemma_not_empty(s) where- { extern- praxi lemma_not_empty {n:int} (x : string(n)) : [ n > 0 ] void }- prval _ = lemma_not_zero(pad) where- { extern- praxi lemma_not_zero {n:int} (x : int(n)) : [ n > 0 ] void }- val (pf | res) = left_pad(i2ssz(pad), c, string1_copy(s))- in- (println!("padding: ", res) ; strnptr_free(res))- end)- else- print("Usage: left-pad <string-to-pad> <pad-length>\n")- end)- else- print("Usage: left-pad <string-to-pad> <pad-length>\n")- in- list_vt_free(args)- end
− test/data/number-theory.dats
@@ -1,167 +0,0 @@-#include "share/atspre_staload.hats"-#include "ats-src/numerics.dats"-#include "contrib/atscntrb-hx-intinf/mylibies.hats"--staload UN = "prelude/SATS/unsafe.sats"-staload "contrib/atscntrb-hx-intinf/SATS/intinf_vt.sats"--#define ATS_MAINATSFLAG 1--// Existential types for even and odd numbers. These are only usable with the-// ATS library.-typedef Even = [ n : nat ] int(2 * n)--typedef Odd = [ n : nat ] int(2 * n+1)--// TODO jacobi symbol-// fn legendre(a: int, p: int) : int =-// a ^ (p - 1 / 2) % p-// m | n-fn divides(m : int, n : int) :<> bool =- n % m = 0--fnx gcd {k : nat}{l : nat} (m : int(l), n : int(k)) : int =- if n > 0 then- gcd(n, witness(m % n))- else- m--fn lcm {k : nat}{l : nat} (m : int(l), n : int(k)) : int =- (m / gcd(m, n)) * n--// stream all divisors of an integer.-fn divisors(n : intGte(1)) :<> stream_vt(int) =- let- fun loop {k : nat}{ m : nat | m > 0 && k >= m } .<k-m>. (n : int(k), acc : int(m)) :<> stream_vt(int) =- if acc >= n then- $ldelay(stream_vt_cons(acc, $ldelay(stream_vt_nil)))- else- if n % acc = 0 then- $ldelay(stream_vt_cons(n, loop(n, acc + 1)))- else- $ldelay(stream_vt_nil)- in- loop(n, 1)- end--// stream all prime divisors of an integer (without multiplicity)-fn prime_divisors(n : intGte(1)) :<> stream_vt(int) =- let- fun loop {k : nat}{ m : nat | m > 0 && k >= m } .<k-m>. (n : int(k), acc : int(m)) :<> stream_vt(int) =- if acc >= n then- $ldelay(stream_vt_cons(acc, $ldelay(stream_vt_nil)))- else- if n % acc = 0 && is_prime(n) then- $ldelay(stream_vt_cons(n, loop(n, acc + 1)))- else- $ldelay(stream_vt_nil)- in- loop(n, 1)- end--fn witness(n : int) : intGte(0) =- $UN.cast(n)--propdef PRIME (p : int) = { x, y : nat | x <= y } MUL(x, y, p) -<> [ x == 1 ] void--dataprop FACT(int, int) =- | FACTbas(0, 1)- | {n : nat}{ r, r1 : int } FACTind(n + 1, r) of (FACT(n, r1), MUL(n + 1, r1, r))--fun get_multiplicity { p : nat | p > 1 } (n : intGte(0), p : int(p)) : int =- case+ n % p of- | 0 => 1 + get_multiplicity(witness(n / p), p)- | _ => 0--fn count_divisors(n : intGte(1)) :<> int =- let- fun loop {k : nat}{ m : nat | m > 0 && k >= m } .<k-m>. (n : int(k), acc : int(m)) :<> int =- if acc >= n then- 1- else- if n % acc = 0 then- 1 + loop(n, acc + 1)- else- loop(n, acc + 1)- in- loop(n, 1)- end--fn sum_divisors(n : intGte(1)) :<> int =- let- fun loop {k : nat}{ m : nat | m > 0 && k >= m } .<k-m>. (n : int(k), acc : int(m)) :<> int =- if acc >= n then- 0- else- if n % acc = 0 then- acc + loop(n, acc + 1)- else- loop(n, acc + 1)- in- loop(n, 1)- end--fn is_perfect(n : intGte(1)) :<> bool =- sum_divisors(n) = n--// distinct prime divisors-fn little_omega(n : intGte(1)) :<> int =- let- fun loop {k : nat}{ m : nat | m > 0 && k >= m } .<k-m>. (n : int(k), acc : int(m)) :<> int =- if acc >= n then- if is_prime(n) then- 1- else- 0- else- if n % acc = 0 && is_prime(acc) then- 1 + loop(n, acc + 1)- else- loop(n, acc + 1)- in- loop(n, 1)- end--// Euler's totient function.-fn totient(n : intGte(1)) : int =- case+ n of- | 1 => 1- | n =>> - begin- let- fnx loop { k : nat | k >= 2 }{ m : nat | m > 0 && k >= m } .<k-m>. (i : int(m), n : int(k)) : int =- if i >= n then- if is_prime(n) then- n - 1- else- n- else- if n % i = 0 && is_prime(i) && i != n then- (loop(i + 1, n) / i) * (i - 1)- else- loop(i + 1, n)- in- loop(1, n)- end- end--// TODO modular exponentiation-// The sum of all φ(m) for m between 1 and n -fun totient_sum(n : intGte(1)) : Intinf =- let- fnx loop { n : nat | n >= 1 }{ m : nat | m >= n } .<m-n>. (i : int(n), bound : int(m)) : Intinf =- if i < bound then- let- val x = loop(i + 1, bound)- val y = add_intinf0_int(x, witness(totient(i)))- in- y- end- else- int2intinf(witness(totient(i)))- in- loop(1, n)- end--extern-fun chinese_remainder {n : nat} (residues : list_vt(int, n), moduli : list_vt(int, n)) : Option_vt(int)
− test/data/number-theory.out
@@ -1,186 +0,0 @@-#include "share/atspre_staload.hats"-#include "ats-src/numerics.dats"-#include "contrib/atscntrb-hx-intinf/mylibies.hats"--staload UN = "prelude/SATS/unsafe.sats"-staload "contrib/atscntrb-hx-intinf/SATS/intinf_vt.sats"--#define ATS_MAINATSFLAG 1--// Existential types for even and odd numbers. These are only usable with the-// ATS library.-typedef Even = [n:nat] int(2*n)-typedef Odd = [n:nat] int(2*n+1)--// TODO jacobi symbol-// fn legendre(a: int, p: int) : int =-// a ^ (p - 1 / 2) % p-// m | n-fn divides(m : int, n : int) :<> bool =- n % m = 0--fnx gcd {k:nat}{l:nat} (m : int(l), n : int(k)) : int =- if n > 0 then- gcd(n, witness(m % n))- else- m--fn lcm {k:nat}{l:nat} (m : int(l), n : int(k)) : int =- (m / gcd(m, n)) * n--// stream all divisors of an integer.-fn divisors(n : intGte(1)) :<> stream_vt(int) =- let- fun loop {k:nat}{ m : nat | m > 0 && k >= m } .<k-m>. ( n : int(k)- , acc : int(m)- ) :<> stream_vt(int) =- if acc >= n then- $ldelay(stream_vt_cons(acc, $ldelay(stream_vt_nil)))- else- if n % acc = 0 then- $ldelay(stream_vt_cons(n, loop(n, acc + 1)))- else- $ldelay(stream_vt_nil)- in- loop(n, 1)- end--// stream all prime divisors of an integer (without multiplicity)-fn prime_divisors(n : intGte(1)) :<> stream_vt(int) =- let- fun loop {k:nat}{ m : nat | m > 0 && k >= m } .<k-m>. ( n : int(k)- , acc : int(m)- ) :<> stream_vt(int) =- if acc >= n then- $ldelay(stream_vt_cons(acc, $ldelay(stream_vt_nil)))- else- if n % acc = 0 && is_prime(n) then- $ldelay(stream_vt_cons(n, loop(n, acc + 1)))- else- $ldelay(stream_vt_nil)- in- loop(n, 1)- end--fn witness(n : int) : intGte(0) =- $UN.cast(n)--propdef PRIME (p : int) =-{ x, y : nat | x <= y } MUL(x, y, p) -<> [ x == 1 ] void--dataprop FACT(int, int) =- | FACTbas(0, 1)- | { r, r1 : int }{n:nat} FACTind(n + 1, r) of (FACT(n, r1), MUL( n + 1- , r1- , r- ))--fun get_multiplicity { p : nat | p > 1 } (n : intGte(0), p : int(p)) :- int =- case+ n % p of- | 0 => 1 + get_multiplicity(witness(n / p), p)- | _ => 0--fn count_divisors(n : intGte(1)) :<> int =- let- fun loop {k:nat}{ m : nat | m > 0 && k >= m } .<k-m>. ( n : int(k)- , acc : int(m)- ) :<> int =- if acc >= n then- 1- else- if n % acc = 0 then- 1 + loop(n, acc + 1)- else- loop(n, acc + 1)- in- loop(n, 1)- end--fn sum_divisors(n : intGte(1)) :<> int =- let- fun loop {k:nat}{ m : nat | m > 0 && k >= m } .<k-m>. ( n : int(k)- , acc : int(m)- ) :<> int =- if acc >= n then- 0- else- if n % acc = 0 then- acc + loop(n, acc + 1)- else- loop(n, acc + 1)- in- loop(n, 1)- end--fn is_perfect(n : intGte(1)) :<> bool =- sum_divisors(n) = n--// distinct prime divisors-fn little_omega(n : intGte(1)) :<> int =- let- fun loop {k:nat}{ m : nat | m > 0 && k >= m } .<k-m>. ( n : int(k)- , acc : int(m)- ) :<> int =- if acc >= n then- if is_prime(n) then- 1- else- 0- else- if n % acc = 0 && is_prime(acc) then- 1 + loop(n, acc + 1)- else- loop(n, acc + 1)- in- loop(n, 1)- end--// Euler's totient function.-fn totient(n : intGte(1)) : int =- case+ n of- | 1 => 1- | n =>> - begin- let- fnx loop { k : nat | k >= 2 }{ m : nat | m > 0 && k >= m } .<k-m>.- (i : int(m), n : int(k)) : int =- if i >= n then- if is_prime(n) then- n - 1- else- n- else- if n % i = 0 && is_prime(i) && i != n then- (loop(i + 1, n) / i) * (i - 1)- else- loop(i + 1, n)- in- loop(1, n)- end- end--// TODO modular exponentiation-// The sum of all φ(m) for m between 1 and n -fun totient_sum(n : intGte(1)) : Intinf =- let- fnx loop { n : nat | n >= 1 }{ m : nat | m >= n } .<m-n>. ( i : int(n)- , bound : int(m)- ) : Intinf =- if i < bound then- let- val x = loop(i + 1, bound)- val y = add_intinf0_int(x, witness(totient(i)))- in- y- end- else- int2intinf(witness(totient(i)))- in- loop(1, n)- end--extern-fun chinese_remainder {n:nat} ( residues : list_vt(int, n)- , moduli : list_vt(int, n)- ) : Option_vt(int)
− test/data/numerics.dats
@@ -1,61 +0,0 @@-#define ATS_MAINATSFLAG 1--#include "share/atspre_staload.hats"--staload "libats/libc/SATS/math.sats"-staload UN = "prelude/SATS/unsafe.sats"--fun exp {n : nat} .<n>. (x : int, n : int(n)) :<> int =- case+ x of- | 0 => 0- | x => - begin- if n > 0 then- let- val n2 = half(n)- val i2 = n % 2- in- if i2 = 0 then- exp(x * x, n2)- else- x * exp(x * x, n2)- end- else- 1- end--castfn lemma_bounded(i: int) : [n:nat] int(n)- = $UN.cast(i)--fun sqrt_bad(k : intGt(0)) : [ m : nat ] int(m) =- let- var pre_bound: int = g0float2int(sqrt_float(g0int2float_int_float(k)))- var bound: [m:nat] int(m) = lemma_bounded(pre_bound)- in- bound- end--fn is_prime(k : intGt(0)) : bool =- case+ k of- | 1 => false- | k => - begin- let- fun loop {n : nat}{m : nat} .<max(0,m-n)>. (i : int(n), bound : int(m)) :<> bool =- if i < bound then- if k % i = 0 then- false- else- loop(i + 1, bound)- else- if i = bound then- if k % i = 0 then- false- else- true- else- true- in- loop(2, sqrt_bad(k))- end- end
− test/data/numerics.out
@@ -1,63 +0,0 @@-#define ATS_MAINATSFLAG 1--#include "share/atspre_staload.hats"--staload "libats/libc/SATS/math.sats"-staload UN = "prelude/SATS/unsafe.sats"--fun exp {n:nat} .<n>. (x : int, n : int(n)) :<> int =- case+ x of- | 0 => 0- | x => - begin- if n > 0 then- let- val n2 = half(n)- val i2 = n % 2- in- if i2 = 0 then- exp(x * x, n2)- else- x * exp(x * x, n2)- end- else- 1- end--castfn lemma_bounded(i : int) : [n:nat] int(n) =- $UN.cast(i)--fun sqrt_bad(k : intGt(0)) : [m:nat] int(m) =- let- var pre_bound: int = g0float2int(sqrt_float(g0int2float_int_float(k)))- var bound: [m:nat] int(m) = lemma_bounded(pre_bound)- in- bound- end--fn is_prime(k : intGt(0)) : bool =- case+ k of- | 1 => false- | k => - begin- let- fun loop {n:nat}{m:nat} .<max(0,m-n)>. ( i : int(n)- , bound : int(m)- ) :<> bool =- if i < bound then- if k % i = 0 then- false- else- loop(i + 1, bound)- else- if i = bound then- if k % i = 0 then- false- else- true- else- true- in- loop(2, sqrt_bad(k))- end- end
− test/data/polyglot.dats
@@ -1,1235 +0,0 @@-#include "share/atspre_staload.hats"-#include "share/HATS/atslib_staload_libats_libc.hats"-#include "prelude/DATS/filebas.dats"-#include "libats/ML/DATS/filebas_dirent.dats"-#include "libats/libc/DATS/dirent.dats"-#include "src/concurrency.dats"-#include "libats/DATS/athread_posix.dats"-#include "prelude/DATS/stream_vt.dats"--%{^-#include "libats/libc/CATS/string.cats"-#include "prelude/CATS/filebas.cats"-%}--staload "prelude/SATS/stream_vt.sats"-staload "libats/ML/DATS/list0.dats"-staload "libats/SATS/athread.sats"-staload "libats/ML/DATS/string.dats"-staload "libats/libc/SATS/stdio.sats"-staload "prelude/SATS/filebas.sats"-staload "src/filetype.sats"-staload "libats/ML/DATS/filebas.dats"-staload EXTRA = "libats/ML/SATS/filebas.sats"-staload "libats/libc/SATS/unistd.sats"-staload "libats/DATS/athread.dats"--fun to_file(s : string, pre : Option(string)) : file =- let- val is_comment = case+ pre of- | Some (x) => string_is_prefix(x, s)- | None => false- in- if s = "" then- @{ lines = 1, blanks = 1, comments = 0, files = 0 }- else- if is_comment then- @{ lines = 1, blanks = 0, comments = 1, files = 0 }- else- @{ lines = 1, blanks = 0, comments = 0, files = 0 }- end--fun empty_file() : file =- let- var f = @{ files = 0, blanks = 0, comments = 0, lines = 0 } : file- in- f- end--fun acc_file() : file =- let- var f = @{ files = 1, blanks = 0, comments = 0, lines = ~1 } : file- in- f- end--// monoidal addition for 'file' type-fun add_results(x : file, y : file) : file =- let- var next = @{ lines = x.lines + y.lines, blanks = x.blanks + y.blanks, comments = x.comments- + y.comments, files = x.files + y.files }- in- next- end--overload + with add_results--// Given a string representing a filepath, return an integer.-fun line_count(s : string, pre : Option(string)) : file =- let- var ref = fileref_open_opt(s, file_mode_r)- in- case ref of- | ~Some_vt (x) => - begin- let- var viewstream: stream_vt(string) = $EXTRA.streamize_fileref_line(x)- val n: file = stream_vt_foldleft_cloptr( viewstream- , acc_file()- , lam (acc, f) =<cloptr1> acc + to_file(f, pre)- )- val _ = fileref_close(x)- in- n- end- end- | ~None_vt() => (println!("\33[33mWarning:\33[0m could not open file at " + s) ; to_file( s- , None- ))- end--// Pad a string of bounded length on the right by adding spaces.-fnx right_pad { k : int | k >= 0 }{ m : int | m <= k } .<k>. (s : string(m), n : int(k)) :-string =- case+ length(s) < n of- | true when n > 0 => right_pad(s, n - 1) + " "- | _ => s--// Pad a string on the left by adding spaces.-fnx left_pad { k : int | k >= 0 } .<k>. (s : string, n : int(k)) : string =- case+ length(s) < n of- | true when n > 0 => " " + left_pad(s, n - 1)- | _ => s--// helper function for make_output-fun maybe_string(s : string, n : int) : string =- if n > 0 then- s + ": " + tostring_int(n) + "\n"- else- ""--// helper function for make_table-fun maybe_table { k : int | k >= 0 && k < 20 } (s : string(k), f : file) : string =- let- var code = f.lines - f.comments - f.blanks- in- if f.files > 0 then- " " + right_pad(s, 21) + left_pad(tostring_int(f.files), 5) + left_pad(tostring_int(f.lines- ), 12)- + left_pad(tostring_int(code), 13) + left_pad(tostring_int(f.comments), 13)- + left_pad(tostring_int(f.blanks), 13) + "\n"- else- ""- end--// helper function for make_output-fun with_nonempty(s1 : string, s2 : string) : string =- if s2 != "" then- s1 + s2- else- ""--// helper function to make totals for tabular output.-fun sum_fields(sc : source_contents) : file =- let- var f = @{ lines = sc.rust.lines + sc.haskell.lines + sc.ats.lines + sc.python.lines- + sc.vimscript.lines + sc.elm.lines + sc.idris.lines + sc.madlang.lines + sc.tex.lines- + sc.markdown.lines + sc.yaml.lines + sc.toml.lines + sc.cabal.lines + sc.happy.lines- + sc.alex.lines + sc.go.lines + sc.html.lines + sc.css.lines + sc.verilog.lines + sc.vhdl.lines- + sc.c.lines + sc.purescript.lines + sc.futhark.lines + sc.brainfuck.lines + sc.ruby.lines- + sc.julia.lines + sc.perl.lines + sc.ocaml.lines + sc.agda.lines + sc.cobol.lines- + sc.tcl.lines + sc.r.lines + sc.lua.lines + sc.cpp.lines + sc.lalrpop.lines + sc.header.lines- + sc.sixten.lines + sc.dhall.lines + sc.ipkg.lines + sc.makefile.lines + sc.justfile.lines- + sc.ion.lines + sc.bash.lines + sc.hamlet.lines + sc.cassius.lines + sc.lucius.lines- + sc.julius.lines + sc.mercury.lines + sc.yacc.lines + sc.lex.lines + sc.coq.lines- + sc.jupyter.lines + sc.java.lines + sc.scala.lines + sc.erlang.lines + sc.elixir.lines- + sc.pony.lines + sc.clojure.lines + sc.cabal_project.lines + sc.assembly.lines + sc.nix.lines- + sc.php.lines + sc.javascript.lines + sc.kotlin.lines + sc.fsharp.lines + sc.fortran.lines- + sc.swift.lines + sc.csharp.lines + sc.nim.lines + sc.cpp_header.lines + sc.elisp.lines- + sc.plaintext.lines + sc.rakefile.lines + sc.llvm.lines + sc.autoconf.lines + sc.batch.lines- + sc.powershell.lines + sc.m4.lines + sc.objective_c.lines- + sc.automake.lines, blanks = sc.rust.blanks + sc.haskell.blanks + sc.ats.blanks- + sc.python.blanks + sc.vimscript.blanks + sc.elm.blanks + sc.idris.blanks + sc.madlang.blanks- + sc.tex.blanks + sc.markdown.blanks + sc.yaml.blanks + sc.toml.blanks + sc.cabal.blanks- + sc.happy.blanks + sc.alex.blanks + sc.go.blanks + sc.html.blanks + sc.css.blanks- + sc.verilog.blanks + sc.vhdl.blanks + sc.c.blanks + sc.purescript.blanks + sc.futhark.blanks- + sc.brainfuck.blanks + sc.ruby.blanks + sc.julia.blanks + sc.perl.blanks + sc.ocaml.blanks- + sc.agda.blanks + sc.cobol.blanks + sc.tcl.blanks + sc.r.blanks + sc.lua.blanks + sc.cpp.blanks- + sc.lalrpop.blanks + sc.header.blanks + sc.sixten.blanks + sc.dhall.blanks + sc.ipkg.blanks- + sc.makefile.blanks + sc.justfile.blanks + sc.ion.blanks + sc.bash.blanks + sc.hamlet.blanks- + sc.cassius.blanks + sc.lucius.blanks + sc.julius.blanks + sc.mercury.blanks + sc.yacc.blanks- + sc.lex.blanks + sc.coq.blanks + sc.jupyter.blanks + sc.java.blanks + sc.scala.blanks- + sc.erlang.blanks + sc.elixir.blanks + sc.pony.blanks + sc.clojure.blanks- + sc.cabal_project.blanks + sc.assembly.blanks + sc.nix.blanks + sc.php.blanks- + sc.javascript.blanks + sc.kotlin.blanks + sc.fsharp.blanks + sc.fortran.blanks- + sc.swift.blanks + sc.csharp.blanks + sc.nim.blanks + sc.cpp_header.blanks + sc.elisp.blanks- + sc.plaintext.blanks + sc.rakefile.blanks + sc.llvm.blanks + sc.autoconf.blanks- + sc.batch.blanks + sc.powershell.blanks + sc.m4.blanks + sc.objective_c.blanks- + sc.automake.blanks, comments = sc.rust.comments + sc.haskell.comments + sc.ats.comments- + sc.python.comments + sc.vimscript.comments + sc.elm.comments + sc.idris.comments- + sc.madlang.comments + sc.tex.comments + sc.markdown.comments + sc.yaml.comments- + sc.toml.comments + sc.cabal.comments + sc.happy.comments + sc.alex.comments + sc.go.comments- + sc.html.comments + sc.css.comments + sc.verilog.comments + sc.vhdl.comments + sc.c.comments- + sc.purescript.comments + sc.futhark.comments + sc.brainfuck.comments + sc.ruby.comments- + sc.julia.comments + sc.perl.comments + sc.ocaml.comments + sc.agda.comments- + sc.cobol.comments + sc.tcl.comments + sc.r.comments + sc.lua.comments + sc.cpp.comments- + sc.lalrpop.comments + sc.header.comments + sc.sixten.comments + sc.dhall.comments- + sc.ipkg.comments + sc.makefile.comments + sc.justfile.comments + sc.ion.comments- + sc.bash.comments + sc.hamlet.comments + sc.cassius.comments + sc.lucius.comments- + sc.julius.comments + sc.mercury.comments + sc.yacc.comments + sc.lex.comments- + sc.coq.comments + sc.jupyter.comments + sc.java.comments + sc.scala.comments- + sc.erlang.comments + sc.elixir.comments + sc.pony.comments + sc.clojure.comments- + sc.cabal_project.comments + sc.assembly.comments + sc.nix.comments + sc.php.comments- + sc.javascript.comments + sc.kotlin.comments + sc.fsharp.comments + sc.fortran.comments- + sc.swift.comments + sc.csharp.comments + sc.nim.comments + sc.cpp_header.comments- + sc.elisp.comments + sc.plaintext.comments + sc.rakefile.comments + sc.llvm.comments- + sc.autoconf.comments + sc.batch.comments + sc.powershell.comments + sc.m4.comments- + sc.objective_c.comments + sc.automake.comments, files = sc.rust.files + sc.haskell.files- + sc.ats.files + sc.python.files + sc.vimscript.files + sc.elm.files + sc.idris.files- + sc.madlang.files + sc.tex.files + sc.markdown.files + sc.yaml.files + sc.toml.files- + sc.cabal.files + sc.happy.files + sc.alex.files + sc.go.files + sc.html.files + sc.css.files- + sc.verilog.files + sc.vhdl.files + sc.c.files + sc.purescript.files + sc.futhark.files- + sc.brainfuck.files + sc.ruby.files + sc.julia.files + sc.perl.files + sc.ocaml.files- + sc.agda.files + sc.cobol.files + sc.tcl.files + sc.r.files + sc.lua.files + sc.cpp.files- + sc.lalrpop.files + sc.header.files + sc.sixten.files + sc.dhall.files + sc.ipkg.files- + sc.makefile.files + sc.justfile.files + sc.ion.files + sc.bash.files + sc.hamlet.files- + sc.cassius.files + sc.lucius.files + sc.julius.files + sc.mercury.files + sc.yacc.files- + sc.lex.files + sc.coq.files + sc.jupyter.files + sc.java.files + sc.scala.files- + sc.erlang.files + sc.elixir.files + sc.pony.files + sc.clojure.files + sc.cabal_project.files- + sc.assembly.files + sc.nix.files + sc.php.files + sc.javascript.files + sc.kotlin.files- + sc.fsharp.files + sc.fortran.files + sc.swift.files + sc.csharp.files + sc.nim.files- + sc.cpp_header.files + sc.elisp.files + sc.plaintext.files + sc.rakefile.files + sc.llvm.files- + sc.autoconf.files + sc.batch.files + sc.powershell.files + sc.m4.files + sc.objective_c.files- + sc.automake.files }- in- f- end--// function to print tabular output at the end-fun make_table(isc : source_contents) : string =- "-------------------------------------------------------------------------------\n \33[35mLanguage\33[0m \33[35mFiles\33[0m \33[35mLines\33[0m \33[35mCode\33[0m \33[35mComments\33[0m \33[35mBlanks\33[0m\n-------------------------------------------------------------------------------\n"- + maybe_table("Alex", isc.alex) + maybe_table("Agda", isc.agda) + maybe_table( "Assembly"- , isc.assembly- ) + maybe_table("ATS", isc.ats)- + maybe_table("Autoconf", isc.autoconf) + maybe_table("Automake", isc.automake)- + maybe_table("Bash", isc.bash) + maybe_table("Batch", isc.batch) + maybe_table( "Brainfuck"- , isc.brainfuck- ) + maybe_table("C", isc.c)- + maybe_table("C Header", isc.header) + maybe_table("C++ cpp_header", isc.cpp_header)- + maybe_table("C++", isc.cpp) + maybe_table("C#", isc.csharp) + maybe_table("Cabal", isc.cabal)- + maybe_table("Cabal Project", isc.cabal_project) + maybe_table("Cassius", isc.cassius)- + maybe_table("COBOL", isc.cobol) + maybe_table("Coq", isc.coq) + maybe_table("CSS", isc.css)- + maybe_table("Dhall", isc.dhall) + maybe_table("Elixir", isc.elixir) + maybe_table( "Elm"- , isc.elm- ) + maybe_table( "Emacs Lisp"- , isc.elisp- )- + maybe_table("Erlang", isc.erlang) + maybe_table("F#", isc.fsharp) + maybe_table( "Fortran"- , isc.fortran- ) + maybe_table("Go", isc.go)- + maybe_table("Hamlet", isc.hamlet) + maybe_table("Happy", isc.happy) + maybe_table( "Haskell"- , isc.haskell- ) + maybe_table("HTML", isc.html)- + maybe_table("Idris", isc.idris) + maybe_table("iPKG", isc.ipkg) + maybe_table("Ion", isc.ion)- + maybe_table("Java", isc.java) + maybe_table("JavaScript", isc.javascript)- + maybe_table("Julius", isc.julius) + maybe_table("Julia", isc.julia) + maybe_table( "Jupyter"- , isc.jupyter- ) + maybe_table( "Justfile"- , isc.justfile- )- + maybe_table("Kotlin", isc.kotlin) + maybe_table("LALRPOP", isc.lalrpop) + maybe_table( "Lex"- , isc.lex- ) + maybe_table( "LLVM"- , isc.llvm- )- + maybe_table("Lua", isc.lua) + maybe_table("Lucius", isc.lucius) + maybe_table("M4", isc.m4)- + maybe_table("Madlang", isc.madlang) + maybe_table("Makefile", isc.makefile)- + maybe_table("Margaret", isc.margaret) + maybe_table("Markdown", isc.markdown)- + maybe_table("Mercury", isc.mercury) + maybe_table("Nim", isc.nim) + maybe_table( "Nix"- , isc.nix- ) + maybe_table( "Objective C"- , isc.objective_c- )- + maybe_table("OCaml", isc.ocaml) + maybe_table("Perl", isc.perl) + maybe_table("PHP", isc.php)- + maybe_table("Plaintext", isc.plaintext) + maybe_table("PowerShell", isc.powershell)- + maybe_table("Pony", isc.pony) + maybe_table("Python", isc.python) + maybe_table( "PureScript"- , isc.purescript- ) + maybe_table("R", isc.r)- + maybe_table("Rakefile", isc.rakefile) + maybe_table("Ruby", isc.ruby) + maybe_table( "Rust"- , isc.rust- ) + maybe_table( "Scala"- , isc.scala- )- + maybe_table("Sixten", isc.sixten) + maybe_table("Swift", isc.swift) + maybe_table( "TCL"- , isc.tcl- ) + maybe_table("TeX", isc.tex)- + maybe_table("TOML", isc.toml) + maybe_table("Verilog", isc.verilog) + maybe_table( "VHDL"- , isc.vhdl- ) + maybe_table( "Vimscript"- , isc.vimscript- )- + maybe_table("Yacc", isc.yacc) + maybe_table("YAML", isc.yaml)- + "-------------------------------------------------------------------------------\n"- + maybe_table("Total", sum_fields(isc))- + "-------------------------------------------------------------------------------\n"--// Function to print output sorted by type of language.-fun make_output(isc : source_contents) : string =- with_nonempty( "\33[33mProgramming Languages:\33[0m\n"- , maybe_string("Agda", isc.agda.lines) + maybe_string("Assembly", isc.assembly.lines)- + maybe_string("ATS", isc.ats.lines) + maybe_string("Brainfuck", isc.brainfuck.lines)- + maybe_string("C", isc.c.lines) + maybe_string("C Header", isc.header.lines)- + maybe_string("C++", isc.cpp.lines) + maybe_string("C++ Header", isc.cpp_header.lines)- + maybe_string("C#", isc.csharp.lines) + maybe_string("COBOL", isc.cobol.lines)- + maybe_string("Coq", isc.coq.lines) + maybe_string("Elixir", isc.elixir.lines)- + maybe_string("Elm", isc.elm.lines) + maybe_string("Erlang", isc.erlang.lines)- + maybe_string("F#", isc.fsharp.lines) + maybe_string("Fortran", isc.fortran.lines)- + maybe_string("Go", isc.go.lines) + maybe_string("Haskell", isc.haskell.lines)- + maybe_string("Idris", isc.idris.lines) + maybe_string("Kotline", isc.kotlin.lines)- + maybe_string("Java", isc.java.lines) + maybe_string("Julia", isc.julia.lines)- + maybe_string("Lua", isc.lua.lines) + maybe_string("Margaret", isc.margaret.lines)- + maybe_string("Mercury", isc.mercury.lines) + maybe_string("Nim", isc.nim.lines)- + maybe_string("Objective C", isc.objective_c.lines) + maybe_string("OCaml", isc.ocaml.lines)- + maybe_string("Perl", isc.perl.lines) + maybe_string("Pony", isc.pony.lines)- + maybe_string("PureScript", isc.purescript.lines) + maybe_string("Python", isc.python.lines)- + maybe_string("R", isc.r.lines) + maybe_string("Ruby", isc.ruby.lines) + maybe_string( "Rust"- , isc.rust.lines- )- + maybe_string("Scala", isc.scala.lines) + maybe_string("Sixten", isc.sixten.lines)- + maybe_string("Swift", isc.swift.lines) + maybe_string("TCL", isc.tcl.lines)- ) + with_nonempty( "\n\33[33mEditor Plugins:\33[0m\n"- , maybe_string("Emacs Lisp", isc.elisp.lines) + maybe_string( "Vimscript"- , isc.vimscript.lines- )- ) + with_nonempty( "\n\33[33mDocumentation:\33[0m\n"- , maybe_string("Markdown", isc.markdown.lines)- + maybe_string("Plaintext", isc.plaintext.lines) + maybe_string( "TeX"- , isc.tex.lines- )- ) + with_nonempty( "\n\33[33mConfiguration:\33[0m\n"- , maybe_string("Cabal", isc.cabal.lines)- + maybe_string( "Cabal Project"- , isc.cabal_project.lines- ) + maybe_string( "Dhall"- , isc.dhall.lines- ) + maybe_string( "iPKG"- , isc.ipkg.lines- )- + maybe_string("TOML", isc.toml.lines)- + maybe_string("YAML", isc.yaml.lines)- ) + with_nonempty( "\n\33[33mShell:\33[0m\n"- , maybe_string( "Bash"- , isc.bash.lines- )- + maybe_string( "Batch"- , isc.batch.lines- ) + maybe_string( "Ion"- , isc.ion.lines- )- + maybe_string( "PowerShell"- , isc.powershell.lines- )- )- + with_nonempty( "\n\33[33mParser Generators:\33[0m\n"- , maybe_string("Alex", isc.alex.lines) + maybe_string("Happy", isc.happy.lines)- + maybe_string("LALRPOP", isc.lalrpop.lines) + maybe_string("Lex", isc.lex.lines)- + maybe_string("Yacc", isc.yacc.lines)- ) + with_nonempty( "\n\33[33mWeb:\33[0m\n"- , maybe_string("Cassius", isc.cassius.lines) + maybe_string("CSS", isc.css.lines)- + maybe_string("Hamlet", isc.hamlet.lines) + maybe_string("HTML", isc.html.lines)- + maybe_string("JavaScript", isc.javascript.lines) + maybe_string( "Julius"- , isc.julius.lines- )- + maybe_string("Lucius", isc.lucius.lines)- ) + with_nonempty( "\n\33[33mHardware:\33[0m\n"- , maybe_string("Verilog", isc.verilog.lines) + maybe_string( "VHDL"- , isc.vhdl.lines- )- ) + with_nonempty( "\n\33[33mNotebooks:\33[0m\n"- , maybe_string("Jupyter", isc.jupyter.lines)- ) + with_nonempty( "\n\33[33mOther:\33[0m\n"- , maybe_string( "Autoconf"- , isc.autoconf.lines- )- + maybe_string( "Automake"- , isc.automake.lines- )- + maybe_string( "Justfile"- , isc.justfile.lines- )- + maybe_string( "LLVM"- , isc.llvm.lines- )- + maybe_string("M4", isc.m4.lines)- + maybe_string( "Madlang"- , isc.madlang.lines- )- + maybe_string( "Makefile"- , isc.makefile.lines- )- + maybe_string( "Rakefile"- , isc.rakefile.lines- )- )--fun add_contents(x : source_contents, y : source_contents) : source_contents =- let- var next = @{ rust = x.rust + y.rust, haskell = x.haskell + y.haskell, ats = x.ats- + y.ats, python = x.python + y.python, vimscript = x.vimscript + y.vimscript, elm = x.elm- + y.elm, idris = x.idris + y.idris, madlang = x.madlang + y.madlang, tex = x.tex- + y.tex, markdown = x.markdown + y.markdown, yaml = x.yaml + y.yaml, toml = x.toml- + y.toml, cabal = x.cabal + y.cabal, happy = x.happy + y.happy, alex = x.alex- + y.alex, go = x.go + y.go, html = x.html + y.html, css = x.css + y.css, verilog = x.verilog- + y.verilog, vhdl = x.vhdl + y.vhdl, c = x.c + y.c, purescript = x.purescript- + y.purescript, futhark = x.futhark + y.futhark, brainfuck = x.brainfuck- + y.brainfuck, ruby = x.ruby + y.ruby, julia = x.julia + y.julia, perl = x.perl- + y.perl, ocaml = x.ocaml + y.ocaml, agda = x.agda + y.agda, cobol = x.cobol- + y.cobol, tcl = x.tcl + y.tcl, r = x.r + y.r, lua = x.lua + y.lua, cpp = x.cpp- + y.cpp, lalrpop = x.lalrpop + y.lalrpop, header = x.header + y.header, sixten = x.sixten- + y.sixten, dhall = x.dhall + y.dhall, ipkg = x.ipkg + y.ipkg, makefile = x.makefile- + y.makefile, justfile = x.justfile + y.justfile, ion = x.ion + y.ion, bash = x.bash- + y.bash, hamlet = x.hamlet + y.hamlet, cassius = x.cassius + y.cassius, lucius = x.lucius- + y.lucius, julius = x.julius + y.julius, mercury = x.mercury + y.mercury, yacc = x.yacc- + y.yacc, lex = x.lex + y.lex, coq = x.coq + y.coq, jupyter = x.jupyter- + y.jupyter, java = x.java + y.java, scala = x.scala + y.scala, erlang = x.erlang- + y.erlang, elixir = x.elixir + y.elixir, pony = x.pony + y.pony, clojure = x.clojure- + y.clojure, cabal_project = x.cabal_project + y.cabal_project, assembly = x.assembly- + y.assembly, nix = x.nix + y.nix, php = x.php + y.php, javascript = x.javascript- + y.javascript, kotlin = x.kotlin + y.kotlin, fsharp = x.fsharp + y.fsharp, fortran = x.fortran- + y.fortran, swift = x.swift + y.swift, csharp = x.csharp + y.csharp, nim = x.nim- + y.nim, cpp_header = x.cpp_header + y.cpp_header, elisp = x.elisp- + y.elisp, plaintext = x.plaintext + y.plaintext, rakefile = x.rakefile- + y.rakefile, llvm = x.llvm + y.llvm, autoconf = x.autoconf + y.autoconf, batch = x.batch- + y.batch, powershell = x.powershell + y.powershell, m4 = x.m4- + y.m4, objective_c = x.objective_c + y.objective_c, automake = x.automake- + y.automake, margaret = x.margaret + y.margaret } : source_contents- in- next- end--// This is the step function used when streaming directory contents. -fun adjust_contents(prev : source_contents, scf : pl_type) : source_contents =- let- val sc_r = ref<source_contents>(prev)- val _ = case+ scf of- | ~haskell n => sc_r->haskell := prev.haskell + n- | ~ats n => sc_r->ats := prev.ats + n- | ~rust n => sc_r->rust := prev.rust + n- | ~markdown n => sc_r->markdown := prev.markdown + n- | ~python n => sc_r->python := prev.python + n- | ~vimscript n => sc_r->vimscript := prev.vimscript + n- | ~yaml n => sc_r->yaml := prev.yaml + n- | ~toml n => sc_r->toml := prev.toml + n- | ~happy n => sc_r->happy := prev.happy + n- | ~alex n => sc_r->alex := prev.alex + n- | ~idris n => sc_r->idris := prev.idris + n- | ~madlang n => sc_r->madlang := prev.madlang + n- | ~elm n => sc_r->elm := prev.elm + n- | ~c n => sc_r->c := prev.c + n- | ~go n => sc_r->go := prev.go + n- | ~cabal n => sc_r->cabal := prev.cabal + n- | ~verilog n => sc_r->verilog := prev.verilog + n- | ~vhdl n => sc_r->vhdl := prev.vhdl + n- | ~html n => sc_r->html := prev.html + n- | ~css n => sc_r->css := prev.css + n- | ~purescript n => sc_r->purescript := prev.purescript + n- | ~futhark n => sc_r->futhark := prev.futhark + n- | ~brainfuck n => sc_r->brainfuck := prev.brainfuck + n- | ~ruby n => sc_r->ruby := prev.ruby + n- | ~julia n => sc_r->julia := prev.julia + n- | ~tex n => sc_r->tex := prev.tex + n- | ~perl n => sc_r->perl := prev.perl + n- | ~ocaml n => sc_r->ocaml := prev.ocaml + n- | ~agda n => sc_r->agda := prev.agda + n- | ~cobol n => sc_r->cobol := prev.cobol + n- | ~tcl n => sc_r->tcl := prev.tcl + n- | ~r n => sc_r->r := prev.r + n- | ~lua n => sc_r->lua := prev.lua + n- | ~cpp n => sc_r->cpp := prev.cpp + n- | ~lalrpop n => sc_r->lalrpop := prev.lalrpop + n- | ~header n => sc_r->header := prev.header + n- | ~sixten n => sc_r->sixten := prev.sixten + n- | ~dhall n => sc_r->dhall := prev.dhall + n- | ~ipkg n => sc_r->ipkg := prev.ipkg + n- | ~justfile n => sc_r->justfile := prev.justfile + n- | ~makefile n => sc_r->makefile := prev.makefile + n- | ~ion n => sc_r->ion := prev.ion + n- | ~bash n => sc_r->bash := prev.bash + n- | ~hamlet n => sc_r->hamlet := prev.hamlet + n- | ~cassius n => sc_r->cassius := prev.cassius + n- | ~lucius n => sc_r->lucius := prev.lucius + n- | ~julius n => sc_r->julius := prev.julius + n- | ~mercury n => sc_r->mercury := prev.mercury + n- | ~yacc n => sc_r->yacc := prev.yacc + n- | ~lex n => sc_r->lex := prev.lex + n- | ~coq n => sc_r->coq := prev.coq + n- | ~jupyter n => sc_r->jupyter := prev.jupyter + n- | ~java n => sc_r->java := prev.java + n- | ~scala n => sc_r->scala := prev.scala + n- | ~erlang n => sc_r->erlang := prev.erlang + n- | ~elixir n => sc_r->elixir := prev.elixir + n- | ~pony n => sc_r->pony := prev.pony + n- | ~clojure n => sc_r->clojure := prev.clojure + n- | ~cabal_project n => sc_r->cabal_project := prev.cabal_project + n- | ~assembly n => sc_r->assembly := prev.assembly + n- | ~nix n => sc_r->nix := prev.nix + n- | ~php n => sc_r->php := prev.php + n- | ~javascript n => sc_r->javascript := prev.javascript + n- | ~kotlin n => sc_r->kotlin := prev.kotlin + n- | ~fsharp n => sc_r->fsharp := prev.fsharp + n- | ~fortran n => sc_r->fortran := prev.fortran + n- | ~swift n => sc_r->swift := prev.swift + n- | ~csharp n => sc_r->csharp := prev.csharp + n- | ~nim n => sc_r->nim := prev.nim + n- | ~cpp_header n => sc_r->cpp_header := prev.cpp_header + n- | ~elisp n => sc_r->elisp := prev.elisp + n- | ~plaintext n => sc_r->plaintext := prev.plaintext + n- | ~rakefile n => sc_r->rakefile := prev.rakefile + n- | ~llvm n => sc_r->llvm := prev.llvm + n- | ~autoconf n => sc_r->autoconf := prev.autoconf + n- | ~batch n => sc_r->batch := prev.batch + n- | ~powershell n => sc_r->powershell := prev.powershell + n- | ~m4 n => sc_r->m4 := prev.m4 + n- | ~objective_c n => sc_r->objective_c := prev.objective_c + n- | ~automake n => sc_r->automake := prev.automake + n- | ~margaret n => sc_r->margaret := prev.margaret + n- | ~unknown _ => ()- in- !sc_r- end--fun free_pl(pl : pl_type) : void =- case+ pl of- | ~unknown _ => ()- | ~rust _ => ()- | ~haskell _ => ()- | ~perl _ => ()- | ~lucius _ => ()- | ~cassius _ => ()- | ~hamlet _ => ()- | ~julius _ => ()- | ~bash _ => ()- | ~coq _ => ()- | ~justfile _ => ()- | ~makefile _ => ()- | ~yaml _ => ()- | ~toml _ => ()- | ~dhall _ => ()- | ~ipkg _ => ()- | ~ion _ => ()- | ~mercury _ => ()- | ~yacc _ => ()- | ~lex _ => ()- | ~r _ => ()- | ~c _ => ()- | ~cpp _ => ()- | ~lua _ => ()- | ~lalrpop _ => ()- | ~header _ => ()- | ~sixten _ => ()- | ~java _ => ()- | ~scala _ => ()- | ~elixir _ => ()- | ~erlang _ => ()- | ~happy _ => ()- | ~alex _ => ()- | ~go _ => ()- | ~html _ => ()- | ~css _ => ()- | ~brainfuck _ => ()- | ~ruby _ => ()- | ~julia _ => ()- | ~elm _ => ()- | ~purescript _ => ()- | ~vimscript _ => ()- | ~ocaml _ => ()- | ~madlang _ => ()- | ~agda _ => ()- | ~idris _ => ()- | ~futhark _ => ()- | ~ats _ => ()- | ~tex _ => ()- | ~cabal _ => ()- | ~cobol _ => ()- | ~tcl _ => ()- | ~verilog _ => ()- | ~vhdl _ => ()- | ~markdown _ => ()- | ~python _ => ()- | ~pony _ => ()- | ~jupyter _ => ()- | ~clojure _ => ()- | ~cabal_project _ => ()- | ~assembly _ => ()- | ~nix _ => ()- | ~php _ => ()- | ~javascript _ => ()- | ~kotlin _ => ()- | ~fsharp _ => ()- | ~fortran _ => ()- | ~swift _ => ()- | ~csharp _ => ()- | ~nim _ => ()- | ~cpp_header _ => ()- | ~elisp _ => ()- | ~plaintext _ => ()- | ~rakefile _ => ()- | ~llvm _ => ()- | ~autoconf _ => ()- | ~batch _ => ()- | ~powershell _ => ()- | ~m4 _ => ()- | ~objective_c _ => ()- | ~automake _ => ()- | ~margaret _ => ()--// match a particular word against a list of keywords-fun match_keywords { m : nat | m <= 10 } (keys : list(string, m), word : string) : bool =- list_foldright_cloref( keys- , lam (next, acc) =<cloref1> acc || eq_string_string(next, word)- , false- )--// TODO use list_vt{int}(0, 1, 2, 3, 4) instead?-// helper function for check_keywords-fun step_keyword(size : file, pre : pl_type, word : string, ext : string) : pl_type =- case+ pre of- | unknown _ => let- - in- case+ ext of- | "y" => let- val _ = free_pl(pre)- var happy_keywords = list_cons("module", list_nil())- in- if match_keywords(happy_keywords, word) then- happy(size)- else- if let- var yacc_keywords = list_cons("struct", list_cons("char", list_cons("int", list_nil())))- in- match_keywords(yacc_keywords, word)- end then- yacc(size)- else- unknown- end- | "v" => let- var _ = free_pl(pre)- var verilog_keywords = list_cons( "endmodule"- , list_cons( "posedge"- , list_cons( "edge"- , list_cons("always", list_cons("wire", list_nil()))- )- )- )- in- if match_keywords(verilog_keywords, word) then- verilog(size)- else- if let- var coq_keywords = list_cons( "Qed"- , list_cons( "Require"- , list_cons( "Hypothesis"- , list_cons( "Inductive"- , list_cons( "Remark"- , list_cons( "Lemma"- , list_cons( "Proof"- , list_cons( "Definition"- , list_cons( "Theorem"- , list_nil()- )- )- )- )- )- )- )- )- )- in- match_keywords(coq_keywords, word)- end then- coq(size)- else- unknown- end- | "m" => let- val _ = free_pl(pre)- var mercury_keywords = list_cons("module", list_cons("pred", list_cons("mode", list_nil())))- in- if match_keywords(mercury_keywords, word) then- mercury(size)- else- if let- var objective_c_keywords = list_cons( "nil"- , list_cons("nullable", list_cons("nonnull", list_nil()))- )- in- match_keywords(objective_c_keywords, word)- end then- objective_c(size)- else- unknown- end- | _ => pre- end- | _ => pre--// Function to disambiguate extensions such as .v (Coq and Verilog) and .m-// (Mercury and Objective C). This should only be called when extensions are in-// conflict, as it reads the whole file.-fun check_keywords(s : string, size : file, ext : string) : pl_type =- let- var ref = fileref_open_opt(s, file_mode_r)- in- case+ ref of- | ~Some_vt (x) => let- var init: pl_type = unknown- var viewstream = $EXTRA.streamize_fileref_word(x)- val result = stream_vt_foldleft_cloptr( viewstream- , init- , lam (acc, next) => step_keyword(size, acc, next, ext)- )- val _ = fileref_close(x)- in- result- end- | ~None_vt() => (println!("\33[33mWarning:\33[0m could not open file at " + s) ; unknown)- end--// Check shebang on scripts.-//-// TODO flexible parser that drops spaces as appropriate-// TODO check magic number so as to avoid checking shebang of binary file-fun check_shebang(s : string) : pl_type =- let- val ref = fileref_open_opt(s, file_mode_r)- val str: string = case+ ref of- | ~Some_vt (x) => let- val s = strptr2string(fileref_get_line_string(x))- val _ = fileref_close(x)- in- s- end- | ~None_vt() => (println!("\33[33mWarning:\33[0m could not open file at " + s) ; "")- in- case+ str of- | "#!/usr/bin/env ion" => ion(line_count(s, Some("#")))- | "#!/usr/bin/env bash" => bash(line_count(s, Some("#")))- | "#!/bin/bash" => bash(line_count(s, Some("#")))- | "#!python" => python(line_count(s, Some("#")))- | "#!python2" => python(line_count(s, Some("#")))- | "#!python3" => python(line_count(s, Some("#")))- | "#!/usr/bin/env python" => python(line_count(s, Some("#")))- | "#!/usr/bin/env python2" => python(line_count(s, Some("#")))- | "#!/usr/bin/env python3" => python(line_count(s, Some("#")))- | "#!/usr/bin/env perl" => perl(line_count(s, Some("#")))- | "#!/usr/bin/env perl6" => perl(line_count(s, Some("#")))- | "#!/usr/bin/perl" => perl(line_count(s, Some("#")))- | "#!/usr/bin/env stack" => haskell(line_count(s, Some("--")))- | "#!/usr/bin/env runhaskell" => haskell(line_count(s, Some("--")))- | "#!/usr/bin/env node" => javascript(line_count(s, None))- | _ => unknown- end--// Match based on filename (for makefiles, etc.)-fun match_filename(s : string) : pl_type =- let- val (prf | str) = filename_get_base(s)- val match = $UN.strptr2string(str)- - prval () = prf(str)- in- case+ match of- | "Makefile" => makefile(line_count(s, Some("#")))- | "Makefile.tc" => makefile(line_count(s, Some("#")))- | "makefile" => makefile(line_count(s, Some("#")))- | "GNUmakefile" => makefile(line_count(s, Some("#")))- | "Justfile" => justfile(line_count(s, Some("#")))- | "justfile" => justfile(line_count(s, Some("#")))- | "Rakefile" => rakefile(line_count(s, None))- | "cabal.project.local" => cabal_project(line_count(s, Some("--")))- | _ => check_shebang(s)- end--// Match based on file extension (assuming the file name is passed in as an-// argument).-fun prune_extension(s : string, file_proper : string) : pl_type =- let- val (prf | str) = filename_get_ext(file_proper)- val match: string = if strptr2ptr(str) > 0 then- $UN.strptr2string(str)- else- ""- - prval () = prf(str)- in- case+ match of- | "hs" => haskell(line_count(s, Some("--")))- | "hs-boot" => haskell(line_count(s, Some("--")))- | "hsig" => haskell(line_count(s, Some("--")))- | "rs" => rust(line_count(s, Some("//")))- | "tex" => tex(line_count(s, Some("%")))- | "md" => markdown(line_count(s, None))- | "markdown" => markdown(line_count(s, None))- | "dats" => ats(line_count(s, Some("//")))- | "hats" => ats(line_count(s, Some("//")))- | "cats" => ats(line_count(s, Some("//")))- | "sats" => ats(line_count(s, Some("//")))- | "py" => python(line_count(s, None))- | "fut" => futhark(line_count(s, Some("--")))- | "pl" => perl(line_count(s, None))- | "agda" => agda(line_count(s, Some("--")))- | "idr" => idris(line_count(s, Some("--")))- | "v" => check_keywords(s, line_count(s, Some("--")), match)- | "m" => check_keywords(s, line_count(s, None), match)- | "vhdl" => vhdl(line_count(s, None))- | "vhd" => vhdl(line_count(s, None))- | "go" => go(line_count(s, Some("//")))- | "vim" => vimscript(line_count(s, None))- | "ml" => ocaml(line_count(s, None))- | "purs" => purescript(line_count(s, None))- | "elm" => elm(line_count(s, Some("--")))- | "mad" => madlang(line_count(s, Some("#")))- | "toml" => toml(line_count(s, Some("#")))- | "cabal" => cabal(line_count(s, Some("--")))- | "yml" => yaml(line_count(s, Some("#")))- | "yaml" => yaml(line_count(s, Some("#")))- | "y" => check_keywords(s, line_count(s, None), match)- | "ypp" => yacc(line_count(s, Some("//")))- | "x" => alex(line_count(s, Some("--")))- | "l" => lex(line_count(s, None))- | "lpp" => lex(line_count(s, None))- | "html" => html(line_count(s, None))- | "htm" => html(line_count(s, None))- | "css" => css(line_count(s, None))- | "vhdl" => vhdl(line_count(s, None))- | "vhd" => vhdl(line_count(s, None))- | "c" => c(line_count(s, Some("//")))- | "b" => brainfuck(line_count(s, None))- | "bf" => brainfuck(line_count(s, None))- | "rb" => ruby(line_count(s, None))- | "cob" => cobol(line_count(s, None))- | "cbl" => cobol(line_count(s, None))- | "cpy" => cobol(line_count(s, None))- | "ml" => ocaml(line_count(s, None))- | "tcl" => tcl(line_count(s, None))- | "r" => r(line_count(s, None))- | "R" => r(line_count(s, None))- | "lua" => lua(line_count(s, None))- | "cpp" => cpp(line_count(s, Some("//")))- | "cc" => cpp(line_count(s, Some("//")))- | "lalrpop" => lalrpop(line_count(s, Some("//")))- | "h" => header(line_count(s, None))- | "vix" => sixten(line_count(s, Some("--")))- | "dhall" => dhall(line_count(s, None))- | "ipkg" => ipkg(line_count(s, Some("--")))- | "mk" => makefile(line_count(s, Some("#")))- | "hamlet" => hamlet(line_count(s, None))- | "cassius" => cassius(line_count(s, None))- | "lucius" => cassius(line_count(s, None))- | "julius" => julius(line_count(s, None))- | "jl" => julia(line_count(s, None))- | "ion" => ion(line_count(s, Some("#")))- | "bash" => bash(line_count(s, Some("#")))- | "ipynb" => jupyter(line_count(s, None))- | "java" => java(line_count(s, None))- | "scala" => scala(line_count(s, None))- | "erl" => erlang(line_count(s, None))- | "hrl" => erlang(line_count(s, None))- | "ex" => elixir(line_count(s, None))- | "exs" => elixir(line_count(s, None))- | "pony" => pony(line_count(s, None))- | "clj" => clojure(line_count(s, None))- | "s" => assembly(line_count(s, Some(";")))- | "S" => assembly(line_count(s, Some(";")))- | "asm" => assembly(line_count(s, Some(";")))- | "nix" => nix(line_count(s, None))- | "php" => php(line_count(s, None))- | "local" => match_filename(s)- | "project" => cabal_project(line_count(s, Some("--")))- | "js" => javascript(line_count(s, None))- | "jsexe" => javascript(line_count(s, None))- | "kt" => kotlin(line_count(s, None))- | "kts" => kotlin(line_count(s, None))- | "fs" => fsharp(line_count(s, None))- | "f" => fortran(line_count(s, None))- | "for" => fortran(line_count(s, None))- | "f90" => fortran(line_count(s, None))- | "f95" => fortran(line_count(s, None))- | "swift" => swift(line_count(s, None))- | "csharp" => csharp(line_count(s, None))- | "nim" => nim(line_count(s, None))- | "el" => elisp(line_count(s, None))- | "txt" => plaintext(line_count(s, None))- | "ll" => llvm(line_count(s, None))- | "in" => autoconf(line_count(s, Some("#")))- | "bat" => batch(line_count(s, None))- | "ps1" => powershell(line_count(s, None))- | "ac" => m4(line_count(s, None))- | "mm" => objective_c(line_count(s, Some("//")))- | "am" => automake(line_count(s, Some("#")))- | "mgt" => margaret(line_count(s, Some("--")))- | "" => match_filename(s)- | "sh" => match_filename(s)- | "yamllint" => match_filename(s)- | _ => unknown- end--// filter out directories containing artifacts-fun bad_dir(s : string, excludes : List0(string)) : bool =- case+ s of- | "." => true- | ".." => true- | ".pijul" => true- | "_darcs" => true- | ".hg" => true- | ".git" => true- | "target" => true- | ".egg-info" => true- | "nimcache" => true- | ".shake" => true- | "dist-newstyle" => true- | "dist" => true- | ".psc-package" => true- | ".pulp-cache" => true- | "output" => true- | "bower_components" => true- | "elm-stuff" => true- | ".stack-work" => true- | ".reco" => true- | ".reco-work" => true- | ".cabal-sandbox" => true- | "node_modules" => true- | ".lein-plugins" => true- | ".sass-cache" => true- | _ => list_exists_cloref(excludes, lam x => x = s || x = s + "/")--fnx step_stream( acc : source_contents- , full_name : string- , file_proper : string- , excludes : List0(string)- ) : source_contents =- if test_file_isdir(full_name) != 0 then- flow_stream(full_name, acc, excludes)- else- adjust_contents(acc, prune_extension(full_name, file_proper))-and flow_stream(s : string, init : source_contents, excludes : List0(string)) :-source_contents =- let- var files = streamize_dirname_fname(s)- var ffiles = stream_vt_filter_cloptr(files, lam x => not(bad_dir(x, excludes)))- in- stream_vt_foldleft_cloptr( ffiles- , init- , lam (acc, next) => step_stream(acc, s + "/" + next, next, excludes)- )- end--fun empty_contents() : source_contents =- let- var isc = @{ rust = empty_file()- , haskell = empty_file()- , ats = empty_file()- , python = empty_file()- , vimscript = empty_file()- , elm = empty_file()- , idris = empty_file()- , madlang = empty_file()- , tex = empty_file()- , markdown = empty_file()- , yaml = empty_file()- , toml = empty_file()- , cabal = empty_file()- , happy = empty_file()- , alex = empty_file()- , go = empty_file()- , html = empty_file()- , css = empty_file()- , verilog = empty_file()- , vhdl = empty_file()- , c = empty_file()- , purescript = empty_file()- , futhark = empty_file()- , brainfuck = empty_file()- , ruby = empty_file()- , julia = empty_file()- , perl = empty_file()- , ocaml = empty_file()- , agda = empty_file()- , cobol = empty_file()- , tcl = empty_file()- , r = empty_file()- , lua = empty_file()- , cpp = empty_file()- , lalrpop = empty_file()- , header = empty_file()- , sixten = empty_file()- , dhall = empty_file()- , ipkg = empty_file()- , makefile = empty_file()- , justfile = empty_file()- , ion = empty_file()- , bash = empty_file()- , hamlet = empty_file()- , cassius = empty_file()- , lucius = empty_file()- , julius = empty_file()- , mercury = empty_file()- , yacc = empty_file()- , lex = empty_file()- , coq = empty_file()- , jupyter = empty_file()- , java = empty_file()- , scala = empty_file()- , erlang = empty_file()- , elixir = empty_file()- , pony = empty_file()- , clojure = empty_file()- , cabal_project = empty_file()- , assembly = empty_file()- , nix = empty_file()- , php = empty_file()- , javascript = empty_file()- , kotlin = empty_file()- , fsharp = empty_file()- , fortran = empty_file()- , swift = empty_file()- , csharp = empty_file()- , nim = empty_file()- , cpp_header = empty_file()- , elisp = empty_file()- , plaintext = empty_file()- , rakefile = empty_file()- , llvm = empty_file()- , autoconf = empty_file()- , batch = empty_file()- , powershell = empty_file()- , m4 = empty_file()- , objective_c = empty_file()- , automake = empty_file()- , margaret = empty_file()- } : source_contents- in- isc- end--fun map_stream(acc : source_contents, includes : List0(string), excludes : List0(string)) :-source_contents =- list_foldleft_cloref( includes- , acc- , lam (acc, next) => if test_file_exists(next) || next = "" then- step_stream(acc, next, next, excludes)- else- (prerr("\33[31mError:\33[0m directory '" + next + "' does not exist\n") ; (exit(1) ; acc))- )--fun is_flag(s : string) : bool =- string_is_prefix("-", s)--fun process_excludes(s : string, acc : command_line) : command_line =- let- val acc_r = ref<command_line>(acc)- val () = if is_flag(s) then- (println!("Error: flag " + s + " found where a directory name was expected") ; (exit(0) ; ()))- else- acc_r->excludes := list_cons(s, acc.excludes)- in- !acc_r- end--fun process(s : string, acc : command_line, is_first : bool) : command_line =- let- val acc_r = ref<command_line>(acc)- val () = if is_flag(s) then- case+ s of- | "--help" => acc_r->help := true- | "-h" => acc_r->help := true- | "--no-table" => if not(acc.no_table) then- acc_r->no_table := true- else- (println!("\33[31mError:\33[0m flag " + s + " cannot appear twice") ; (exit(0) ; ()))- | "-t" => if not(acc.no_table) then- acc_r->no_table := true- else- (println!("\33[31mError:\33[0m flag " + s + " cannot appear twice") ; (exit(0) ; ()))- | "--parallel" => acc_r->parallel := true- | "-p" => acc_r->parallel := true- | "--version" => acc_r->version := true- | "-V" => acc_r->version := true- | "-e" => (println!("\33[31mError:\33[0m flag " + s + " must be followed by an argument") ;- (exit(0) ; ()))- | "--exclude" => (println!("\33[31mError:\33[0m flag " + s + " must be followed by an argument"- ) ; (exit(0) ; ()))- | _ => (println!("\33[31mError:\33[0m flag '" + s + "' not recognized") ; (exit(0) ; ()))- else- if not(is_first) then- acc_r->includes := list_cons(s, acc.includes)- else- ()- in- !acc_r- end--fnx get_cli { n : int | n >= 1 }{ m : nat | m < n } .<n - m>. ( argc : int(n)- , argv : !(argv(n))- , current : int(m)- , prev_is_exclude : bool- , acc : command_line- ) : command_line =- let- var arg = argv[current]- in- if current < argc - 1 then- if arg != "--exclude" && arg != "-e" then- let- val c = get_cli(argc, argv, current + 1, false, acc)- in- if prev_is_exclude && current != 0 then- process_excludes(arg, c)- else- if current != 0 then- process(arg, c, current = 0)- else- c- end- else- let- val c = get_cli(argc, argv, current + 1, true, acc)- in- c- end- else- if prev_is_exclude then- process_excludes(arg, acc)- else- process(arg, acc, current = 0)- end--fun version() : void =- println!("polygot version 0.3.11\nCopyright (c) 2017 Vanessa McHale")--fun help() : void =- print("polyglot - Count lines of code quickly.--\33[36mUSAGE:\33[0m poly [DIRECTORY] ... [OPTION] ...--\33[36mFLAGS:\33[0m- -V, --version show version information- -h, --help display this help and exit- -e, --exclude exclude a directory- -p, --parallel execute in parallel- -t, --no-table display results in alternate format--When no directory is provided poly will execute in the-current directory.--Bug reports and updates: nest.pijul.com/vamchale/polyglot\n"- )--fun head(xs : List0(string)) : string =- case+ xs of- | list_cons (x, xs) => x + ", " + head(xs)- | list_nil() => ""--// TODO channel to draw work? e.g. take a channel of strings, return a channel of source_contents-fun work( excludes : List0(string)- , send : channel(List0(string))- , chan : channel(source_contents)- ) : void =- {- val- (n) = channel_remove(send)- var x = map_stream(empty_contents(), n, excludes)- val () = channel_insert(chan, x)- val- ~None_vt() = channel_unref(chan)- val- () = case channel_unref<List0(string)>(send) of- | ~None_vt() => ()- | ~Some_vt (snd) => queue_free<List0(string)>(snd)- }--// Function returning the number of CPU cores.-extern-fun ncpu () : int--%{^-#include <unistd.h>-int ncpu() {- return sysconf(_SC_NPROCESSORS_ONLN);-}-%}--#define NCPU 4--fun apportion(includes : List0(string)) : (List0(string), List0(string)) =- let- var n = length(includes) / 2- val (p, q) = list_split_at(includes, n)- in- (list_vt2t(p), q)- end--// TODO maybe make a parallel fold?-fun threads(includes : List0(string), excludes : List0(string)) : source_contents =- let- val chan = channel_make<source_contents>(2)- val chan2 = channel_ref(chan)- val chan3 = channel_ref(chan)- val send1 = channel_make<List0(string)>(1)- val send2 = channel_make<List0(string)>(1)- val send_r1 = channel_ref(send1)- val send_r2 = channel_ref(send2)- var new_includes = if length(includes) > 0 then- includes- else- list_cons(".", list_nil())- val (fst, snd) = apportion(new_includes)- val _ = channel_insert(send1, fst)- val _ = channel_insert(send2, snd)- val t2 = athread_create_cloptr_exn(llam () => work(excludes, send_r1, chan2))- val t3 = athread_create_cloptr_exn(llam () => work(excludes, send_r2, chan3))- val- ~None_vt() = channel_unref(send1)- val- ~None_vt() = channel_unref(send2)- val- (n) = channel_remove(chan)- val- (m) = channel_remove(chan)- val () = ignoret(usleep(1u))- val () = while(channel_refcount(chan) >= 2)()- val r = add_contents(n, m)- val- ~Some_vt (que) = channel_unref<source_contents>(chan)- val () = queue_free<source_contents>(que)- in- r- end--implement main0 (argc, argv) =- let- val cli = @{ version = false- , help = false- , no_table = false- , parallel = false- , excludes = list_nil()- , includes = list_nil()- } : command_line- val parsed = get_cli(argc, argv, 0, false, cli)- in- if parsed.help then- (help() ; exit(0))- else- if parsed.version then- (version() ; exit(0))- else- let- val result = if parsed.parallel then- threads(parsed.includes, parsed.excludes)- else- if length(parsed.includes) > 0 then- map_stream(empty_contents(), parsed.includes, parsed.excludes)- else- map_stream(empty_contents(), list_cons(".", list_nil()), parsed.excludes)- in- if parsed.no_table then- print(make_output(result))- else- print(make_table(result))- end- end
− test/data/polyglot.out
@@ -1,1619 +0,0 @@-#include "share/atspre_staload.hats"-#include "share/HATS/atslib_staload_libats_libc.hats"-#include "prelude/DATS/filebas.dats"-#include "libats/ML/DATS/filebas_dirent.dats"-#include "libats/libc/DATS/dirent.dats"-#include "src/concurrency.dats"-#include "libats/DATS/athread_posix.dats"-#include "prelude/DATS/stream_vt.dats"--%{^-#include "libats/libc/CATS/string.cats"-#include "prelude/CATS/filebas.cats"-%}--staload "prelude/SATS/stream_vt.sats"-staload "libats/ML/DATS/list0.dats"-staload "libats/SATS/athread.sats"-staload "libats/ML/DATS/string.dats"-staload "libats/libc/SATS/stdio.sats"-staload "prelude/SATS/filebas.sats"-staload "src/filetype.sats"-staload "libats/ML/DATS/filebas.dats"-staload EXTRA = "libats/ML/SATS/filebas.sats"-staload "libats/libc/SATS/unistd.sats"-staload "libats/DATS/athread.dats"--fun to_file(s : string, pre : Option(string)) : file =- let- val is_comment = case+ pre of- | Some (x) => string_is_prefix(x, s)- | None => false- in- if s = "" then- @{ lines = 1, blanks = 1, comments = 0, files = 0 }- else- if is_comment then- @{ lines = 1, blanks = 0, comments = 1, files = 0 }- else- @{ lines = 1, blanks = 0, comments = 0, files = 0 }- end--fun empty_file() : file =- let- var f = @{ files = 0, blanks = 0, comments = 0, lines = 0 } : file- in- f- end--fun acc_file() : file =- let- var f = @{ files = 1, blanks = 0, comments = 0, lines = ~1 } : file- in- f- end--// monoidal addition for 'file' type-fun add_results(x : file, y : file) : file =- let- var next = @{ lines = x.lines + y.lines- , blanks = x.blanks + y.blanks- , comments = x.comments + y.comments- , files = x.files + y.files- }- in- next- end--overload + with add_results--// Given a string representing a filepath, return an integer.-fun line_count(s : string, pre : Option(string)) : file =- let- var ref = fileref_open_opt(s, file_mode_r)- in- case ref of- | ~Some_vt (x) => - begin- let- var viewstream: stream_vt(string) = $EXTRA.streamize_fileref_line(x)- val n: file = stream_vt_foldleft_cloptr( viewstream- , acc_file()- , lam (acc, f) =<cloptr1> acc + to_file(f, pre)- )- val _ = fileref_close(x)- in- n- end- end- | ~None_vt() => ( println!("\33[33mWarning:\33[0m could not open file at " + s)- ; to_file(s, None)- )- end--// Pad a string of bounded length on the right by adding spaces.-fnx right_pad { k : int | k >= 0 }{ m : int | m <= k } .<k>.-(s : string(m), n : int(k)) : string =- case+ length(s) < n of- | true when n > 0 => right_pad(s, n - 1) + " "- | _ => s--// Pad a string on the left by adding spaces.-fnx left_pad { k : int | k >= 0 } .<k>. (s : string, n : int(k)) :- string =- case+ length(s) < n of- | true when n > 0 => " " + left_pad(s, n - 1)- | _ => s--// helper function for make_output-fun maybe_string(s : string, n : int) : string =- if n > 0 then- s + ": " + tostring_int(n) + "\n"- else- ""--// helper function for make_table-fun maybe_table { k : int | k >= 0 && k < 20 } ( s : string(k)- , f : file- ) : string =- let- var code = f.lines - f.comments - f.blanks- in- if f.files > 0 then- " "- + right_pad(s, 21)- + left_pad(tostring_int(f.files), 5)- + left_pad(tostring_int(f.lines), 12)- + left_pad(tostring_int(code), 13)- + left_pad(tostring_int(f.comments), 13)- + left_pad(tostring_int(f.blanks), 13)- + "\n"- else- ""- end--// helper function for make_output-fun with_nonempty(s1 : string, s2 : string) : string =- if s2 != "" then- s1 + s2- else- ""--// helper function to make totals for tabular output.-fun sum_fields(sc : source_contents) : file =- let- var f = @{ lines = sc.rust.lines- + sc.haskell.lines- + sc.ats.lines- + sc.python.lines- + sc.vimscript.lines- + sc.elm.lines- + sc.idris.lines- + sc.madlang.lines- + sc.tex.lines- + sc.markdown.lines- + sc.yaml.lines- + sc.toml.lines- + sc.cabal.lines- + sc.happy.lines- + sc.alex.lines- + sc.go.lines- + sc.html.lines- + sc.css.lines- + sc.verilog.lines- + sc.vhdl.lines- + sc.c.lines- + sc.purescript.lines- + sc.futhark.lines- + sc.brainfuck.lines- + sc.ruby.lines- + sc.julia.lines- + sc.perl.lines- + sc.ocaml.lines- + sc.agda.lines- + sc.cobol.lines- + sc.tcl.lines- + sc.r.lines- + sc.lua.lines- + sc.cpp.lines- + sc.lalrpop.lines- + sc.header.lines- + sc.sixten.lines- + sc.dhall.lines- + sc.ipkg.lines- + sc.makefile.lines- + sc.justfile.lines- + sc.ion.lines- + sc.bash.lines- + sc.hamlet.lines- + sc.cassius.lines- + sc.lucius.lines- + sc.julius.lines- + sc.mercury.lines- + sc.yacc.lines- + sc.lex.lines- + sc.coq.lines- + sc.jupyter.lines- + sc.java.lines- + sc.scala.lines- + sc.erlang.lines- + sc.elixir.lines- + sc.pony.lines- + sc.clojure.lines- + sc.cabal_project.lines- + sc.assembly.lines- + sc.nix.lines- + sc.php.lines- + sc.javascript.lines- + sc.kotlin.lines- + sc.fsharp.lines- + sc.fortran.lines- + sc.swift.lines- + sc.csharp.lines- + sc.nim.lines- + sc.cpp_header.lines- + sc.elisp.lines- + sc.plaintext.lines- + sc.rakefile.lines- + sc.llvm.lines- + sc.autoconf.lines- + sc.batch.lines- + sc.powershell.lines- + sc.m4.lines- + sc.objective_c.lines- + sc.automake.lines- , blanks = sc.rust.blanks- + sc.haskell.blanks- + sc.ats.blanks- + sc.python.blanks- + sc.vimscript.blanks- + sc.elm.blanks- + sc.idris.blanks- + sc.madlang.blanks- + sc.tex.blanks- + sc.markdown.blanks- + sc.yaml.blanks- + sc.toml.blanks- + sc.cabal.blanks- + sc.happy.blanks- + sc.alex.blanks- + sc.go.blanks- + sc.html.blanks- + sc.css.blanks- + sc.verilog.blanks- + sc.vhdl.blanks- + sc.c.blanks- + sc.purescript.blanks- + sc.futhark.blanks- + sc.brainfuck.blanks- + sc.ruby.blanks- + sc.julia.blanks- + sc.perl.blanks- + sc.ocaml.blanks- + sc.agda.blanks- + sc.cobol.blanks- + sc.tcl.blanks- + sc.r.blanks- + sc.lua.blanks- + sc.cpp.blanks- + sc.lalrpop.blanks- + sc.header.blanks- + sc.sixten.blanks- + sc.dhall.blanks- + sc.ipkg.blanks- + sc.makefile.blanks- + sc.justfile.blanks- + sc.ion.blanks- + sc.bash.blanks- + sc.hamlet.blanks- + sc.cassius.blanks- + sc.lucius.blanks- + sc.julius.blanks- + sc.mercury.blanks- + sc.yacc.blanks- + sc.lex.blanks- + sc.coq.blanks- + sc.jupyter.blanks- + sc.java.blanks- + sc.scala.blanks- + sc.erlang.blanks- + sc.elixir.blanks- + sc.pony.blanks- + sc.clojure.blanks- + sc.cabal_project.blanks- + sc.assembly.blanks- + sc.nix.blanks- + sc.php.blanks- + sc.javascript.blanks- + sc.kotlin.blanks- + sc.fsharp.blanks- + sc.fortran.blanks- + sc.swift.blanks- + sc.csharp.blanks- + sc.nim.blanks- + sc.cpp_header.blanks- + sc.elisp.blanks- + sc.plaintext.blanks- + sc.rakefile.blanks- + sc.llvm.blanks- + sc.autoconf.blanks- + sc.batch.blanks- + sc.powershell.blanks- + sc.m4.blanks- + sc.objective_c.blanks- + sc.automake.blanks- , comments = sc.rust.comments- + sc.haskell.comments- + sc.ats.comments- + sc.python.comments- + sc.vimscript.comments- + sc.elm.comments- + sc.idris.comments- + sc.madlang.comments- + sc.tex.comments- + sc.markdown.comments- + sc.yaml.comments- + sc.toml.comments- + sc.cabal.comments- + sc.happy.comments- + sc.alex.comments- + sc.go.comments- + sc.html.comments- + sc.css.comments- + sc.verilog.comments- + sc.vhdl.comments- + sc.c.comments- + sc.purescript.comments- + sc.futhark.comments- + sc.brainfuck.comments- + sc.ruby.comments- + sc.julia.comments- + sc.perl.comments- + sc.ocaml.comments- + sc.agda.comments- + sc.cobol.comments- + sc.tcl.comments- + sc.r.comments- + sc.lua.comments- + sc.cpp.comments- + sc.lalrpop.comments- + sc.header.comments- + sc.sixten.comments- + sc.dhall.comments- + sc.ipkg.comments- + sc.makefile.comments- + sc.justfile.comments- + sc.ion.comments- + sc.bash.comments- + sc.hamlet.comments- + sc.cassius.comments- + sc.lucius.comments- + sc.julius.comments- + sc.mercury.comments- + sc.yacc.comments- + sc.lex.comments- + sc.coq.comments- + sc.jupyter.comments- + sc.java.comments- + sc.scala.comments- + sc.erlang.comments- + sc.elixir.comments- + sc.pony.comments- + sc.clojure.comments- + sc.cabal_project.comments- + sc.assembly.comments- + sc.nix.comments- + sc.php.comments- + sc.javascript.comments- + sc.kotlin.comments- + sc.fsharp.comments- + sc.fortran.comments- + sc.swift.comments- + sc.csharp.comments- + sc.nim.comments- + sc.cpp_header.comments- + sc.elisp.comments- + sc.plaintext.comments- + sc.rakefile.comments- + sc.llvm.comments- + sc.autoconf.comments- + sc.batch.comments- + sc.powershell.comments- + sc.m4.comments- + sc.objective_c.comments- + sc.automake.comments- , files = sc.rust.files- + sc.haskell.files- + sc.ats.files- + sc.python.files- + sc.vimscript.files- + sc.elm.files- + sc.idris.files- + sc.madlang.files- + sc.tex.files- + sc.markdown.files- + sc.yaml.files- + sc.toml.files- + sc.cabal.files- + sc.happy.files- + sc.alex.files- + sc.go.files- + sc.html.files- + sc.css.files- + sc.verilog.files- + sc.vhdl.files- + sc.c.files- + sc.purescript.files- + sc.futhark.files- + sc.brainfuck.files- + sc.ruby.files- + sc.julia.files- + sc.perl.files- + sc.ocaml.files- + sc.agda.files- + sc.cobol.files- + sc.tcl.files- + sc.r.files- + sc.lua.files- + sc.cpp.files- + sc.lalrpop.files- + sc.header.files- + sc.sixten.files- + sc.dhall.files- + sc.ipkg.files- + sc.makefile.files- + sc.justfile.files- + sc.ion.files- + sc.bash.files- + sc.hamlet.files- + sc.cassius.files- + sc.lucius.files- + sc.julius.files- + sc.mercury.files- + sc.yacc.files- + sc.lex.files- + sc.coq.files- + sc.jupyter.files- + sc.java.files- + sc.scala.files- + sc.erlang.files- + sc.elixir.files- + sc.pony.files- + sc.clojure.files- + sc.cabal_project.files- + sc.assembly.files- + sc.nix.files- + sc.php.files- + sc.javascript.files- + sc.kotlin.files- + sc.fsharp.files- + sc.fortran.files- + sc.swift.files- + sc.csharp.files- + sc.nim.files- + sc.cpp_header.files- + sc.elisp.files- + sc.plaintext.files- + sc.rakefile.files- + sc.llvm.files- + sc.autoconf.files- + sc.batch.files- + sc.powershell.files- + sc.m4.files- + sc.objective_c.files- + sc.automake.files- }- in- f- end--// function to print tabular output at the end-fun make_table(isc : source_contents) : string =- "-------------------------------------------------------------------------------\n \33[35mLanguage\33[0m \33[35mFiles\33[0m \33[35mLines\33[0m \33[35mCode\33[0m \33[35mComments\33[0m \33[35mBlanks\33[0m\n-------------------------------------------------------------------------------\n"- + maybe_table("Alex", isc.alex)- + maybe_table("Agda", isc.agda)- + maybe_table("Assembly", isc.assembly)- + maybe_table("ATS", isc.ats)- + maybe_table("Autoconf", isc.autoconf)- + maybe_table("Automake", isc.automake)- + maybe_table("Bash", isc.bash)- + maybe_table("Batch", isc.batch)- + maybe_table("Brainfuck", isc.brainfuck)- + maybe_table("C", isc.c)- + maybe_table("C Header", isc.header)- + maybe_table("C++ cpp_header", isc.cpp_header)- + maybe_table("C++", isc.cpp)- + maybe_table("C#", isc.csharp)- + maybe_table("Cabal", isc.cabal)- + maybe_table("Cabal Project", isc.cabal_project)- + maybe_table("Cassius", isc.cassius)- + maybe_table("COBOL", isc.cobol)- + maybe_table("Coq", isc.coq)- + maybe_table("CSS", isc.css)- + maybe_table("Dhall", isc.dhall)- + maybe_table("Elixir", isc.elixir)- + maybe_table("Elm", isc.elm)- + maybe_table("Emacs Lisp", isc.elisp)- + maybe_table("Erlang", isc.erlang)- + maybe_table("F#", isc.fsharp)- + maybe_table("Fortran", isc.fortran)- + maybe_table("Go", isc.go)- + maybe_table("Hamlet", isc.hamlet)- + maybe_table("Happy", isc.happy)- + maybe_table("Haskell", isc.haskell)- + maybe_table("HTML", isc.html)- + maybe_table("Idris", isc.idris)- + maybe_table("iPKG", isc.ipkg)- + maybe_table("Ion", isc.ion)- + maybe_table("Java", isc.java)- + maybe_table("JavaScript", isc.javascript)- + maybe_table("Julius", isc.julius)- + maybe_table("Julia", isc.julia)- + maybe_table("Jupyter", isc.jupyter)- + maybe_table("Justfile", isc.justfile)- + maybe_table("Kotlin", isc.kotlin)- + maybe_table("LALRPOP", isc.lalrpop)- + maybe_table("Lex", isc.lex)- + maybe_table("LLVM", isc.llvm)- + maybe_table("Lua", isc.lua)- + maybe_table("Lucius", isc.lucius)- + maybe_table("M4", isc.m4)- + maybe_table("Madlang", isc.madlang)- + maybe_table("Makefile", isc.makefile)- + maybe_table("Margaret", isc.margaret)- + maybe_table("Markdown", isc.markdown)- + maybe_table("Mercury", isc.mercury)- + maybe_table("Nim", isc.nim)- + maybe_table("Nix", isc.nix)- + maybe_table("Objective C", isc.objective_c)- + maybe_table("OCaml", isc.ocaml)- + maybe_table("Perl", isc.perl)- + maybe_table("PHP", isc.php)- + maybe_table("Plaintext", isc.plaintext)- + maybe_table("PowerShell", isc.powershell)- + maybe_table("Pony", isc.pony)- + maybe_table("Python", isc.python)- + maybe_table("PureScript", isc.purescript)- + maybe_table("R", isc.r)- + maybe_table("Rakefile", isc.rakefile)- + maybe_table("Ruby", isc.ruby)- + maybe_table("Rust", isc.rust)- + maybe_table("Scala", isc.scala)- + maybe_table("Sixten", isc.sixten)- + maybe_table("Swift", isc.swift)- + maybe_table("TCL", isc.tcl)- + maybe_table("TeX", isc.tex)- + maybe_table("TOML", isc.toml)- + maybe_table("Verilog", isc.verilog)- + maybe_table("VHDL", isc.vhdl)- + maybe_table("Vimscript", isc.vimscript)- + maybe_table("Yacc", isc.yacc)- + maybe_table("YAML", isc.yaml)- + "-------------------------------------------------------------------------------\n"- + maybe_table("Total", sum_fields(isc))- + "-------------------------------------------------------------------------------\n"--// Function to print output sorted by type of language.-fun make_output(isc : source_contents) : string =- with_nonempty( "\33[33mProgramming Languages:\33[0m\n"- , maybe_string("Agda", isc.agda.lines)- + maybe_string("Assembly", isc.assembly.lines)- + maybe_string("ATS", isc.ats.lines)- + maybe_string("Brainfuck", isc.brainfuck.lines)- + maybe_string("C", isc.c.lines)- + maybe_string("C Header", isc.header.lines)- + maybe_string("C++", isc.cpp.lines)- + maybe_string("C++ Header", isc.cpp_header.lines)- + maybe_string("C#", isc.csharp.lines)- + maybe_string("COBOL", isc.cobol.lines)- + maybe_string("Coq", isc.coq.lines)- + maybe_string("Elixir", isc.elixir.lines)- + maybe_string("Elm", isc.elm.lines)- + maybe_string("Erlang", isc.erlang.lines)- + maybe_string("F#", isc.fsharp.lines)- + maybe_string("Fortran", isc.fortran.lines)- + maybe_string("Go", isc.go.lines)- + maybe_string("Haskell", isc.haskell.lines)- + maybe_string("Idris", isc.idris.lines)- + maybe_string("Kotline", isc.kotlin.lines)- + maybe_string("Java", isc.java.lines)- + maybe_string("Julia", isc.julia.lines)- + maybe_string("Lua", isc.lua.lines)- + maybe_string("Margaret", isc.margaret.lines)- + maybe_string("Mercury", isc.mercury.lines)- + maybe_string("Nim", isc.nim.lines)- + maybe_string("Objective C", isc.objective_c.lines)- + maybe_string("OCaml", isc.ocaml.lines)- + maybe_string("Perl", isc.perl.lines)- + maybe_string("Pony", isc.pony.lines)- + maybe_string("PureScript", isc.purescript.lines)- + maybe_string("Python", isc.python.lines)- + maybe_string("R", isc.r.lines)- + maybe_string("Ruby", isc.ruby.lines)- + maybe_string("Rust", isc.rust.lines)- + maybe_string("Scala", isc.scala.lines)- + maybe_string("Sixten", isc.sixten.lines)- + maybe_string("Swift", isc.swift.lines)- + maybe_string("TCL", isc.tcl.lines)- )- + with_nonempty( "\n\33[33mEditor Plugins:\33[0m\n"- , maybe_string("Emacs Lisp", isc.elisp.lines)- + maybe_string("Vimscript", isc.vimscript.lines)- )- + with_nonempty( "\n\33[33mDocumentation:\33[0m\n"- , maybe_string("Markdown", isc.markdown.lines)- + maybe_string("Plaintext", isc.plaintext.lines)- + maybe_string("TeX", isc.tex.lines)- )- + with_nonempty( "\n\33[33mConfiguration:\33[0m\n"- , maybe_string("Cabal", isc.cabal.lines)- + maybe_string("Cabal Project", isc.cabal_project.lines)- + maybe_string("Dhall", isc.dhall.lines)- + maybe_string("iPKG", isc.ipkg.lines)- + maybe_string("TOML", isc.toml.lines)- + maybe_string("YAML", isc.yaml.lines)- )- + with_nonempty( "\n\33[33mShell:\33[0m\n"- , maybe_string("Bash", isc.bash.lines)- + maybe_string("Batch", isc.batch.lines)- + maybe_string("Ion", isc.ion.lines)- + maybe_string("PowerShell", isc.powershell.lines)- )- + with_nonempty( "\n\33[33mParser Generators:\33[0m\n"- , maybe_string("Alex", isc.alex.lines)- + maybe_string("Happy", isc.happy.lines)- + maybe_string("LALRPOP", isc.lalrpop.lines)- + maybe_string("Lex", isc.lex.lines)- + maybe_string("Yacc", isc.yacc.lines)- )- + with_nonempty( "\n\33[33mWeb:\33[0m\n"- , maybe_string("Cassius", isc.cassius.lines)- + maybe_string("CSS", isc.css.lines)- + maybe_string("Hamlet", isc.hamlet.lines)- + maybe_string("HTML", isc.html.lines)- + maybe_string("JavaScript", isc.javascript.lines)- + maybe_string("Julius", isc.julius.lines)- + maybe_string("Lucius", isc.lucius.lines)- )- + with_nonempty( "\n\33[33mHardware:\33[0m\n"- , maybe_string("Verilog", isc.verilog.lines)- + maybe_string("VHDL", isc.vhdl.lines)- )- + with_nonempty( "\n\33[33mNotebooks:\33[0m\n"- , maybe_string("Jupyter", isc.jupyter.lines)- )- + with_nonempty( "\n\33[33mOther:\33[0m\n"- , maybe_string("Autoconf", isc.autoconf.lines)- + maybe_string("Automake", isc.automake.lines)- + maybe_string("Justfile", isc.justfile.lines)- + maybe_string("LLVM", isc.llvm.lines)- + maybe_string("M4", isc.m4.lines)- + maybe_string("Madlang", isc.madlang.lines)- + maybe_string("Makefile", isc.makefile.lines)- + maybe_string("Rakefile", isc.rakefile.lines)- )--fun add_contents(x : source_contents, y : source_contents) :- source_contents =- let- var next = @{ rust = x.rust + y.rust- , haskell = x.haskell + y.haskell- , ats = x.ats + y.ats- , python = x.python + y.python- , vimscript = x.vimscript + y.vimscript- , elm = x.elm + y.elm- , idris = x.idris + y.idris- , madlang = x.madlang + y.madlang- , tex = x.tex + y.tex- , markdown = x.markdown + y.markdown- , yaml = x.yaml + y.yaml- , toml = x.toml + y.toml- , cabal = x.cabal + y.cabal- , happy = x.happy + y.happy- , alex = x.alex + y.alex- , go = x.go + y.go- , html = x.html + y.html- , css = x.css + y.css- , verilog = x.verilog + y.verilog- , vhdl = x.vhdl + y.vhdl- , c = x.c + y.c- , purescript = x.purescript + y.purescript- , futhark = x.futhark + y.futhark- , brainfuck = x.brainfuck + y.brainfuck- , ruby = x.ruby + y.ruby- , julia = x.julia + y.julia- , perl = x.perl + y.perl- , ocaml = x.ocaml + y.ocaml- , agda = x.agda + y.agda- , cobol = x.cobol + y.cobol- , tcl = x.tcl + y.tcl- , r = x.r + y.r- , lua = x.lua + y.lua- , cpp = x.cpp + y.cpp- , lalrpop = x.lalrpop + y.lalrpop- , header = x.header + y.header- , sixten = x.sixten + y.sixten- , dhall = x.dhall + y.dhall- , ipkg = x.ipkg + y.ipkg- , makefile = x.makefile + y.makefile- , justfile = x.justfile + y.justfile- , ion = x.ion + y.ion- , bash = x.bash + y.bash- , hamlet = x.hamlet + y.hamlet- , cassius = x.cassius + y.cassius- , lucius = x.lucius + y.lucius- , julius = x.julius + y.julius- , mercury = x.mercury + y.mercury- , yacc = x.yacc + y.yacc- , lex = x.lex + y.lex- , coq = x.coq + y.coq- , jupyter = x.jupyter + y.jupyter- , java = x.java + y.java- , scala = x.scala + y.scala- , erlang = x.erlang + y.erlang- , elixir = x.elixir + y.elixir- , pony = x.pony + y.pony- , clojure = x.clojure + y.clojure- , cabal_project = x.cabal_project + y.cabal_project- , assembly = x.assembly + y.assembly- , nix = x.nix + y.nix- , php = x.php + y.php- , javascript = x.javascript + y.javascript- , kotlin = x.kotlin + y.kotlin- , fsharp = x.fsharp + y.fsharp- , fortran = x.fortran + y.fortran- , swift = x.swift + y.swift- , csharp = x.csharp + y.csharp- , nim = x.nim + y.nim- , cpp_header = x.cpp_header + y.cpp_header- , elisp = x.elisp + y.elisp- , plaintext = x.plaintext + y.plaintext- , rakefile = x.rakefile + y.rakefile- , llvm = x.llvm + y.llvm- , autoconf = x.autoconf + y.autoconf- , batch = x.batch + y.batch- , powershell = x.powershell + y.powershell- , m4 = x.m4 + y.m4- , objective_c = x.objective_c + y.objective_c- , automake = x.automake + y.automake- , margaret = x.margaret + y.margaret- } : source_contents- in- next- end--// This is the step function used when streaming directory contents. -fun adjust_contents(prev : source_contents, scf : pl_type) :- source_contents =- let- val sc_r = ref<source_contents>(prev)- val _ = case+ scf of- | ~haskell n => sc_r->haskell := prev.haskell + n- | ~ats n => sc_r->ats := prev.ats + n- | ~rust n => sc_r->rust := prev.rust + n- | ~markdown n => sc_r->markdown := prev.markdown + n- | ~python n => sc_r->python := prev.python + n- | ~vimscript n => sc_r->vimscript := prev.vimscript + n- | ~yaml n => sc_r->yaml := prev.yaml + n- | ~toml n => sc_r->toml := prev.toml + n- | ~happy n => sc_r->happy := prev.happy + n- | ~alex n => sc_r->alex := prev.alex + n- | ~idris n => sc_r->idris := prev.idris + n- | ~madlang n => sc_r->madlang := prev.madlang + n- | ~elm n => sc_r->elm := prev.elm + n- | ~c n => sc_r->c := prev.c + n- | ~go n => sc_r->go := prev.go + n- | ~cabal n => sc_r->cabal := prev.cabal + n- | ~verilog n => sc_r->verilog := prev.verilog + n- | ~vhdl n => sc_r->vhdl := prev.vhdl + n- | ~html n => sc_r->html := prev.html + n- | ~css n => sc_r->css := prev.css + n- | ~purescript n => sc_r->purescript := prev.purescript + n- | ~futhark n => sc_r->futhark := prev.futhark + n- | ~brainfuck n => sc_r->brainfuck := prev.brainfuck + n- | ~ruby n => sc_r->ruby := prev.ruby + n- | ~julia n => sc_r->julia := prev.julia + n- | ~tex n => sc_r->tex := prev.tex + n- | ~perl n => sc_r->perl := prev.perl + n- | ~ocaml n => sc_r->ocaml := prev.ocaml + n- | ~agda n => sc_r->agda := prev.agda + n- | ~cobol n => sc_r->cobol := prev.cobol + n- | ~tcl n => sc_r->tcl := prev.tcl + n- | ~r n => sc_r->r := prev.r + n- | ~lua n => sc_r->lua := prev.lua + n- | ~cpp n => sc_r->cpp := prev.cpp + n- | ~lalrpop n => sc_r->lalrpop := prev.lalrpop + n- | ~header n => sc_r->header := prev.header + n- | ~sixten n => sc_r->sixten := prev.sixten + n- | ~dhall n => sc_r->dhall := prev.dhall + n- | ~ipkg n => sc_r->ipkg := prev.ipkg + n- | ~justfile n => sc_r->justfile := prev.justfile + n- | ~makefile n => sc_r->makefile := prev.makefile + n- | ~ion n => sc_r->ion := prev.ion + n- | ~bash n => sc_r->bash := prev.bash + n- | ~hamlet n => sc_r->hamlet := prev.hamlet + n- | ~cassius n => sc_r->cassius := prev.cassius + n- | ~lucius n => sc_r->lucius := prev.lucius + n- | ~julius n => sc_r->julius := prev.julius + n- | ~mercury n => sc_r->mercury := prev.mercury + n- | ~yacc n => sc_r->yacc := prev.yacc + n- | ~lex n => sc_r->lex := prev.lex + n- | ~coq n => sc_r->coq := prev.coq + n- | ~jupyter n => sc_r->jupyter := prev.jupyter + n- | ~java n => sc_r->java := prev.java + n- | ~scala n => sc_r->scala := prev.scala + n- | ~erlang n => sc_r->erlang := prev.erlang + n- | ~elixir n => sc_r->elixir := prev.elixir + n- | ~pony n => sc_r->pony := prev.pony + n- | ~clojure n => sc_r->clojure := prev.clojure + n- | ~cabal_project n => sc_r->cabal_project := prev.cabal_project + n- | ~assembly n => sc_r->assembly := prev.assembly + n- | ~nix n => sc_r->nix := prev.nix + n- | ~php n => sc_r->php := prev.php + n- | ~javascript n => sc_r->javascript := prev.javascript + n- | ~kotlin n => sc_r->kotlin := prev.kotlin + n- | ~fsharp n => sc_r->fsharp := prev.fsharp + n- | ~fortran n => sc_r->fortran := prev.fortran + n- | ~swift n => sc_r->swift := prev.swift + n- | ~csharp n => sc_r->csharp := prev.csharp + n- | ~nim n => sc_r->nim := prev.nim + n- | ~cpp_header n => sc_r->cpp_header := prev.cpp_header + n- | ~elisp n => sc_r->elisp := prev.elisp + n- | ~plaintext n => sc_r->plaintext := prev.plaintext + n- | ~rakefile n => sc_r->rakefile := prev.rakefile + n- | ~llvm n => sc_r->llvm := prev.llvm + n- | ~autoconf n => sc_r->autoconf := prev.autoconf + n- | ~batch n => sc_r->batch := prev.batch + n- | ~powershell n => sc_r->powershell := prev.powershell + n- | ~m4 n => sc_r->m4 := prev.m4 + n- | ~objective_c n => sc_r->objective_c := prev.objective_c + n- | ~automake n => sc_r->automake := prev.automake + n- | ~margaret n => sc_r->margaret := prev.margaret + n- | ~unknown _ => ()- in- !sc_r- end--fun free_pl(pl : pl_type) : void =- case+ pl of- | ~unknown _ => ()- | ~rust _ => ()- | ~haskell _ => ()- | ~perl _ => ()- | ~lucius _ => ()- | ~cassius _ => ()- | ~hamlet _ => ()- | ~julius _ => ()- | ~bash _ => ()- | ~coq _ => ()- | ~justfile _ => ()- | ~makefile _ => ()- | ~yaml _ => ()- | ~toml _ => ()- | ~dhall _ => ()- | ~ipkg _ => ()- | ~ion _ => ()- | ~mercury _ => ()- | ~yacc _ => ()- | ~lex _ => ()- | ~r _ => ()- | ~c _ => ()- | ~cpp _ => ()- | ~lua _ => ()- | ~lalrpop _ => ()- | ~header _ => ()- | ~sixten _ => ()- | ~java _ => ()- | ~scala _ => ()- | ~elixir _ => ()- | ~erlang _ => ()- | ~happy _ => ()- | ~alex _ => ()- | ~go _ => ()- | ~html _ => ()- | ~css _ => ()- | ~brainfuck _ => ()- | ~ruby _ => ()- | ~julia _ => ()- | ~elm _ => ()- | ~purescript _ => ()- | ~vimscript _ => ()- | ~ocaml _ => ()- | ~madlang _ => ()- | ~agda _ => ()- | ~idris _ => ()- | ~futhark _ => ()- | ~ats _ => ()- | ~tex _ => ()- | ~cabal _ => ()- | ~cobol _ => ()- | ~tcl _ => ()- | ~verilog _ => ()- | ~vhdl _ => ()- | ~markdown _ => ()- | ~python _ => ()- | ~pony _ => ()- | ~jupyter _ => ()- | ~clojure _ => ()- | ~cabal_project _ => ()- | ~assembly _ => ()- | ~nix _ => ()- | ~php _ => ()- | ~javascript _ => ()- | ~kotlin _ => ()- | ~fsharp _ => ()- | ~fortran _ => ()- | ~swift _ => ()- | ~csharp _ => ()- | ~nim _ => ()- | ~cpp_header _ => ()- | ~elisp _ => ()- | ~plaintext _ => ()- | ~rakefile _ => ()- | ~llvm _ => ()- | ~autoconf _ => ()- | ~batch _ => ()- | ~powershell _ => ()- | ~m4 _ => ()- | ~objective_c _ => ()- | ~automake _ => ()- | ~margaret _ => ()--// match a particular word against a list of keywords-fun match_keywords { m : nat | m <= 10 } ( keys : list(string, m)- , word : string- ) : bool =- list_foldright_cloref(keys, lam (next, acc) =<cloref1> acc- || eq_string_string(next, word), false)--// TODO use list_vt{int}(0, 1, 2, 3, 4) instead?-// helper function for check_keywords-fun step_keyword( size : file- , pre : pl_type- , word : string- , ext : string- ) : pl_type =- case+ pre of- | unknown _ => let- - in- case+ ext of- | "y" => let- val _ = free_pl(pre)- var happy_keywords = list_cons("module", list_nil())- in- if match_keywords(happy_keywords, word) then- happy(size)- else- if let- var yacc_keywords = list_cons( "struct"- , list_cons("char", list_cons("int", list_nil()))- )- in- match_keywords(yacc_keywords, word)- end then- yacc(size)- else- unknown- end- | "v" => let- var _ = free_pl(pre)- var verilog_keywords = list_cons( "endmodule"- , list_cons( "posedge"- , list_cons( "edge"- , list_cons("always", list_cons("wire", list_nil()))- )- )- )- in- if match_keywords( verilog_keywords- , word- ) then- verilog(size)- else- if let- var coq_keywords = list_cons( "Qed"- , list_cons( "Require"- , list_cons( "Hypothesis"- , list_cons( "Inductive"- , list_cons( "Remark"- , list_cons( "Lemma"- , list_cons( "Proof"- , list_cons( "Definition"- , list_cons( "Theorem"- , list_nil()- )- )- )- )- )- )- )- )- )- in- match_keywords(coq_keywords, word)- end then- coq(size)- else- unknown- end- | "m" => let- val _ = free_pl(pre)- var mercury_keywords = list_cons( "module"- , list_cons("pred", list_cons("mode", list_nil()))- )- in- if match_keywords(mercury_keywords, word) then- mercury(size)- else- if let- var objective_c_keywords = list_cons( "nil"- , list_cons("nullable", list_cons("nonnull", list_nil()))- )- in- match_keywords(objective_c_keywords, word)- end then- objective_c(size)- else- unknown- end- | _ => pre- end- | _ => pre--// Function to disambiguate extensions such as .v (Coq and Verilog) and .m-// (Mercury and Objective C). This should only be called when extensions are in-// conflict, as it reads the whole file.-fun check_keywords(s : string, size : file, ext : string) : pl_type =- let- var ref = fileref_open_opt(s, file_mode_r)- in- case+ ref of- | ~Some_vt (x) => let- var init: pl_type = unknown- var viewstream = $EXTRA.streamize_fileref_word(x)- val result = stream_vt_foldleft_cloptr( viewstream- , init- , lam (acc, next) =>- step_keyword(size, acc, next, ext)- )- val _ = fileref_close(x)- in- result- end- | ~None_vt() => ( println!("\33[33mWarning:\33[0m could not open file at " + s)- ; unknown- )- end--// Check shebang on scripts.-//-// TODO flexible parser that drops spaces as appropriate-// TODO check magic number so as to avoid checking shebang of binary file-fun check_shebang(s : string) : pl_type =- let- val ref = fileref_open_opt(s, file_mode_r)- val str: string = case+ ref of- | ~Some_vt (x) => let- val s = strptr2string(fileref_get_line_string(x))- val _ = fileref_close(x)- in- s- end- | ~None_vt() => ( println!("\33[33mWarning:\33[0m could not open file at " + s)- ; ""- )- in- case+ str of- | "#!/usr/bin/env ion" => ion(line_count(s, Some("#")))- | "#!/usr/bin/env bash" => bash(line_count(s, Some("#")))- | "#!/bin/bash" => bash(line_count(s, Some("#")))- | "#!python" => python(line_count(s, Some("#")))- | "#!python2" => python(line_count(s, Some("#")))- | "#!python3" => python(line_count(s, Some("#")))- | "#!/usr/bin/env python" => python(line_count(s, Some("#")))- | "#!/usr/bin/env python2" => python(line_count(s, Some("#")))- | "#!/usr/bin/env python3" => python(line_count(s, Some("#")))- | "#!/usr/bin/env perl" => perl(line_count(s, Some("#")))- | "#!/usr/bin/env perl6" => perl(line_count(s, Some("#")))- | "#!/usr/bin/perl" => perl(line_count(s, Some("#")))- | "#!/usr/bin/env stack" => haskell(line_count(s, Some("--")))- | "#!/usr/bin/env runhaskell" => haskell(line_count(s, Some("--")))- | "#!/usr/bin/env node" => javascript(line_count(s, None))- | _ => unknown- end--// Match based on filename (for makefiles, etc.)-fun match_filename(s : string) : pl_type =- let- val (prf | str) = filename_get_base(s)- val match = $UN.strptr2string(str)- prval () = prf(str)- in- case+ match of- | "Makefile" => makefile(line_count(s, Some("#")))- | "Makefile.tc" => makefile(line_count(s, Some("#")))- | "makefile" => makefile(line_count(s, Some("#")))- | "GNUmakefile" => makefile(line_count(s, Some("#")))- | "Justfile" => justfile(line_count(s, Some("#")))- | "justfile" => justfile(line_count(s, Some("#")))- | "Rakefile" => rakefile(line_count(s, None))- | "cabal.project.local" => cabal_project(line_count(s, Some("--")))- | _ => check_shebang(s)- end--// Match based on file extension (assuming the file name is passed in as an-// argument).-fun prune_extension(s : string, file_proper : string) : pl_type =- let- val (prf | str) = filename_get_ext(file_proper)- val match: string = if strptr2ptr(str) > 0 then- $UN.strptr2string(str)- else- ""- prval () = prf(str)- in- case+ match of- | "hs" => haskell(line_count(s, Some("--")))- | "hs-boot" => haskell(line_count(s, Some("--")))- | "hsig" => haskell(line_count(s, Some("--")))- | "rs" => rust(line_count(s, Some("//")))- | "tex" => tex(line_count(s, Some("%")))- | "md" => markdown(line_count(s, None))- | "markdown" => markdown(line_count(s, None))- | "dats" => ats(line_count(s, Some("//")))- | "hats" => ats(line_count(s, Some("//")))- | "cats" => ats(line_count(s, Some("//")))- | "sats" => ats(line_count(s, Some("//")))- | "py" => python(line_count(s, None))- | "fut" => futhark(line_count(s, Some("--")))- | "pl" => perl(line_count(s, None))- | "agda" => agda(line_count(s, Some("--")))- | "idr" => idris(line_count(s, Some("--")))- | "v" => check_keywords(s, line_count(s, Some("--")), match)- | "m" => check_keywords(s, line_count(s, None), match)- | "vhdl" => vhdl(line_count(s, None))- | "vhd" => vhdl(line_count(s, None))- | "go" => go(line_count(s, Some("//")))- | "vim" => vimscript(line_count(s, None))- | "ml" => ocaml(line_count(s, None))- | "purs" => purescript(line_count(s, None))- | "elm" => elm(line_count(s, Some("--")))- | "mad" => madlang(line_count(s, Some("#")))- | "toml" => toml(line_count(s, Some("#")))- | "cabal" => cabal(line_count(s, Some("--")))- | "yml" => yaml(line_count(s, Some("#")))- | "yaml" => yaml(line_count(s, Some("#")))- | "y" => check_keywords(s, line_count(s, None), match)- | "ypp" => yacc(line_count(s, Some("//")))- | "x" => alex(line_count(s, Some("--")))- | "l" => lex(line_count(s, None))- | "lpp" => lex(line_count(s, None))- | "html" => html(line_count(s, None))- | "htm" => html(line_count(s, None))- | "css" => css(line_count(s, None))- | "vhdl" => vhdl(line_count(s, None))- | "vhd" => vhdl(line_count(s, None))- | "c" => c(line_count(s, Some("//")))- | "b" => brainfuck(line_count(s, None))- | "bf" => brainfuck(line_count(s, None))- | "rb" => ruby(line_count(s, None))- | "cob" => cobol(line_count(s, None))- | "cbl" => cobol(line_count(s, None))- | "cpy" => cobol(line_count(s, None))- | "ml" => ocaml(line_count(s, None))- | "tcl" => tcl(line_count(s, None))- | "r" => r(line_count(s, None))- | "R" => r(line_count(s, None))- | "lua" => lua(line_count(s, None))- | "cpp" => cpp(line_count(s, Some("//")))- | "cc" => cpp(line_count(s, Some("//")))- | "lalrpop" => lalrpop(line_count(s, Some("//")))- | "h" => header(line_count(s, None))- | "vix" => sixten(line_count(s, Some("--")))- | "dhall" => dhall(line_count(s, None))- | "ipkg" => ipkg(line_count(s, Some("--")))- | "mk" => makefile(line_count(s, Some("#")))- | "hamlet" => hamlet(line_count(s, None))- | "cassius" => cassius(line_count(s, None))- | "lucius" => cassius(line_count(s, None))- | "julius" => julius(line_count(s, None))- | "jl" => julia(line_count(s, None))- | "ion" => ion(line_count(s, Some("#")))- | "bash" => bash(line_count(s, Some("#")))- | "ipynb" => jupyter(line_count(s, None))- | "java" => java(line_count(s, None))- | "scala" => scala(line_count(s, None))- | "erl" => erlang(line_count(s, None))- | "hrl" => erlang(line_count(s, None))- | "ex" => elixir(line_count(s, None))- | "exs" => elixir(line_count(s, None))- | "pony" => pony(line_count(s, None))- | "clj" => clojure(line_count(s, None))- | "s" => assembly(line_count(s, Some(";")))- | "S" => assembly(line_count(s, Some(";")))- | "asm" => assembly(line_count(s, Some(";")))- | "nix" => nix(line_count(s, None))- | "php" => php(line_count(s, None))- | "local" => match_filename(s)- | "project" => cabal_project(line_count(s, Some("--")))- | "js" => javascript(line_count(s, None))- | "jsexe" => javascript(line_count(s, None))- | "kt" => kotlin(line_count(s, None))- | "kts" => kotlin(line_count(s, None))- | "fs" => fsharp(line_count(s, None))- | "f" => fortran(line_count(s, None))- | "for" => fortran(line_count(s, None))- | "f90" => fortran(line_count(s, None))- | "f95" => fortran(line_count(s, None))- | "swift" => swift(line_count(s, None))- | "csharp" => csharp(line_count(s, None))- | "nim" => nim(line_count(s, None))- | "el" => elisp(line_count(s, None))- | "txt" => plaintext(line_count(s, None))- | "ll" => llvm(line_count(s, None))- | "in" => autoconf(line_count(s, Some("#")))- | "bat" => batch(line_count(s, None))- | "ps1" => powershell(line_count(s, None))- | "ac" => m4(line_count(s, None))- | "mm" => objective_c(line_count(s, Some("//")))- | "am" => automake(line_count(s, Some("#")))- | "mgt" => margaret(line_count(s, Some("--")))- | "" => match_filename(s)- | "sh" => match_filename(s)- | "yamllint" => match_filename(s)- | _ => unknown- end--// filter out directories containing artifacts-fun bad_dir(s : string, excludes : List0(string)) : bool =- case+ s of- | "." => true- | ".." => true- | ".pijul" => true- | "_darcs" => true- | ".hg" => true- | ".git" => true- | "target" => true- | ".egg-info" => true- | "nimcache" => true- | ".shake" => true- | "dist-newstyle" => true- | "dist" => true- | ".psc-package" => true- | ".pulp-cache" => true- | "output" => true- | "bower_components" => true- | "elm-stuff" => true- | ".stack-work" => true- | ".reco" => true- | ".reco-work" => true- | ".cabal-sandbox" => true- | "node_modules" => true- | ".lein-plugins" => true- | ".sass-cache" => true- | _ => list_exists_cloref(excludes, lam x => x = s || x = s + "/")--fnx step_stream( acc : source_contents- , full_name : string- , file_proper : string- , excludes : List0(string)- ) : source_contents =- if test_file_isdir(full_name) != 0 then- flow_stream(full_name, acc, excludes)- else- adjust_contents(acc, prune_extension(full_name, file_proper))-and flow_stream( s : string- , init : source_contents- , excludes : List0(string)- ) : source_contents =- let- var files = streamize_dirname_fname(s)- var ffiles = stream_vt_filter_cloptr(files, lam x => not(bad_dir( x- , excludes- )))- in- stream_vt_foldleft_cloptr( ffiles- , init- , lam (acc, next) =>- step_stream(acc, s + "/" + next, next, excludes)- )- end--fun empty_contents() : source_contents =- let- var isc = @{ rust = empty_file()- , haskell = empty_file()- , ats = empty_file()- , python = empty_file()- , vimscript = empty_file()- , elm = empty_file()- , idris = empty_file()- , madlang = empty_file()- , tex = empty_file()- , markdown = empty_file()- , yaml = empty_file()- , toml = empty_file()- , cabal = empty_file()- , happy = empty_file()- , alex = empty_file()- , go = empty_file()- , html = empty_file()- , css = empty_file()- , verilog = empty_file()- , vhdl = empty_file()- , c = empty_file()- , purescript = empty_file()- , futhark = empty_file()- , brainfuck = empty_file()- , ruby = empty_file()- , julia = empty_file()- , perl = empty_file()- , ocaml = empty_file()- , agda = empty_file()- , cobol = empty_file()- , tcl = empty_file()- , r = empty_file()- , lua = empty_file()- , cpp = empty_file()- , lalrpop = empty_file()- , header = empty_file()- , sixten = empty_file()- , dhall = empty_file()- , ipkg = empty_file()- , makefile = empty_file()- , justfile = empty_file()- , ion = empty_file()- , bash = empty_file()- , hamlet = empty_file()- , cassius = empty_file()- , lucius = empty_file()- , julius = empty_file()- , mercury = empty_file()- , yacc = empty_file()- , lex = empty_file()- , coq = empty_file()- , jupyter = empty_file()- , java = empty_file()- , scala = empty_file()- , erlang = empty_file()- , elixir = empty_file()- , pony = empty_file()- , clojure = empty_file()- , cabal_project = empty_file()- , assembly = empty_file()- , nix = empty_file()- , php = empty_file()- , javascript = empty_file()- , kotlin = empty_file()- , fsharp = empty_file()- , fortran = empty_file()- , swift = empty_file()- , csharp = empty_file()- , nim = empty_file()- , cpp_header = empty_file()- , elisp = empty_file()- , plaintext = empty_file()- , rakefile = empty_file()- , llvm = empty_file()- , autoconf = empty_file()- , batch = empty_file()- , powershell = empty_file()- , m4 = empty_file()- , objective_c = empty_file()- , automake = empty_file()- , margaret = empty_file()- } : source_contents- in- isc- end--fun map_stream( acc : source_contents- , includes : List0(string)- , excludes : List0(string)- ) : source_contents =- list_foldleft_cloref( includes- , acc- , lam (acc, next) =>- if test_file_exists(next) || next = "" then- step_stream(acc, next, next, excludes)- else- ( prerr("\33[31mError:\33[0m directory '" + next + "' does not exist\n")- ; exit(1)- ; acc- )- )--fun is_flag(s : string) : bool =- string_is_prefix("-", s)--fun process_excludes(s : string, acc : command_line) : command_line =- let- val acc_r = ref<command_line>(acc)- val () = if is_flag(s) then- ( println!("Error: flag " + s + " found where a directory name was expected")- ; exit(0)- ; ()- )- else- acc_r->excludes := list_cons(s, acc.excludes)- in- !acc_r- end--fun process(s : string, acc : command_line, is_first : bool) :- command_line =- let- val acc_r = ref<command_line>(acc)- val () = if is_flag(s) then- case+ s of- | "--help" => acc_r->help := true- | "-h" => acc_r->help := true- | "--no-table" => if not(acc.no_table) then- acc_r->no_table := true- else- ( println!("\33[31mError:\33[0m flag " + s + " cannot appear twice")- ; exit(0)- ; ()- )- | "-t" => if not(acc.no_table) then- acc_r->no_table := true- else- ( println!("\33[31mError:\33[0m flag " + s + " cannot appear twice")- ; exit(0)- ; ()- )- | "--parallel" => acc_r->parallel := true- | "-p" => acc_r->parallel := true- | "--version" => acc_r->version := true- | "-V" => acc_r->version := true- | "-e" => ( println!("\33[31mError:\33[0m flag " + s + " must be followed by an argument")- ; exit(0)- ; ()- )- | "--exclude" => ( println!("\33[31mError:\33[0m flag " + s + " must be followed by an argument")- ; exit(0)- ; ()- )- | _ => ( println!("\33[31mError:\33[0m flag '" + s + "' not recognized")- ; exit(0)- ; ()- )- else- if not(is_first) then- acc_r->includes := list_cons(s, acc.includes)- else- ()- in- !acc_r- end--fnx get_cli { n : int | n >= 1 }{ m : nat | m < n } .<n-m>.-( argc : int(n)-, argv : !argv(n)-, current : int(m)-, prev_is_exclude : bool-, acc : command_line-) : command_line =- let- var arg = argv[current]- in- if current < argc - 1 then- if arg != "--exclude" && arg != "-e" then- let- val c = get_cli(argc, argv, current + 1, false, acc)- in- if prev_is_exclude && current != 0 then- process_excludes(arg, c)- else- if current != 0 then- process(arg, c, current = 0)- else- c- end- else- let- val c = get_cli(argc, argv, current + 1, true, acc)- in- c- end- else- if prev_is_exclude then- process_excludes(arg, acc)- else- process(arg, acc, current = 0)- end--fun version() : void =- println!("polygot version 0.3.11\nCopyright (c) 2017 Vanessa McHale")--fun help() : void =- print("polyglot - Count lines of code quickly.--\33[36mUSAGE:\33[0m poly [DIRECTORY] ... [OPTION] ...--\33[36mFLAGS:\33[0m- -V, --version show version information- -h, --help display this help and exit- -e, --exclude exclude a directory- -p, --parallel execute in parallel- -t, --no-table display results in alternate format--When no directory is provided poly will execute in the-current directory.--Bug reports and updates: nest.pijul.com/vamchale/polyglot\n")--fun head(xs : List0(string)) : string =- case+ xs of- | list_cons (x, xs) => x + ", " + head(xs)- | list_nil() => ""--// TODO channel to draw work? e.g. take a channel of strings, return a channel of source_contents-fun work( excludes : List0(string)- , send : channel(List0(string))- , chan : channel(source_contents)- ) : void =- {- val- (n) = channel_remove(send)- var x = map_stream(empty_contents(), n, excludes)- val () = channel_insert(chan, x)- val- ~None_vt() = channel_unref(chan)- val- () = case channel_unref<List0(string)>(send) of- | ~None_vt() => ()- | ~Some_vt (snd) => queue_free<List0(string)>(snd)- }--// Function returning the number of CPU cores.-extern-fun ncpu() : int--%{^-#include <unistd.h>-int ncpu() {- return sysconf(_SC_NPROCESSORS_ONLN);-}-%}--#define NCPU 4--fun apportion(includes : List0(string)) :- (List0(string), List0(string)) =- let- var n = length(includes) / 2- val (p, q) = list_split_at(includes, n)- in- (list_vt2t(p), q)- end--// TODO maybe make a parallel fold?-fun threads(includes : List0(string), excludes : List0(string)) :- source_contents =- let- val chan = channel_make<source_contents>(2)- val chan2 = channel_ref(chan)- val chan3 = channel_ref(chan)- val send1 = channel_make<List0(string)>(1)- val send2 = channel_make<List0(string)>(1)- val send_r1 = channel_ref(send1)- val send_r2 = channel_ref(send2)- var new_includes = if length(includes) > 0 then- includes- else- list_cons(".", list_nil())- val (fst, snd) = apportion(new_includes)- val _ = channel_insert(send1, fst)- val _ = channel_insert(send2, snd)- val t2 = athread_create_cloptr_exn(llam () =>- work(excludes, send_r1, chan2))- val t3 = athread_create_cloptr_exn(llam () =>- work(excludes, send_r2, chan3))- val- ~None_vt() = channel_unref(send1)- val- ~None_vt() = channel_unref(send2)- val- (n) = channel_remove(chan)- val- (m) = channel_remove(chan)- val () = ignoret(usleep(1u))- val () = while(channel_refcount(chan) >= 2)()- val r = add_contents(n, m)- val- ~Some_vt (que) = channel_unref<source_contents>(chan)- val () = queue_free<source_contents>(que)- in- r- end--implement main0 (argc, argv) =- let- val cli = @{ version = false- , help = false- , no_table = false- , parallel = false- , excludes = list_nil()- , includes = list_nil()- } : command_line- val parsed = get_cli(argc, argv, 0, false, cli)- in- if parsed.help then- (help() ; exit(0))- else- if parsed.version then- (version() ; exit(0))- else- let- val result = if parsed.parallel then- threads(parsed.includes, parsed.excludes)- else- if length(parsed.includes) > 0 then- map_stream(empty_contents(), parsed.includes, parsed.excludes)- else- map_stream( empty_contents()- , list_cons(".", list_nil())- , parsed.excludes- )- in- if parsed.no_table then- print(make_output(result))- else- print(make_table(result))- end- end
− test/data/toml-parse.dats
@@ -1,244 +0,0 @@-#include "share/atspre_staload.hats"-#include "share/HATS/atslib_staload_libats_libc.hats"--staload UN = "prelude/SATS/unsafe.sats"-staload "src/types.sats"-staload "prelude/basics_sta.sats"-staload "libats/libc/SATS/stdio.sats"-staload "prelude/SATS/string.sats"--fun snoc(s : string, c : char) : string =- let- val sc = char2string(c)- val x = string0_append(s, sc)- in- strptr2string(x)- end--fun next {m : nat} (x : string(m)) : Option_vt(char) =- if length(x) > 0 then- Some_vt(string_head(x))- else- None_vt--fun stop_plain_string(c : char) : bool =- case+ c of- | '\n' => true- | '#' => true- | _ => false--fun map {a : vtype}{b : vtype} (f : a -<lincloptr1> b, x : parser(a)) : parser(b) =- let- val g = x.modify- in- @{ modify = llam c =<lincloptr1> - begin- let- val (y, z): (cstream, a) = g(c)- val w: b = f(z)- in- (cloptr_free($UN.castvwtp0(f)) ; cloptr_free($UN.castvwtp0(g)) ; (y, w))- end- end }- end--extern-fun bind {a : vtype}{b : vtype} (x : parser(a), f : a -<lincloptr1> parser(b)) : parser(b)--fun pure {a : vtype} (x : a) : parser(a) =- @{ modify = llam c =<lincloptr1> (c, x) }--fun chain {a : vtype}{b : vtype} (x : parser(a), y : parser(b)) : parser(b) =- @{ modify = llam c =<lincloptr1> let- val f = x.modify- val g = y.modify- val (pre_res, _) = f(c)- val (res, y) = g(pre_res)- val _ = cloptr_free($UN.castvwtp0(f))- val _ = cloptr_free($UN.castvwtp0(g))- in- (res, y)- end }--fun run_parser {a : vtype} (in_stream : cstream, parser : parser(a)) : a =- let- val g = parser.modify- val (s, z) = g(in_stream)- val _ = stream_vt_free(s)- val _ = cloptr_free($UN.castvwtp0(g))- in- z- end--fun consume_space() : parser(null) =- pre_consume_space() where- { fun pre_consume_space() : parser(null) =- let- fnx loop(input : cstream) : (cstream, null) =- case+ !input of- | ~stream_vt_cons (' ', xs) => loop(xs)- | ~stream_vt_cons (_, xs) => (xs, null)- | ~stream_vt_nil() => ($ldelay(stream_vt_nil), null)- in- @{ modify = llam (input) =<lincloptr1> loop(input) }- end }--fun consume_int() : parser(token) =- pre_consume_int() where- { fun pre_consume_int() : parser(token) =- let- fun loop(input : cstream, data : int) : (cstream, int) =- case+ !input of- | ~stream_vt_cons ('0', xs) => loop(xs, 10 * data)- | ~stream_vt_cons ('1', xs) => loop(xs, 10 * data + 1)- | ~stream_vt_cons ('2', xs) => loop(xs, 10 * data + 2)- | ~stream_vt_cons ('3', xs) => loop(xs, 10 * data + 3)- | ~stream_vt_cons ('4', xs) => loop(xs, 10 * data + 4)- | ~stream_vt_cons ('5', xs) => loop(xs, 10 * data + 5)- | ~stream_vt_cons ('6', xs) => loop(xs, 10 * data + 6)- | ~stream_vt_cons ('7', xs) => loop(xs, 10 * data + 7)- | ~stream_vt_cons ('8', xs) => loop(xs, 10 * data + 8)- | ~stream_vt_cons ('9', xs) => loop(xs, 10 * data + 9)- | ~stream_vt_cons (_, xs) => (xs, data)- | ~stream_vt_nil() => ($ldelay(stream_vt_nil), data)- - fun data(input : cstream) : (cstream, token) =- let- val (x, y) = loop(input, 0)- in- (x, int_tok(y))- end- in- @{ modify = llam (input) =<lincloptr1> data(input) }- end }--fun is_letter(c : char) : bool =- case+ c of- | 'a' => true- | 'b' => true- | 'c' => true- | 'd' => true- | 'e' => true- | 'f' => true- | 'g' => true- | 'h' => true- | 'i' => true- | 'j' => true- | 'k' => true- | 'l' => true- | 'm' => true- | 'n' => true- | 'o' => true- | 'p' => true- | 'q' => true- | 'r' => true- | 's' => true- | 't' => true- | 'u' => true- | 'v' => true- | 'w' => true- | 'x' => true- | 'y' => true- | 'z' => true- | '-' => true- | _ => false--fun free_tok(t : token) : void =- case+ t of- | ~string_tok (_) => ()- | ~int_tok (_) => ()- | ~eq_tok() => ()- | ~pound_tok() => ()- | ~float_tok (_) => ()- | ~bool_tok (_) => ()--fun mk_eq(s : string) : token =- eq_tok()--// TODO consider list_vt(char)? what would that accomplish/help-// FIXME this is stupid as hell.-fun consume_eq() : parser(token) =- map(llam x =<lincloptr1> mk_eq(x), pre_consume_identifier()) where- { fun pre_consume_identifier() : parser(string) =- let- fun loop(input : cstream, data : string) : (cstream, string) =- case+ !input of- | ~stream_vt_cons ('=', xs) => loop(xs, snoc(data, '='))- | ~stream_vt_cons (_, xs) => (xs, data)- | ~stream_vt_nil() => ($ldelay(stream_vt_nil), "")- - fun data(input : cstream) : (cstream, string) =- loop(input, "")- in- @{ modify = llam (input) =<lincloptr1> data(input) }- end }--fun consume_identifier() : parser(token) =- map(llam x =<lincloptr1> string_tok(x), pre_consume_identifier()) where- { fun pre_consume_identifier() : parser(string) =- let- fun loop(input : cstream, data : string) : (cstream, string) =- case+ !input of- | ~stream_vt_cons (c, xs) when is_letter(c) => loop(xs, snoc(data, c))- | ~stream_vt_cons (_, xs) => (xs, data)- | ~stream_vt_nil() => ($ldelay(stream_vt_nil), "")- - fun data(input : cstream) : (cstream, string) =- loop(input, "")- in- @{ modify = llam (input) =<lincloptr1> data(input) }- end }--fun consume_quoted() : parser(token) =- map(llam x =<lincloptr1> string_tok(x), pre_consume_quoted()) where- { fun pre_consume_quoted() : parser(string) =- let- fun loop(input : cstream, is_escaped : bool, data : string) : (cstream, string) =- case+ !input of- | ~stream_vt_cons ('\\', xs) => loop(xs, true, data)- | ~stream_vt_cons (x, xs) => - begin- if not(is_escaped) then- if x = '"' then- (xs, data)- else- loop(xs, false, snoc(data, x))- else- loop(xs, false, snoc(data, x))- end- | ~stream_vt_nil() => (prerr!("Error: missing \"") ; exit(1) ; ($ldelay(stream_vt_nil), ""))- - fun data(input : cstream) : (cstream, string) =- loop(input, false, "")- in- @{ modify = llam (input) =<lincloptr1> data(input) }- end }--fun tokenize(input : cstream) : tstream =- case+ !input of- | ~stream_vt_cons (x, xs) => (stream_vt_free(xs) ; $ldelay(stream_vt_nil()))- | ~stream_vt_nil() => $ldelay(stream_vt_nil())--fun display_token(t : token) : void =- case+ t of- | ~string_tok (s) => println!(s)- | ~int_tok (i) => println!(tostring_int(i))- | ~eq_tok() => println!("=")- | ~pound_tok() => println!("#")- | ~float_tok (x) => ()- | ~bool_tok (b) => ()--implement main0 () =- let- var fr = fileref_open_exn("junk1", file_mode_r)- var stream = streamize_fileref_char(fr)- val t1: token = run_parser(stream, consume_quoted())- var fr = fileref_open_exn("junk2", file_mode_r)- var stream = streamize_fileref_char(fr)- val t2: token = run_parser(stream, consume_int())- var fr = fileref_open_exn("junk3", file_mode_r)- var stream = streamize_fileref_char(fr)- val t3: token = run_parser(stream, chain(consume_identifier(), chain(consume_eq(), consume_int())))- in- (display_token(t1) ; display_token(t2) ; display_token(t3))- end
− test/data/toml-parse.out
@@ -1,260 +0,0 @@-#include "share/atspre_staload.hats"-#include "share/HATS/atslib_staload_libats_libc.hats"--staload UN = "prelude/SATS/unsafe.sats"-staload "src/types.sats"-staload "prelude/basics_sta.sats"-staload "libats/libc/SATS/stdio.sats"-staload "prelude/SATS/string.sats"--fun snoc(s : string, c : char) : string =- let- val sc = char2string(c)- val x = string0_append(s, sc)- in- strptr2string(x)- end--fun next {m:nat} (x : string(m)) : Option_vt(char) =- if length(x) > 0 then- Some_vt(string_head(x))- else- None_vt--fun stop_plain_string(c : char) : bool =- case+ c of- | '\n' => true- | '#' => true- | _ => false--fun map {a:vtype}{b:vtype} (f : a -<lincloptr1> b, x : parser(a)) :- parser(b) =- let- val g = x.modify- in- @{ modify = llam c =<lincloptr1>- - begin- let- val (y, z): (cstream, a) = g(c)- val w: b = f(z)- in- (cloptr_free($UN.castvwtp0(f)); cloptr_free($UN.castvwtp0(g)); (y, w))- end- end }- end--extern-fun bind {a:vtype}{b:vtype} ( x : parser(a)- , f : a -<lincloptr1> parser(b)- ) : parser(b)--fun pure {a:vtype} (x : a) : parser(a) =- @{ modify = llam c =<lincloptr1> (c, x) }--fun chain {a:vtype}{b:vtype} (x : parser(a), y : parser(b)) :- parser(b) =- @{ modify = llam c =<lincloptr1>- let- val f = x.modify- val g = y.modify- val (pre_res, _) = f(c)- val (res, y) = g(pre_res)- val _ = cloptr_free($UN.castvwtp0(f))- val _ = cloptr_free($UN.castvwtp0(g))- in- (res, y)- end }--fun run_parser {a:vtype} (in_stream : cstream, parser : parser(a)) : a =- let- val g = parser.modify- val (s, z) = g(in_stream)- val _ = stream_vt_free(s)- val _ = cloptr_free($UN.castvwtp0(g))- in- z- end--fun consume_space() : parser(null) =- pre_consume_space() where- { fun pre_consume_space() : parser(null) =- let- fnx loop(input : cstream) : (cstream, null) =- case+ !input of- | ~stream_vt_cons (' ', xs) => loop(xs)- | ~stream_vt_cons (_, xs) => (xs, null)- | ~stream_vt_nil() => ($ldelay(stream_vt_nil), null)- in- @{ modify = llam (input) =<lincloptr1> loop(input) }- end }--fun consume_int() : parser(token) =- pre_consume_int() where- { fun pre_consume_int() : parser(token) =- let- fun loop(input : cstream, data : int) : (cstream, int) =- case+ !input of- | ~stream_vt_cons ('0', xs) => loop(xs, 10 * data)- | ~stream_vt_cons ('1', xs) => loop(xs, 10 * data + 1)- | ~stream_vt_cons ('2', xs) => loop(xs, 10 * data + 2)- | ~stream_vt_cons ('3', xs) => loop(xs, 10 * data + 3)- | ~stream_vt_cons ('4', xs) => loop(xs, 10 * data + 4)- | ~stream_vt_cons ('5', xs) => loop(xs, 10 * data + 5)- | ~stream_vt_cons ('6', xs) => loop(xs, 10 * data + 6)- | ~stream_vt_cons ('7', xs) => loop(xs, 10 * data + 7)- | ~stream_vt_cons ('8', xs) => loop(xs, 10 * data + 8)- | ~stream_vt_cons ('9', xs) => loop(xs, 10 * data + 9)- | ~stream_vt_cons (_, xs) => (xs, data)- | ~stream_vt_nil() => ($ldelay(stream_vt_nil), data)- - fun data(input : cstream) : (cstream, token) =- let- val (x, y) = loop(input, 0)- in- (x, int_tok(y))- end- in- @{ modify = llam (input) =<lincloptr1> data(input) }- end }--fun is_letter(c : char) : bool =- case+ c of- | 'a' => true- | 'b' => true- | 'c' => true- | 'd' => true- | 'e' => true- | 'f' => true- | 'g' => true- | 'h' => true- | 'i' => true- | 'j' => true- | 'k' => true- | 'l' => true- | 'm' => true- | 'n' => true- | 'o' => true- | 'p' => true- | 'q' => true- | 'r' => true- | 's' => true- | 't' => true- | 'u' => true- | 'v' => true- | 'w' => true- | 'x' => true- | 'y' => true- | 'z' => true- | '-' => true- | _ => false--fun free_tok(t : token) : void =- case+ t of- | ~string_tok (_) => ()- | ~int_tok (_) => ()- | ~eq_tok() => ()- | ~pound_tok() => ()- | ~float_tok (_) => ()- | ~bool_tok (_) => ()--fun mk_eq(s : string) : token =- eq_tok()--// TODO consider list_vt(char)? what would that accomplish/help-// FIXME this is stupid as hell.-fun consume_eq() : parser(token) =- map(llam x =<lincloptr1> mk_eq(x), pre_consume_identifier()) where- { fun pre_consume_identifier() : parser(string) =- let- fun loop(input : cstream, data : string) : (cstream, string) =- case+ !input of- | ~stream_vt_cons ('=', xs) => loop(xs, snoc(data, '='))- | ~stream_vt_cons (_, xs) => (xs, data)- | ~stream_vt_nil() => ($ldelay(stream_vt_nil), "")- - fun data(input : cstream) : (cstream, string) =- loop(input, "")- in- @{ modify = llam (input) =<lincloptr1> data(input) }- end }--fun consume_identifier() : parser(token) =- map( llam x =<lincloptr1> string_tok(x)- , pre_consume_identifier()- ) where- { fun pre_consume_identifier() : parser(string) =- let- fun loop(input : cstream, data : string) : (cstream, string) =- case+ !input of- | ~stream_vt_cons (c, xs) when is_letter(c) => loop(xs, snoc(data, c))- | ~stream_vt_cons (_, xs) => (xs, data)- | ~stream_vt_nil() => ($ldelay(stream_vt_nil), "")- - fun data(input : cstream) : (cstream, string) =- loop(input, "")- in- @{ modify = llam (input) =<lincloptr1> data(input) }- end }--fun consume_quoted() : parser(token) =- map(llam x =<lincloptr1> string_tok(x), pre_consume_quoted()) where- { fun pre_consume_quoted() : parser(string) =- let- fun loop(input : cstream, is_escaped : bool, data : string) :- (cstream, string) =- case+ !input of- | ~stream_vt_cons ('\\', xs) => loop(xs, true, data)- | ~stream_vt_cons (x, xs) => - begin- if not(is_escaped) then- if x = '"' then- (xs, data)- else- loop(xs, false, snoc(data, x))- else- loop(xs, false, snoc(data, x))- end- | ~stream_vt_nil() => ( prerr!("Error: missing \"")- ; exit(1)- ; ($ldelay(stream_vt_nil), "")- )- - fun data(input : cstream) : (cstream, string) =- loop(input, false, "")- in- @{ modify = llam (input) =<lincloptr1> data(input) }- end }--fun tokenize(input : cstream) : tstream =- case+ !input of- | ~stream_vt_cons (x, xs) => ( stream_vt_free(xs)- ; $ldelay(stream_vt_nil())- )- | ~stream_vt_nil() => $ldelay(stream_vt_nil())--fun display_token(t : token) : void =- case+ t of- | ~string_tok (s) => println!(s)- | ~int_tok (i) => println!(tostring_int(i))- | ~eq_tok() => println!("=")- | ~pound_tok() => println!("#")- | ~float_tok (x) => ()- | ~bool_tok (b) => ()--implement main0 () =- let- var fr = fileref_open_exn("junk1", file_mode_r)- var stream = streamize_fileref_char(fr)- val t1: token = run_parser(stream, consume_quoted())- var fr = fileref_open_exn("junk2", file_mode_r)- var stream = streamize_fileref_char(fr)- val t2: token = run_parser(stream, consume_int())- var fr = fileref_open_exn("junk3", file_mode_r)- var stream = streamize_fileref_char(fr)- val t3: token = run_parser( stream- , chain(consume_identifier(), chain(consume_eq(), consume_int()))- )- in- (display_token(t1) ; display_token(t2) ; display_token(t3))- end
− test/data/types.out
@@ -1,24 +0,0 @@-datavtype null =- | null--datavtype token =- | string_tok of string- | int_tok of int- | eq_tok- | pound_tok- | float_tok of float- | bool_tok of bool--datavtype error_state =- | okay- | error_state of string--vtypedef cstream = stream_vt(char)-vtypedef tstream = stream_vt(token)--datavtype either(a : t@ype, b : t@ype+) =- | left of a- | right of b--vtypedef parser(a : vt@ype+) =- @{ modify = cstream -<lincloptr1> (cstream, a) }
− test/data/types.sats
@@ -1,23 +0,0 @@-datavtype null =- | null--datavtype token =- | string_tok of string- | int_tok of int- | eq_tok- | pound_tok- | float_tok of float- | bool_tok of bool--datavtype error_state =- | okay- | error_state of string--vtypedef cstream = stream_vt(char)-vtypedef tstream = stream_vt(token)--datavtype either(a : t@ype, b : t@ype+) =- | left of a- | right of b--vtypedef parser(a : vt@ype+) = @{ modify = cstream -<lincloptr1> (cstream, a) }