-
Notifications
You must be signed in to change notification settings - Fork 1
Language Reference
Andrew Elliot edited this page Aug 19, 2023
·
8 revisions
Some notes:
- we use
:=to denote a definition of a syntax item. - we use
{ ... }to mean there are 0 or more items. - we use
[ ... ]to mean there are 0 or 1 item. - we use
( ... )to group things together. - we use
" ... "to mean literal. - we use
`as another way to write literal. - we use
|to denote an alternation. - we use
(space) to denote a concatenation. - we use
*postfix operator to denote 0 or more items. - we use
+postfix operator to denote 1 or more items. - we use
?postfix operator to denote 0 or 1 item. - we use normal identifier to denote a definition of syntax.
- we use
< ... >to mean a special groups of syntax item. It is usually clear by context. - we use
a ... bto mean a sequence. e.g."1" ... "5"to mean("1"|"2"|"3"|"4"|"5"). - we use
//to mean a comment. - we use
#prefix operator to denote an external defined syntax item. This usually means you need to find definition ofpattern, in case you encounter a#pattern, in other place.
NOTE NOTE: Except note 12, ... in notes means meta syntax item. e.g. from [ ... ] and |, we
can have ["a"|"b"] to mean optional literal a or b in language syntax.
NOTE NOTE: Operators *, + and ? are all unary operator and attached to its preceding item.
// common identifier
name := ("_"|ASCII_alphabet) {"_"|ASCII_alphabet|digit}
literal := string | number | record | selector | variant | tuple
string := `"` <Unicode>* `"`
number := integer | floating
integer := digit+
floating := integer ["." integer]
record := "{" record_field {"," record_field} "}"
record_field := name "=" expression
tuple := "(" expression {"," expression} ")"
// these two acts like a function. see info in Intuition section.
variant := "`" name
selector := "." name
expression := name
| literal
| expression_group
| expression_type
| expression expression_annotation
| expression_let
| expression_lambda
expression_group := "(" expression ")
expression_type := "@" (#type_literal | #type_name | #type_quantifier | "(" #type ")")
expression_annotation := ":" #type
expression_let := "let" #pattern "=" expression "in" expression
expression_lambda := equation_line | equation_group
equation_line := "\" [name+ ";;"] #pattern {"," #pattern} "=" expression
equation_group := "[" [name+ ";;"] equation_branch {"|" equation_branch} "]"
equation_branch := pattern_group "=" expression {"|" pattern_group "=" expression }
pattern_group := pattern_sequel {"|" pattern_sequel}
pattern_sequel := #pattern {"," #pattern}
// common syntax item
ASCII_alphabet := ("a" ... "z")
| ("A" ... "Z")
digit := "0" ... "9"
<Unicode> is Unicode sequence. e.g. "中文" or emoji "😊" or latin "Ʀ"
- name:
name1,_name2,name_1_name3,___name4 - string and number literal:
"this is a string",32,23.2there is no escape token in string literal, we may add it later
- record:
{a = _a_name, b = 32},{ job = "student", age = 32 } - one line lambda:
\ ?a = a,\ 32 = "it is 32",\ a;; (?a : a) = a,\ ;; ?x, ?y = x + yoperator like
+has its own rule and acts like a syntax sugar. we introduce it in another section. - multi line lambda:
[ ?f, ?a = f a ][ 0 = "it is zero" | ?a = "it is number: " <> toString a ]-
[ 0 | 1 | 2 | 3 = "it is from 0 to 3" | _ = "number above 3" ]
- local let definition:
-
let ?a = 32 in a + 6 -
let ?name = "Polo";; ?age = 32 : int;; ?compute = [ ( ?x, ?y : int ), ?inc = (x, y + inc) ] in { name = name, age = age, count = compute
-