Skip to main content

K# Syntax

General notes

Expression blocks

Using blocks is possible to divide the expression in many lines. The following lines should be have an indentation. All the lines within the same indentation offset are part of the same expression e.g

let sum = 
if condition then
trueExpr
else falseExpr
Note

Indentation can be spaces or tabs. More about indentation

Operator precedence and associativity

#OperatorAssociativity
12**left
11* / %left
10+ -left
9<< >>left
8< <= >= >left
7== !=left
6&left
5^left
4|left
3&&left
2||left
1$left
0.left

Grammar

Lexical tokens

Built-in Tokens

tokenDefinition
letterUnicode categories: lowercase, uppercase, titlecase
lowerCaseLetterUnicode lowercase character
upperCaseLetterUnicode uppercase character
digit0, 1, 2, 3, 4, 5, 6, 7, 8, 9
+Represent a normal indentation offset
?nRepresent a optional indentation offset using the startOffset of the next token
*Represent a repeating indentation offset
?Represent an optional indentation offset
|Represent a normal aligned indentation offset
whiteSpace" ", "\t"
operatorAny supported operator or custom operator
note

Each token can be separated by one or many <whiteSpace> tokens.

Keywords

  1. if
  2. then
  3. else
  4. let
  5. match
  6. with

Functions can't have as name:

  1. native
  2. internal
  3. pub
  4. impl
  5. trait
  6. type
  7. import

Tokens

<wordLetter> ::= <letter> | <digit> | "_"
<lowerCaseWord> ::= <lowerCaseLetter> <wordLetter>*
<upperCaseWord> ::= <upperCaseLetter> <wordLetter>*
<word> ::= <lowerCaseWord> | <upperCaseWord>
<functionName> ::= <lowerCaseWord> (<operator> <word>)+
| "if"
| "(" <operator> ")"
<character> ::= "'" <unicodeChar> "'"
<string> ::= "\"" <unicodeChar>+ "\""
<multiLineString> ::= "\"\"\"" <unicodeChar> "\"\"\""
<integer> ::= <digit>+
<hexInteger> ::= "0x" <hexDigit>+
<hexDigit> ::= <digit> | "a" | "b" | "c" | "d" | "e" | "f"
<octalInteger> ::= "0o" <octalDigit>+
<octalDigit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7"
<binaryInteger> ::= "0b" <binaryDigit>+
<binaryDigit> ::= "0" | "1"
<float> ::= <digit>+ "." <digit>+

Module

<module> ::= <import>
| <annotatedTopLevelExpression>

<annotatedTopLevelExpression> ::= <annotation>* <topLevelExpression>

<topLevelExpression> ::= <type>
| <trait>
| <typeDeclaration>
| <function>
| <traitImpl>
note

more about modules

Import

<import> ::= <+> "import" <moduleName> ("as" <key>)?
<key> ::= <lowerCaseWord>
<moduleName> ::= <lowerCaseWord> ("." <lowerCaseWord>)*

Annotations

<annotation> ::= "@" <+> <annotationName> <annotationParams>?

<annotationName> ::= <lowerCaseWord>
<annotationParams> ::= "(" ")"
| "(" <?> <annotationParam>+ ")"
<annotationParam> ::= <annotationParamName> "=" <annotationParamValue>
| <annotationParamValue>
<annotationParamName> ::= <lowerCaseWord> | <upperCaseWord> | <functionName>
<annotationParamValue> ::= <annotation>
| <array>
| <string>
| <multiLineString>
| <boolLiteral>
<array> ::= "[" <?> <annotationParamValue> ("," <annotationParamValue>)* "]"
<boolLiteral> ::= "True" | "False"
note

more about annotations

Type and Traits

<type> ::= <+> "internal"? "type" <typeName> "=" <typeExpression>
<trait> ::= <+> "internal"? "trait" <typeName> "=" <*> <traitFunction>+
<typeDeclaration> ::= <+> <functionName> <typeParam>* "=" <typeValue>

<typeName> ::= <upperCaseWord> <typeParam>*

<typeExpression> ::= <?> <typeValue> (<typeSetSeparator> <typeValue>)*
<traitFunction> ::= <functionName> "::" <?> <typeValue>

<typeValue> ::= <simpleType> (<typeValueSeparator> <typeValue>)?

<simpleType> ::= <label>? <typeValue>
| <label>? "(" <typeValue> ")"
| <label>? <typeVariable>

