This document is a language specification (yet informal) of the kou programming language.
The syntax is specified using Extended Backus-Naur Form (EBNF).
| alternation
() grouping
[] option (0 or 1 times)
{} repetition (0 to n times)
Lower-case production names are used to identify lexical tokens. Non-terminals are in CamelCase. Lexical tokens are enclosed in double quotes "".
-> , ( ) [ ] { } : = ;
Unary:
unary_op = "+" | "-" | "!" .
Binary:
binary_op = rel_op | add_op | mul_op | bool_op .
rel_op = "==" | "!=" | "<" | "<=" | ">" | ">=" .
add_op = "+" | "-" | "|" | "^" .
mul_op = "*" | "/" | "%" | "&" .
bool_op = "||" | "&&" .
import as let fn if else for in new while break
Integer:
decimal_digit = "0" … "9" .
int_lit = decimal_digit { decimal_digit } .
Float:
decimals = decimal_digit { decimal_digit } .
float_lit = decimals "." [ decimals ]
| "." decimals
Char:
escaped_char = "\" ( "n" | "r" | "t" | "\" | "'" | """ ) .
char = unicode_char | escaped_char .
char_lit = "'" ( char ) "'"
String:
string_lit = """ { char } """ .
Boolean:
bool_lit = "true" | "false"
lower_letter = "a" … "z" .
letter = lower_letter | "_" .
ident = letter { letter | decimal_digit } .
Type = PrimType | FuncType | TupleType | ArrayType | VoidType .
PrimType = "int" | "float" | "str" | "bool" | "char" .
FuncType = Type "->" Type .
TupleType = "(" [ Type { "," Type } ] ")" .
Semantically, 1-tuple is the same with its inner type, or 1-tuple is desugared into its inner type.
Related: TupleExpr
ArrayType = "[" Type "]" .
Related: ArrayExpr
VoidType = "void" .
Void type does not have a value. Any actual value in the type of "void"
should result in a semantic error.
Each file in kou is represented as a module.
Module = { Import } { Decl } .
Import = "import" ImportPath
"(" ImportElem { "," ImportElem } ")" .
ImportPath = string_lit .
ImportElem = ident [ "as" ident ] .
Decl = "let" ident [ ":" Type ] "=" Expr .
Expr = PrimUnaryExpr | BinaryExpr .
BinaryExpr = Expr binary_op Expr .
PrimUnaryExpr = PrimExpr | UnaryExpr .
UnaryExpr = unary_op PrimUnaryExpr
PrimExpr = LitExpr
| IdentExpr
| TupleExpr
| ArrayExpr
| CallExpr
| FuncExpr
| CondExpr
| LoopExpr
| NewExpr.
Expr
stands for Expression.
The name stands for Literal Expression.
LitExpr = int_lit | float_lit | string_lit | bool_lit | char_lit .
The name stands for Identifier Expression.
IdentExpr = ident .
TupleExpr = "(" [ Expr { "," Expr } ] ")" .
Semantically, 1-tuple is the same with its inner value, or 1-tuple is desugared into its inner value.
Related: Tuple type
ArrayExpr = "[" Expr { "," Expr } "]"
Related: Array type
CallExpr = PrimExpr TupleExpr .
Related: TupleExpr
IndexExpr = PrimExpr "[" Expr "]" .
It can be used to retrieve an element from an array or a tuple.
For the tuple case, the index should be a LitExpr
having int_lit
, with a
value in the tuple's size range.
Related: Literals
FuncExpr = "fn" ParamTuple Type Block .
ParamTuple = "(" [ Param { "," Param } ] ")" .
Param = ident Type .
Related: Block
CondExpr = "if" Expr Block "else" Block .
Related: Block
LoopExpr = "while" Expr Block .
Related:
NewExpr = "new" Type "[" Expr "]" .
It creates an array with a specified size.
Related:
Assign = LVal "=" Expr .
LVal = IdentExpr
| IndexExpr .
Related:
Break = "break" .
Break only works in LoopExpr.
Related: LoopExpr
Block = "{" { ( Expr | Decl | Assign | Break ) ";" } [ Expr ] "}" .
A block ending without Expr
(no ";"
) has its return type as void
, and it
is the only way to express void
type in kou.
Related: Void type