bricks-syntax-0.0.0.4: ...

Bricks.Expression

Synopsis

# Expressions

Constructors

 Expr'Var Var A variable, such as x Expr'Str Str'Dynamic A string, quoted in the traditional form using a single double-quote (" ... ") Expr'Str'Indented InStr A string in "indented string" form, using two single-quotes ('' ... '') Expr'List List A list is an ordered collection of expressions. Expr'Dict Dict A dict is an unordered enumerated mapping from strings. Expr'Dot Dot A dot expression (named after the . character it contains) looks up the value at a particular key in a dict. Expr'Lambda Lambda A lambda expression x: y where x is the parameter. Expr'Apply Apply The application of a function to a single argument. Expr'Let Let A let-in expression consists of a list of variable bindings followed by an expression.

Instances

 Source # This instance is designed for doctests and REPL experimentation. The format is designed to strike a balance in verbosity between the derived Show implementations (which are unwieldily long) and the Bricks language itself (which is quite terse but unsuitable for demonstrating the parser, as outputting a Bricks rendering of parse result wouldn't illumunate anyone's understanding of the AST that the Show instances are here to depict). MethodsshowList :: [Expression] -> ShowS #

# Variables

data Var Source #

A variable x, as in the lambda calculus sense, is in one of two positions:

1. A binding, which may take a number of forms: - x: ... (Param'Name) - let x = ... ; in ... (LetBinding'Eq) - let inherit ( ... ) x; in ... (LetBinding'Inhherit)
2. A contextual reference to a lambda head or let binding in which x is bound: - The expression x by itself - An inherit binding in a dict expression (DictBinding'Inherit'Var)

#### Syntax

Variables are always written without quotes.

Unquoted strings are used for variables (Expr'Var) and places that bind variables (Lambda and Let).

Constructors

 Var Fields

Instances

 Source # MethodsshowsPrec :: Int -> Var -> ShowS #show :: Var -> String #showList :: [Var] -> ShowS #

# Static strings

A fixed string value. We use the description "static" to mean the string may not contain antiquotation, in contrast with Str'Dynamic which can.

Constructors

 Str'Static Fields

Instances

 Source # MethodsshowList :: [Str'Static] -> ShowS # Source # Methodsstimes :: Integral b => b -> Str'Static -> Str'Static #

# Dynamic strings

A dynamic string is a quoted string expression, which may be a simple string like "hello" or a more complex string containing antiquotation like "Hello, my name is ${name}!". See Expr'Str. We use the description "dynamic" to mean the string may contain antiquotation, in contrast with Str'Static which cannot. This is the type of string expressions (Expr'Str). #### String syntax A string may be quoted either in the traditional form using a single double-quote (" ... "): "one\ntwo" or in the "indented string" form using two single-quotes ('' ... ''): '' one two '' Both of these examples reduce to the same value, because leading whitespace is stripped from indented strings. Either may contain "antiquotation" (also known as "string interpolation") to conveniently concatenate string-valued variables into the string. "Hello, my name is${name}!"

Normal strings may contain the following escape sequences:

• \\\
• \""
• \${${
• \n → newline
• \r → carriage return
• \t → tab

The indented string form does not interpret any escape sequences.

Constructors

 Str'Dynamic Fields

Instances

 Source # MethodsshowList :: [Str'Dynamic] -> ShowS # Source # Methodsstimes :: Integral b => b -> Str'Dynamic -> Str'Dynamic #

data Str'1 Source #

One part of a Str'Dynamic.

Constructors

 Str'1'Literal Str'Static Str'1'Antiquote Expression

Instances

 Source # MethodsshowsPrec :: Int -> Str'1 -> ShowS #show :: Str'1 -> String #showList :: [Str'1] -> ShowS #

Simplify a dynamic string by combining consecutive pieces of static text.

#### Examples

>>> :{
>>> str :: Text -> Str'1
>>> str x = Str'1'Literal $Str'Static x Nothing >>>  >>> var :: Text -> Str'1 >>> var x = Str'1'Antiquote . Expr'Var$
>>> Var (unquotedString'orThrow x) Nothing
>>> :}

>>> :{
>>> str'dynamic'normalize $Str'Dynamic (Seq.fromList >>> [str "a", str "b", var "x", var "y", str "c", str "d"]) Nothing >>> :} str ["ab", antiquote (var "x"), antiquote (var "y"), "cd"]  #### Examples >>> str'dynamic'to'static$ Str'Dynamic (Seq.fromList []) Nothing
Just ""

>>> a = Str'1'Literal (Str'Static "hi" Nothing)

>>> b = Str'1'Antiquote $Expr'Var$ Var (unquotedString'orThrow "x") Nothing

>>> str'dynamic'to'static $Str'Dynamic (Seq.fromList [ a ]) Nothing Just "hi"  >>> str'dynamic'to'static$ Str'Dynamic (Seq.fromList [ a, b ]) Nothing
Nothing


# Indented string

data InStr Source #

An "indented string literal," delimited by two single-quotes ''.

This type of literal is called "indented" because the parser automatically removes leading whitespace from the string (inStr'dedent), which makes it convenient to use these literals for multi-line strings within an indented expression without the whitespace from indentation ending up as part of the string.

Constructors

 InStr Fields

Instances

 Source # MethodsshowsPrec :: Int -> InStr -> ShowS #show :: InStr -> String #showList :: [InStr] -> ShowS #

Determine how many characters of whitespace to strip from an indented string.

Determine the minimum indentation of any nonempty line, and remove that many space characters from the front of every line.

Remove any empty lines from the beginning or end of an indented string, and remove the newline from the final nonempty line.

# Single line of an indented string

data InStr'1 Source #

One line of an InStr.

Constructors

 InStr'1 FieldsinStr'1'level :: NaturalThe number of leading space characters. We store this separately for easier implementation of inStr'dedent.inStr'1'indentSource :: Maybe SourceRangeThe source position of the leading space charactersinStr'1'str :: Seq Str'1The meat of the line, after any leading spaces and before the line break.inStr'1'lineBreak :: Maybe Str'StaticThe line break at the end, if any; all lines but the last one should have a line break

Instances

 Source # MethodsshowList :: [InStr'1] -> ShowS #

# Lists

data List Source #

A list is an ordered collection.

#### Syntax

A list expression (Expr'List) starts with [, ends with ], and contains any number of expressions in between.

The empty list:

[ ]

A list containing three variables:

[ a b c ]

Lambdas, function applications, let-in expressions, and with expressions must be parenthesized when in a list.

[
(x: f x y)
(g y)
(let a = y; in f a a)
(with d; f x a)
]

Constructors

 List Fields

Instances

 Source # MethodsshowsPrec :: Int -> List -> ShowS #show :: List -> String #showList :: [List] -> ShowS #

# Dicts

data Dict Source #

A dict is an unordered enumerated mapping from strings.

#### Syntax

A dict expression (Expr'Dict) starts with { or rec {, ends with }, and contains any number of DictBindings in between.

The empty dict (with no bindings):

{ }

A dict with two bindings:

{
a = "one";
b = "one two";
}

By default, dict bindings cannot refer to each other. For that, you need the rec keyword to create a recursive dict.

rec {
a = "one";
b = "${a} two"; } In either case, the order of the bindings does not matter. The left-hand side of a dict binding may be a quoted string (in the traditional " ... " style, not the indented-string '' style), which make it possible for them to be strings that otherwise couldn't be expressed unquoted, such as strings containing spaces: { "a b" = "c"; } The left-hand side of a dict may even be an arbitrary expression, using the ${ ... } form:

{ a = "Z"; }.${ let b = "a"; in b } Constructors  Dot Fields Instances  Source # MethodsshowsPrec :: Int -> Dot -> ShowS #show :: Dot -> String #showList :: [Dot] -> ShowS # Arguments  :: Expression Dict -> [Expression] Lookups -> Expression Dot expression # Lambdas data Lambda Source # A function expressed as a lambda abstraction. #### Syntax A lambda expression (Expr'Lambda) has the form x: y where x is the function parameter to bind in the function body y. This is a function that turns a name into a greeting: name: "Hello,${name}!"

The function parameter can also be a dict pattern, which looks like this:

{ a, b, c ? "another" }: "Hello, ${a},${b}, and ${c}!" That function accepts a dict and looks up the keys a, b, and c from it, applying the default value "another" to c if it is not present in the dict. Dict patterns therefore give us something that resembles functions with named parameters and default arguments. By default, a lambda defined with a dict pattern fails to evaluate if the dict argument contains keys that are not listed in the pattern. To prevent it from failing, you can end the pattern with  ... : ({ a, ... }: x) { a = "1"; b = "2"; } Every function has a single parameter. If you need multiple parameters, you have to curry: a: b: [ a b ] Constructors  Lambda Fieldslambda'head :: ParamDeclaration of the function's parameterlambda'body :: ExpressionBody of the function; what it evaluates tolambda'source :: Maybe SourceRange Instances  Source # MethodsshowsPrec :: Int -> Lambda -> ShowS #showList :: [Lambda] -> ShowS # # Function parameters data Param Source # A parameter to a Lambda. All functions have a single parameter, but it's more complicated than that because it may also include dict destructuring. Constructors  Param'Name Var A simple single-parameter function Param'DictPattern DictPattern Dict destructuring, which gives you something resembling multiple named parameters with default values Param'Both Var DictPattern Both a param name and a dict pattern, separated by the @ keyword Instances  Source # MethodsshowsPrec :: Int -> Param -> ShowS #show :: Param -> String #showList :: [Param] -> ShowS # A type of function parameter (Param) that does dict destructuring. Constructors  DictPattern FieldsdictPattern'items :: Seq DictPattern'1The list of keys to pull out of the dict, along with any default value each may havedictPattern'ellipsis :: BoolWhether to allow additional keys beyond what is listed in the items, corresponding to the ... keyword Instances  Source # MethodsshowList :: [DictPattern] -> ShowS # One item within a DictPattern. Constructors  DictPattern'1 FieldsdictPattern'1'name :: VarThe name of the key to pull out of the dictdictPattern'1'default :: Maybe ExpressionThe default value to be used if the key is not present in the dict Instances  Source # MethodsshowList :: [DictPattern'1] -> ShowS # # Function application data Apply Source # The application of a function to a single argument. #### Syntax An function application expression (Expr'Apply) looks like this: f x If a function has multiple (curried) parameters, you can chain them together like so: f x y z Constructors  Apply Fieldsapply'func :: ExpressionThe function being calledapply'arg :: ExpressionThe argument to the functionapply'source :: Maybe SourceRange Instances  Source # MethodsshowsPrec :: Int -> Apply -> ShowS #show :: Apply -> String #showList :: [Apply] -> ShowS # Arguments  :: Expression Function -> [Expression] Args -> Expression Function application # let data Let Source # #### Syntax A let-in expression (Expr'Let) looks like this: let greet = x: "Hello,${x}!";
name = "Chris";
in
greet name

Let bindings, like dict bindings, may also use the inherit keyword.

let
d = { greet = x: "Hello, \${x}!"; name = "Chris"; }
inherit (d) greet name;
in
greet name

The previous example also demonstrates how the bindings in a let expression may refer to each other (much like a dict with the rec keyword). As with dicts, the order of the bindings does not matter.

Constructors

 Let Fieldslet'bindings :: Seq LetBindingThe bindings (everything between the let and in keywords)let'value :: ExpressionThe value (everything after the in keyword)let'source :: Maybe SourceRange

Instances

 Source # MethodsshowsPrec :: Int -> Let -> ShowS #show :: Let -> String #showList :: [Let] -> ShowS #

A semicolon-terminated binding within the binding list of a Let expression.

Constructors

 LetBinding'Eq Var Expression A binding with an equals sign, of the form x = y; LetBinding'Inherit Expression (Seq Var) A binding using the inherit keyword, of the form inherit (x) a b;

Instances

 Source # MethodsshowList :: [LetBinding] -> ShowS #