<typeVariable> ::= <typeConstructor>
| <typeParam>

<typeConstructor> ::= <upperCaseWord>
<typeParam> ::= <lowerCaseWord>
<label> ::= <lowerCaseWord> ":"

<typeSetOperator> ::= "|" | "&"
<typeValueOperator> ::= "->" | ","
note

more about type system

Traits Implementation

<traitImpl> ::= <+> "internal" "impl" <traitName> "for" <typeName> "=" <*> <implFunction>+
<traitName> ::= <upperCaseWord> <lowerCaseWord>
<typeName> ::= <upperCaseWord>

<implFunction> ::= <functionName> <+> <functionParams> "=" <expression>

Functions

<function> ::= <nativeFunction> | <normalFunction>
<nativeFunction> ::= "native" "pub"? <functionName> <+> <functionParams>

<normalFunction> ::= "pub"? <functionName> <+> <functionParams> "=" <expression>
<functionParams> ::= <lowerCaseWord>*
note

more about functions

Expressions

<expression> ::= <?n> <exprOperator0>
<exprOperator0> ::= <exprOperator1> <operator0> <exprOperator0>
<exprOperator1> ::= <exprOperator2> <operator1> <exprOperator1>
<exprOperator2> ::= <exprOperator3> <operator2> <exprOperator2>
<exprOperator3> ::= <exprOperator4> <operator3> <exprOperator3>
<exprOperator4> ::= <exprOperator5> <operator4> <exprOperator4>
<exprOperator5> ::= <exprOperator6> <operator5> <exprOperator5>
<exprOperator6> ::= <exprOperator7> <operator6> <exprOperator6>
<exprOperator7> ::= <exprOperator8> <operator7> <exprOperator7>
<exprOperator8> ::= <exprOperator9> <operator8> <exprOperator8>
<exprOperator9> ::= <exprOperator10> <operator9> <exprOperator9>
<exprOperator10> ::= <exprOperator11> <operator10> <exprOperator10>
<exprOperator11> ::= <exprOperator12> <operator11> <exprOperator11>
<exprOperator12> ::= <exprOperator> <operator12> <exprOperator12>
<exprOperator> ::= <exprValue> <operator> <exprOperator>

<exprValue> ::= "(" <expression> ")"
| <literal>
| <ifExpr>
| <letExpr>
| <matchExpr>
| <functionCall>
| <tupleExpr>

<literal> ::= <character>
| <string>
| <multiLineString>
| <integer>
| <hexInteger>
| <octalInteger>
| <binaryInteger>
| <float>
| <unit>
| <list>
| <set>
| <map>
| <binding>

<unit> ::= "()"
<list> ::= "[" <expression> ("," <expression>)* "]"
<set> ::= "#[" <expression> ("," <expression>)* "]"
<map> ::= "{" <entry> ("," <entry>)* "}"
<entry> ::= <exprValue> ":" <expression>

<binding> ::= <lowerCaseWord>
| <upperCaseWord>
| <functionName>
| <operatorFunctionName>
<operatorFunctionName> ::= "(" <operator> ")"

<ifExpr> ::= "if" <expression> "then" <expression> "else" <expression>
<letExpr> ::= <|> "let" <*> <letBinding>+ "then" <expression>
<matchExpr> ::= "match" <expression> "with" <*> <matchBranch>+
<letBinding> ::= <matchBinding> = <expression>
<matchBranch> ::= <matchBinding> "then" <expression>

<functionCall> ::= <functionName> <*> <functionCallParam>*
<functionCallParam> ::= "\n" <expression>
| <exprValue>
<tupleExpr> ::= <exprValue> ("," <exprValue>)+

Match Expressions

<matchBinding> ::= "(" <matchOrBinding> ")"
| <matchOrBinding>
<matchOrBinding> ::= <matchAndBinding> ("||" <matchOrBinding>)?
<matchAndBinding> ::= <binding> ("&&" <matchAndBinding>)?

<binding> ::= <varBinding>
| <typeBinding>
| <listBinding>
| <exprBinding>

<varBinding> ::= <lowerCaseWord>
<typeBinding> ::= <upperCaseWord> <typeBindingParam>
<typeBindingParam> ::= <varBinding>
| <exprValue>
<exprBinding> ::= <exprValue>
<listBinding> ::= "[" <exprValue> ("," <exprValue>)* "|" <varBinding> "]"
note