Surface Syntax¶
Note
As described in #324, we are in the progress of revising the surface syntax; it’s subject to change in near future.
Lexical Syntax¶
The basic lexical items in Cogent are comments (including documentation blocks and pragmas), identifiers (including reserved words), symbols and literals. Additionally, in a Cogent program, many C preprocessor directives can be used.
Comments¶
Comments have the same form as in Haskell:
a comment may either be a single-line comment
starting with the symbol --
and ending at the end of the line,
or it may be a block comment
enclosed in {- and -}.
Block comments may occur in Cogent source between all other lexical entities. Block comments can nest: the closing brace of the inner comment does not end an outer comment.
Some examples of comments are:
f: U8 -> U8 -- this is a line comment after a function signature
f x {- x is the function argument -} = x+1
-- function f returns its incremented argument
{- This is a comment with a nested {- inner comment. -}
After it the outer comment continues. -}
A special form of comments are document blocks.
They have a similar form to line comments,
but start with the symbol @.
Document blocks can be used
to generate HTML documentation
from Cogent source using Docgent:
@@ # Heading
@@ This is a standalone documentation block
@ Documentation for the following function
f: U8 -> U8
f x = x+1
Another special form of comments are pragmas, which have the form:
{-# ... #-}
Pragmas are used to optimise Cogent programs, and to interface external C components. The details of pragmas are not (yet?) covered by this manual.
Todo
(jashankj, 2020-09-17): add pragma documentation somewhere
Identifiers¶
Identifiers are used to name items in a program. As usual in programming languages, they consist of a sequence of letters and digits, beginning with a letter.
Cogent syntactically distinguishes between lowercase identifiers and capitalized identifiers:
- LowercaseID: informally,
a sequence of letters, digits, underscore symbols, and single quotesstarting with a lowercase letter- CapitalizedID: informally,
a sequence of letters, digits, underscore symbols, and single quotesstarting with an uppercase letter
The single quote, ', may appear in an identifier
anywhere except at the beginning.
The underscore, _, may appear in an identifier
anywhere except the beginning and end.
Examples for valid identifiers are
v1, very_long_identifier,
CamelCase, T, W_h_y,
and v'.
Lowercase identifiers are used for record field names, and for term variables and type variables. Capitalized identifiers are used for type constructors and data constructors.
There are some reserved words in Cogent, which syntactically are identifiers, but cannot be used as identifiers. The reserved words are, in alphabetical order:
all and at complement else if in include inline layout let not o
pointer put rec record take then type upcast variant True False
array map2 @put @take
Todo
(jashankj, 2020-09-17): where did end and repr go?
Literals¶
There are four kinds of literals in Cogent.
Boolean Literals¶
The Boolean literals are the reserved words True and False.
- BooleanLiteral: one of
TrueFalse
The type of a Boolean literal is Bool.
Integer Literals¶
Integer literals are digit sequences. They can be written in decimal, hexadecimal, or octal form.
- IntegerLiteral: one of
DecDigits0xHexDigits0XHexDigits0oOctDigits0OOctDigits- DecDigits: informally,
a sequence of decimal digits 0-9.- HexDigits: informally,
a sequence of hexadecimal digits 0-9, A-F.- OctDigits: informally,
a sequence of octal digits 0-7.
Todo
(jashankj, 2020-02-14): what type have int literals?
Character Literals¶
A character literal consists of a quoted character.
- CharacterLiteral: informally,
a character enclosed in single quotes.
The type of a character literal is U8,
corresponding to a single eight-bit byte.
Syntactically,
a character literal can be specified as in Haskell
(see the Haskell Report),
i.e., full Unicode and several escape sequences (such as \n) are supported.
However, a valid character literal in Cogent
must always correspond to a code value in the range 0..255.
Examples for valid character literals are 'h', '8', and '/'.
The quoted character '\300' is not a legal character literal,
since it is mapped to octal 0o300 (decimal 192).
Todo
(jashankj, 2020-02-14): uh, that octal 300 is probably ok?
String Literals¶
A string literal consists of a quoted character sequence.
- StringLiteral: informally,
a sequence of characters enclosed in double quotes.
Syntactically, a string literal can be specified as in Haskell — again, see the Haskell Report. As with character literals, escape sequences are supported for specifying every character. For a valid Cogent string literal, every character must be mapped to a code in the range 0..255.
An example for a valid string literal is
the string "This is a string literal\n".
Again, the string "String containing a \300 glyph" is not legal,
since it contains a character mapped to code 0o300.
Todo
(jashankj, 2020-02-14): sensible octal literal in a string?