Skip to content

Commit

Permalink
update doc infra: single map for all doc snippets + references
Browse files Browse the repository at this point in the history
  • Loading branch information
byorgey committed Dec 25, 2024
1 parent 0d2cd64 commit 71bef60
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 166 deletions.
325 changes: 194 additions & 131 deletions src/Disco/Doc.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
-----------------------------------------------------------------------------

-----------------------------------------------------------------------------

-- SPDX-License-Identifier: BSD-3-Clause

-- |
Expand All @@ -11,10 +7,12 @@
--
-- Built-in documentation.
module Disco.Doc (
primDoc,
primReference,
otherDoc,
otherReference,
DocKey(..),
RefType(..),
Reference(..),
mkRef,
mkIntro,
docMap,
) where

import Data.Map (Map)
Expand All @@ -24,136 +22,201 @@ import Disco.Syntax.Operators
import Disco.Syntax.Prims
import Disco.Util ((==>))

-- | A map from some primitives to a short descriptive string,
-- to be shown by the :doc command.
primDoc :: Map Prim String
primDoc =
M.fromList
[ PrimUOp Neg ==> "Arithmetic negation."
, PrimBOp Add ==> "The sum of two numbers, types, or graphs."
, PrimBOp Sub ==> "The difference of two numbers."
, PrimBOp SSub ==> "The difference of two numbers, with a lower bound of 0."
, PrimBOp Mul ==> "The product of two numbers, types, or graphs."
, PrimBOp Div ==> "Divide two numbers."
, PrimBOp IDiv ==> "The integer quotient of two numbers, rounded down."
, PrimBOp Mod ==> "a mod b is the remainder when a is divided by b."
, PrimBOp Exp ==> "Exponentiation. a ^ b is a raised to the b power."
, PrimUOp Fact ==> "n! computes the factorial of n, that is, 1 * 2 * ... * n."
, PrimFloor ==> "floor(x) is the largest integer which is <= x."
, PrimCeil ==> "ceiling(x) is the smallest integer which is >= x."
, PrimAbs ==> "abs(x) is the absolute value of x. Also written |x|."
, PrimMin ==> "min(x,y) is the minimum of x and y, i.e. whichever is smaller."
, PrimMax ==> "max(x,y) is the maximum of x and y, i.e. whichever is larger."
, PrimUOp Not ==> "Logical negation: not(T) = F and not(F) = T."
, PrimBOp And ==> "Logical conjunction (and): T /\\ T = T; otherwise x /\\ y = F."
, PrimBOp Or ==> "Logical disjunction (or): F \\/ F = F; otherwise x \\/ y = T."
, PrimBOp Impl ==> "Logical implication (implies): T -> F = F; otherwise x -> y = T."
, PrimBOp Iff ==> "Biconditional (if and only if)."
, PrimBOp Eq ==> "Equality test. x == y is T if x and y are equal."
, PrimBOp Neq ==> "Inequality test. x /= y is T if x and y are unequal."
, PrimBOp Lt ==> "Less-than test. x < y is T if x is less than (but not equal to) y."
, PrimBOp Gt ==> "Greater-than test. x > y is T if x is greater than (but not equal to) y."
, PrimBOp Leq ==> "Less-than-or-equal test. x <= y is T if x is less than or equal to y."
, PrimBOp Geq ==> "Greater-than-or-equal test. x >= y is T if x is greater than or equal to y."
, PrimBOp CartProd ==> "Cartesian product, i.e. the collection of all pairs. Also works on bags and sets."
, PrimPower ==> "Power set, i.e. the set of all subsets. Also works on bags."
, PrimBOp Union ==> "Union of two sets (or bags)."
, PrimBOp Inter ==> "Intersection of two sets (or bags)."
, PrimBOp Diff ==> "Difference of two sets (or bags)."
]
-- | Lookup keys for documentation.
data DocKey where
PrimKey :: Prim -> DocKey
OtherKey :: String -> DocKey
deriving (Eq, Ord, Show)

