For programs that are in the subset, the compiler should conform to the Ballerina Language Specification 2022R1.
- Only values allowed are of basic type nil, boolean, int, float, decimal, string, list, mapping, error and function.
- At module level
- function definitions
- no default arguments
- may be declared
public
- const definitions
- not of structured types
- type definitions
- function definitions
- Type descriptors:
- predefined basic type name:
boolean
,decimal
,error
,float
,int
,string
- nil type
()
- singletons of basic type boolean, int, float, decimal, string
any
typebyte
typeanydata
type- optional type:
T?
- unions:
T1|T2
- intersections:
T1&T2
- structure types
- map type:
map<T>
- array type:
T[]
- record types:
record { T1 f1; T2 f2; }
andrecord {| T1 f1; T2 f2; R...; |}
- tuple types:
[T1, T2]
and[T1, T2, R...]
- map type:
- function types
- bare function type:
function
- proper subtypes of
function
such as:function(T1) returns T2
- bare function type:
object
type- a reference to a type defined by a type definition
- predefined basic type name:
- Statements:
- function/method call statement
- local variable declaration with explicit type descriptor and initializer
- binding pattern is either an identifier or
_
- binding pattern is either an identifier or
- assignment
- assignment statement
L = E;
- compound assignment
L op= E;
- lvalues for fields
L.x
- lvalues for a list or mapping
L[E]
- assignment to wildcard binding pattern
_ = E;
- assignment statement
return
statementif
/else
statementswhile
statementbreak
andcontinue
statementsforeach
statements that use<..
match
statement with match patterns that are constpanic
statement
- Expressions:
- literals for nil, boolean, int, float and string
- binary operators:
+
,-
,*
,/
,%
,<
,<=
,>
,>=
,==
,!=
,===
,!==
,&
,^
,|
,<<
,>>
,>>>
,&&
,||
- unary operators:
-
,!
,~
- type cast
<T>E
- type test
E is T
,E !is T
- function call
- method call
v.f(args)
syntax for calling langlib functions - member access
E[i]
for both list and mapping - field access
E.f
- list constructor
[E1, E2, ..., En]
- mapping constructor
{ f1: E1, f2: E2,..., fn: En }
- error constructor
error(msg)
check
expressioncheckpanic
expression- anonymous function with explicit parameter types
function (T1 P1, T2 P2, ..., Tn Pn) { ... }
- Langlib functions:
array:length
array:push
string:length
map:length
int:toHexString
error:message
- Ballerina library functions:
io:println
This deals explicitly with operator precedence and associativity.
module-part = import-decl* module-defn*
import-decl = "import" [org-name "/"] module-name ["as" import-prefix] ";"
org-name = identifier
module-name =
identifier
| module-name "." identifier
import-prefix = identifier
module-defn = function-defn | const-defn | type-defn
function-defn = ["public"] "function" identifier signature stmt-block
signature = "(" [param-list] ")" [ "returns" type-desc ]
const-defn = ["public"] "const" [builtin-type-name] identifier "=" const-expr ";"
type-defn = ["public"] "type" identifier type-desc ";"
type-desc = union-type-desc
union-type-desc =
intersection-type-desc
| union-type-desc "|" intersection-type-desc
intersection-type-desc =
postfix-type-desc
| intersection-type-desc "&" postfix-type-desc
postfix-type-desc =
primary-type-desc
| optional-type-desc
| array-type-desc
optional-type-desc = postfix-type-desc "?"
array-type-desc := array-member-type-desc array-dimension+
array-dimension := "[" [ array-length ] "]"
array-member-type-desc := type-desc *but not* array-type-desc
array-length :=
int-literal
| constant-reference-expr
primary-type-desc =
builtin-type-name
| nil-type-desc
| singleton-type-desc
| "(" type-desc ")"
| type-reference
| map-type-desc
| record-type-desc
| tuple-type-desc
| function-type-desc
| object-type-desc
builtin-type-name = "any" | "anydata" | "boolean" | "byte" | "int" | "float" | "string" | "error" | "function"
nil-type-desc = nil-literal
singleton-type-desc = simple-const-expr
# reference to a type definition
type-reference = identifier | qualified-identifier
map-type-desc = "map" "<" type-desc ">"
record-type-desc = inclusive-record-type-desc | exclusive-record-type-desc
inclusive-record-type-desc = "record" "{" field-desc* "}"
exclusive-record-type-desc = "record" "{|" field-desc* [rest-field-desc] "|}"
field-desc = type-desc identifier ";"
rest-field-desc = type-desc "..." ";"
tuple-type-desc = "[" tuple-member-type-desc-list "]"
tuple-member-type-desc-list =
type-desc ("," type-desc)* ["," tuple-rest-desc]
| [ tuple-rest-desc ]
tuple-rest-desc = type-desc "..."
function-type-desc = "function" signature
param-list = param ["," param]* ["," rest-param]
param = type-desc [identifier] # identifier can only be omitted when occurring in function-type-desc
rest-param = type-desc "..." identifier
object-type-desc = "object" "{" object-member-desc* "}"
object-member-desc = object-field-desc | method-decl
object-field-desc = "public" type-desc identifier ";"
method-decl = "public" "function" method-name signature ";"
method-name = identifier | special-method-name
special-method-name = "map" | "join" | "start"
stmt-block = "{" statement* "}"
statement =
local-var-decl-stmt
| call-stmt
| assign-stmt
| compound-assign-stmt
| destructuring-assign-stmt
| return-stmt
| if-else-stmt
| while-stmt
| break-stmt
| continue-stmt
| foreach-stmt
| panic-stmt
| match-stmt
local-var-decl-stmt = ["final"] type-desc binding-pattern "=" expression ";"
binding-pattern = identifier | wildcard-binding-pattern
call-stmt = call-expr ";"
call-expr =
function-call-expr
| method-call-expr
| checking-keyword call-expr
assign-stmt = lvexpr "=" expression ";"
compound-assign-stmt = lvexpr CompoundAssignmentOperator expression ";"
destructuring-assign-stmt = wildcard-binding-pattern "=" expression ";"
wildcard-binding-pattern = "_"
lvexpr =
variable-reference-lvexpr
| field-access-lvexpr
| member-access-lvexpr
variable-reference-lvexpr = identifier
field-access-lvexpr =lvexpr "." identifier
member-access-lvexpr = lvexpr "[" expression "]"
return-stmt = "return" [expression] ";"
if-else-stmt = "if" expression stmt-block ["else" (if-else-stmt | stmt-block)]
while-stmt = "while" expression stmt-block
break-stmt = "break" ";"
continue-stmt = "continue" ";"
foreach-stmt = "foreach" "int" identifier "in" additive-expr "..<" additive-expr stmt-block
panic-stmt = "panic" expression ";"
match-stmt = "match" expression "{" match-clause+ "}"
match-clause = match-pattern-list "=>" stmt-block
match-pattern-list =
match-pattern
| match-pattern-list "|" match-pattern
match-pattern =
"_"
| simple-const-expr
simple-const-expr =
literal
| "-" int-literal
| "-" floating-point-literal
| const-reference-expr
expression = logical-or-expr
const-expr = logical-or-expr # must also satisfy restrictions of const-expr as in Ballerina language spec
const-reference-expr = identifier | qualified-identifier # must refer to something defined with a const-decl
expression = logical-or-expr
logical-or-expr =
logical-and-expr
| logical-or-expr "||" logical-and-expr
logical-and-expr =
bitwise-or-expr
| logical-and-expr "&&" bitwise-or-expr
bitwise-or-expr =
bitwise-xor-expr
| bitwise-or-expr "|" bitwise-xor-expr
bitwise-xor-expr =
bitwise-and-expr
| bitwise-xor-expr "^" bitwise-and-expr
bitwise-and-expr =
equality-expr
| bitwise-and-expr "&" equality-expr
equality-expr =
relational-expr
| equality-expr "==" relational-expr
| equality-expr "!=" relational-expr
| equality-expr "===" relational-expr
| equality-expr "!==" relational-expr
relational-expr =
shift-expr
| shift-expr "<" shift-expr
| shift-expr "<=" shift-expr
| shift-expr ">" shift-expr
| shift-expr ">=" shift-expr
| shift-expr ["!"] "is" type-desc
shift-expr =
additive-expr
| shift-expr "<<" additive-expr
| shift-expr ">>" additive-expr
| shift-expr ">>>" additive-expr
additive-expr =
multiplicative-expr
| additive-expr "+" multiplicative-expr
| additive-expr "-" multiplicative-expr
multiplicative-expr =
unary-expr
| multiplicative-expr "*" unary-expr
| multiplicative-expr "/" unary-expr
| multiplicative-expr "%" unary-expr
unary-expr =
primary-expr
| "-" unary-expr
| "~" unary-expr
| type-cast-expr
| checking-expr
type-cast-expr = "<" type-desc ">" unary-expr
checking-expr = checking-keyword unary-expr
checking-keyword = "check" | "checkpanic"
primary-expr =
literal
| error-constructor-expr
| member-access-expr
| field-access-expr
| function-call-expr
| method-call-expr
| variable-reference-expr
| list-constructor-expr
| mapping-constructor-expr
| explicit-anonymous-function-expr
| "(" expression ")"
literal = nil-literal | boolean-literal | int-literal | floating-point-literal | string-literal
nil-literal = "(" ")" | "null"
boolean-literal = "true" | "false"
error-constructor-expr = "error" "(" expression ")"
list-constructor-expr = "[" [expr-list] "]"
expr-list = expression ["," expression ]*
mapping-constructor-expr = "{" [field-list] "}"
field-list = field ["," field ]*
field = field-name ":" expression
field-name = string-literal | identifier
explicit-anonymous-function-expr = "function" signature stmt-block
member-access-expr = primary-expr "[" expression "]"
field-access-expr = primary-expr "." identifier
function-call-expr = function-reference arg-list
method-call-expr = primary-expr "." identifier arg-list
arg-list = "(" [expr-list] ")"
function-reference = identifier | qualified-identifier
qualified-identifier = module-prefix ":" identifier
module-prefix = identifier
variable-reference-expr = identifier | qualified-identifier # can refer to parameter, local variable or constant
// tokens
int-literal = (as in Ballerina language spec)
floating-point-literal = (as in Ballerina spec, except HexFloatingPointLiteral is not allowed)
string-literal = (as in Ballerina language spec)
identifier = [A-Za-z][A-Za-z0-9_]*
CompoundAssignmentOperator = (as in Ballerina language spec)
// comments starting with // allowed as in Ballerina language spec
Language spec syntax references:
There are the following additional restrictions:
- member access
s[i]
is not supported whens
has typestring
- relational operators are not supported when the static type of either of the operands includes nil
Method call syntax can be used for calling the following langlib functions:
array:length
array:push
string:length
map:length
int:toHexString
error:message
Two kinds of import
are supported.
- An import with an organization of
ballerina
is allowed with the following restrictions- only
ballerina/io
can be imported - the only function from
ballerina/io
that can be called isprintln
println
only accepts a single argument (which is of typeany
)
- only
- An import with no organization and with a module name starting with
root
. Animport root.X;
in a fileF.bal
will read the module from the filesF.modules/X/*.bal
.
list-constructor-expr
andmapping-constructor-expr
are not allowed within aconst-expr
.- Types in type definitions are restricted semantically, rather than syntactically: a type definition that is referenced from a function definition must define a type that is equivalent to one that can be described using the type-defn grammar in this document. It must also match the type-defn grammar supported for semantic type-checking.
- After a variable is captured, its type can no longer be narrowed (e.g. by a type test) unless the variable is final.
- Add support for
function
values - Add support for anonymous functions
- Add support for
object
type descriptors with restrictions
- #1024 - decimal values must not use hexadecimal literals