-- | A map from some primitives to their corresponding page in the
-- Disco language reference
-- (https://disco-lang.readthedocs.io/en/latest/reference/index.html).
primReference :: Map Prim String
primReference =
M.fromList
[ PrimBOp Add ==> "addition"
, PrimBOp Sub ==> "subtraction"
, PrimBOp SSub ==> "subtraction"
, PrimBOp Mul ==> "multiplication"
, PrimBOp Div ==> "division"
, PrimBOp IDiv ==> "integerdiv"
, PrimBOp Mod ==> "mod"
, PrimBOp Exp ==> "exponentiation"
, PrimUOp Fact ==> "factorial"
, PrimFloor ==> "round"
, PrimCeil ==> "round"
, PrimAbs ==> "abs"
, PrimUOp Not ==> "logic-ops"
, PrimBOp And ==> "logic-ops"
, PrimBOp Or ==> "logic-ops"
, PrimBOp Impl ==> "logic-ops"
, PrimBOp Iff ==> "logic-ops"
, PrimBOp CartProd ==> "cp"
, PrimPower ==> "power"
, PrimBOp Union ==> "set-ops"
, PrimBOp Inter ==> "set-ops"
, PrimBOp Diff ==> "set-ops"
, PrimBOp Eq ==> "compare"
, PrimBOp Neq ==> "compare"
, PrimBOp Lt ==> "compare"
, PrimBOp Gt ==> "compare"
, PrimBOp Leq ==> "compare"
, PrimBOp Geq ==> "compare"
]
-- | An enumeration of different types of documentation references.
data RefType where
-- | A reference to the Gentle Introduction (https://disco-lang.readthedocs.io/en/latest/introduction/index.html)
Intro :: RefType
-- | A reference to the Language Reference (https://disco-lang.readthedocs.io/en/latest/reference/index.html)
Ref :: RefType
-- | An arbitrary free-form URL
URL :: RefType
deriving (Eq, Ord, Show, Read, Bounded, Enum)

otherDoc :: Map String String
otherDoc =
-- | A reference for further reading.
data Reference = Reference { refType :: RefType, ref :: String }
deriving (Eq, Ord, Show)

mkRef :: String -> Reference
mkRef = Reference Ref

mkIntro :: String -> Reference
mkIntro = Reference Intro

-- | A map storing documentation for various things that can be looked
-- up with :doc. Each key is mapped to a short descriptive string,
-- plus references for further reading.
docMap :: Map DocKey (String, [Reference])
docMap =
M.fromList
[ "N" ==> docN
, "" ==> docN
, "Nat" ==> docN
, "Natural" ==> docN
, "Z" ==> docZ
, "" ==> docZ
, "Int" ==> docZ
, "Integer" ==> docZ
, "F" ==> docF
, "𝔽" ==> docF
, "Frac" ==> docF
, "Fractional" ==> docF
, "Q" ==> docQ
, "" ==> docQ
, "Rational" ==> docQ
, "Bool" ==> docB
, "Boolean" ==> docB
, "Unit" ==> "The unit type, i.e. a type with only a single value."
, "Prop" ==> "The type of propositions."
, "Set" ==> "The type of finite sets."
, "|~|" ==> "Absolute value, or the size of a collection."
, "{?" ==> "{? ... ?} is a case expression, for choosing a result based on conditions."
[ PrimKey (PrimUOp Neg) ==>
"Arithmetic negation." ==>
[]
, PrimKey (PrimBOp Add) ==>
"The sum of two numbers, types, or graphs." ==>
[mkIntro "arithmetic", mkRef "addition"]
, PrimKey (PrimBOp Sub) ==>
"The difference of two numbers." ==>
[mkIntro "arithmetic", mkRef "subtraction"]
, PrimKey (PrimBOp SSub) ==>
"The difference of two numbers, with a lower bound of 0." ==>
[mkRef "subtraction"]
, PrimKey (PrimBOp Mul) ==>
"The product of two numbers, types, or graphs." ==>
[mkRef "multiplication"]
, PrimKey (PrimBOp Div) ==>
"Divide two numbers." ==>
[mkRef "division"]
, PrimKey (PrimBOp IDiv) ==>
"The integer quotient of two numbers, rounded down." ==>
[mkRef "integerdiv"]
, PrimKey (PrimBOp Mod) ==>
"a mod b is the remainder when a is divided by b." ==>
[mkRef "mod"]
, PrimKey (PrimBOp Exp) ==>
"Exponentiation. a ^ b is a raised to the b power." ==>
[mkRef "exponentiation"]
, PrimKey (PrimUOp Fact) ==>
"n! computes the factorial of n, that is, 1 * 2 * ... * n." ==>
[mkRef "factorial"]
, PrimKey (PrimFloor) ==>
"floor(x) is the largest integer which is <= x." ==>
[mkRef "round"]
, PrimKey (PrimCeil) ==>
"ceiling(x) is the smallest integer which is >= x." ==>
[mkRef "round"]
, PrimKey (PrimAbs) ==>
"abs(x) is the absolute value of x. Also written |x|." ==>
[mkRef "abs"]
, PrimKey (PrimMin) ==>
"min(x,y) is the minimum of x and y, i.e. whichever is smaller." ==>
[]
, PrimKey (PrimMax) ==>
"max(x,y) is the maximum of x and y, i.e. whichever is larger." ==>
[]
, PrimKey (PrimUOp Not) ==>
"Logical negation: not(T) = F and not(F) = T." ==>
[mkRef "logic-ops"]
, PrimKey (PrimBOp And) ==>
"Logical conjunction (and): T /\\ T = T; otherwise x /\\ y = F." ==>
[mkRef "logic-ops"]
, PrimKey (PrimBOp Or) ==>
"Logical disjunction (or): F \\/ F = F; otherwise x \\/ y = T." ==>
[mkRef "logic-ops"]
, PrimKey (PrimBOp Impl) ==>
"Logical implication (implies): T -> F = F; otherwise x -> y = T." ==>
[mkRef "logic-ops"]
, PrimKey (PrimBOp Iff) ==>
"Biconditional (if and only if)." ==>
[mkRef "logic-ops"]
, PrimKey (PrimBOp Eq) ==>
"Equality test. x == y is T if x and y are equal." ==>
[mkRef "compare"]
, PrimKey (PrimBOp Neq) ==>
"Inequality test. x /= y is T if x and y are unequal." ==>
[mkRef "compare"]
, PrimKey (PrimBOp Lt) ==>
"Less-than test. x < y is T if x is less than (but not equal to) y." ==>
[mkRef "compare"]
, PrimKey (PrimBOp Gt) ==>
"Greater-than test. x > y is T if x is greater than (but not equal to) y." ==>
[mkRef "compare"]
, PrimKey (PrimBOp Leq) ==>
"Less-than-or-equal test. x <= y is T if x is less than or equal to y." ==>
[mkRef "compare"]
, PrimKey (PrimBOp Geq) ==>
"Greater-than-or-equal test. x >= y is T if x is greater than or equal to y." ==>
[mkRef "compare"]
, PrimKey (PrimBOp CartProd) ==>
"Cartesian product, i.e. the collection of all pairs. Also works on bags and sets." ==>
[mkRef "cp"]
, PrimKey (PrimPower) ==>
"Power set, i.e. the set of all subsets. Also works on bags." ==>
[mkRef "power"]
, PrimKey (PrimBOp Union) ==>
"Union of two sets (or bags)." ==>
[mkRef "set-ops"]
, PrimKey (PrimBOp Inter) ==>
"Intersection of two sets (or bags)." ==>
[mkRef "set-ops"]
, PrimKey (PrimBOp Diff) ==>
"Difference of two sets (or bags)." ==>
[mkRef "set-ops"]
, OtherKey "N" ==>
docN ==>
[mkRef "natural"]
, OtherKey "" ==>
docN ==>
[mkRef "natural"]
, OtherKey "Nat" ==>
docN ==>
[mkRef "natural"]
, OtherKey "Natural" ==>
docN ==>
[mkRef "natural"]
, OtherKey "Z" ==>
docZ ==>
[mkRef "integer"]
, OtherKey "" ==>
docZ ==>
[mkRef "integer"]
, OtherKey "Int" ==>
docZ ==>
[mkRef "integer"]
, OtherKey "Integer" ==>
docZ ==>
[mkRef "integer"]
, OtherKey "F" ==>
docF ==>
[mkRef "fraction"]
, OtherKey "𝔽" ==>
docF ==>
[mkRef "fraction"]
, OtherKey "Frac" ==>
docF ==>
[mkRef "fraction"]
, OtherKey "Fractional" ==>
docF ==>
[mkRef "fraction"]
, OtherKey "Q" ==>
docQ ==>
[mkRef "rational"]
, OtherKey "" ==>
docQ ==>
[mkRef "rational"]
, OtherKey "Rational" ==>
docQ ==>
[mkRef "rational"]
, OtherKey "Bool" ==>
docB ==>
[mkRef "bool"]
, OtherKey "Boolean" ==>
docB ==>
[mkRef "bool"]
, OtherKey "Unit" ==>
"The unit type, i.e. a type with only a single value." ==>
[mkRef "unit"]
, OtherKey "Prop" ==>
"The type of propositions." ==>
[mkRef "prop"]
, OtherKey "Set" ==>
"The type of finite sets." ==>
[mkRef "set"]
, OtherKey "|~|" ==>
"Absolute value, or the size of a collection." ==>
[mkRef "size"]
, OtherKey "{?" ==>
"{? ... ?} is a case expression, for choosing a result based on conditions." ==>
[mkRef "case"]
]
where
docN = "The type of natural numbers: 0, 1, 2, ..."
docZ = "The type of integers: ..., -2, -1, 0, 1, 2, ..."
docF = "The type of fractional numbers p/q >= 0."
docQ = "The type of rational numbers p/q."
docB = "The type of Booleans (T or F)."

otherReference :: Map String String
otherReference =
M.fromList
[ "N" ==> "natural"
, "" ==> "natural"
, "Nat" ==> "natural"
, "Natural" ==> "natural"
, "Z" ==> "integer"
, "" ==> "integer"
, "Int" ==> "integer"
, "Integer" ==> "integer"
, "F" ==> "fraction"
, "𝔽" ==> "fraction"
, "Frac" ==> "fraction"
, "Fractional" ==> "fraction"
, "Q" ==> "rational"
, "" ==> "rational"
, "Rational" ==> "rational"
, "Bool" ==> "bool"
, "Boolean" ==> "bool"
, "Unit" ==> "unit"
, "Prop" ==> "prop"
, "Set" ==> "set"
, "|~|" ==> "size"
, "{?" ==> "case"
]
Loading

0 comments on commit 71bef60

Please sign in to comment.