Bali is designed to be reasonably simple to compile. The Bali language changes every semester.
We use the following notation throughout this document:
program | [declarations ] : (class | function)* | A program consists of zero or more declarations (global variables) followed by zero or more classes and/or functions. |
function | type name ( [declarations] ) : [ declarations ] : statement* end | A function has a return-type, a name, 0 or more parameters, and a body consisting of optional declarations (local variables) followed by zero or more statements. |
class | class name : [ declarations ] : function* endclass | A class has a name. To simplify Part 4, there is no inheritance. The class's body consists of declarations (i.e., fields) followed by zero or more methods (each method looks like a function). |
declarations | type name ( , type name )* | Each declaration is a type followed by a name. |
type | ( int | boolean | void | name ) [ [ ] ] | There are predefined types (int, boolean, and void) and user-defined types (i.e., classes). There are also corresponding array types (one-dimensional arrays, only). Note that it is a semantic error if void is used other than as a return type. |
statement | reference = expression ; | An assignment statement. |
reference ; | Function call (useful for side-effects). | |
if expression then statement* [ else statement*] endif | An if-statement has an optional else part. | |
loop statement* ( while | until ) expression ; statement* endloop | Looping. Note that there are two blocks of statements. The loop works by executing the first block, then checking the condition and possibly exiting the loop, then executing the second block. If the condition causes a loop-exit then the second block is not executed. After executing the second block the loop starts over again with the first block. Either statement-block in a loop can be empty or both blocks be nonempty. | |
return [ expression ] ; | Return statement. The type of the expression must match the return-type of the function. The no-expression version is semantically valid within a constructor or if the function's return-type is void. | |
print expression ( , expression )* ; | Print statement. Multiple expressions can be printed. Ideally, all are printed on a single line with a space between adjacent items, but this isn't possible with SaM-code. | |
reference | ( name | this ) modifier* | A reference typically evaluates to a specific "location" appropriate for storage or retrieval. Modifiers are evaluated left-to-right. Keyword this is only valid within a class method; this represents the current instance. If this is used as a function, it calls the constructor for this class. |
modifier | subscript | functionArgs | fieldRef | The modifiers for a reference. |
subscript | [ expression ] | A subscript. |
functionArgs | ( [ expression ( , expression )* ] ) | Function arguments. |
fieldRef | . name | Field reference. |
expression | [ + | - | not ] term ( binaryOp term )* | An expression is a a sequence of terms separated by binary operators. There can be an optional sign or boolean-negation in front of the first term of an expression; it is applied to the first term. Operators are evaluated left-to-right (i.e., no precedence rules). |
binaryOp | arithmeticOp | comparisonOp | booleanOp | The three kinds of binary operators. |
arithmeticOp | + | - | * | / | % | Operators for arithmetic. |
comparisonOp | < | <= | == | != | > | >= | Comparison operators. |
booleanOp | and | or | Boolean operators (both are short-circuiting). |
term | literal | ( expression ) | arrayValue | inputValue | reference | A term is a literal, a parenthesized expression, an array value, an input value, or a reference. |
literal | integer | true | false | null | Unsigned integers (e.g., 123, 6, 44), boolean constants, and the no-object indicator. |
arrayValue | type arrayElementList | An array value consists of a type indicator (all elements of the array must be of this type) followed by a list of elements. |
arrayElementList | { [ expression ( , expression )* ] } | The elements of the array. |
inputValue | readInt | These "values" are read from standard input; readInt expects an integer (initial blanks are ignored, an initial + or - is OK). |
name | Any token whose kind is 'w' (see the Scanner212 code). | Note that a keyword cannot be used as a name (because keywords are all kind 'K'). |
comments | Anything following a # on a line is considered to be a comment. This doesn't show up in the grammar above because it's handled by the scanner (Scanner212.java). |
keywords |
|
program |
|
main function |
|
declarations |
|
namespaces |
|
namespace rules for types |
|
functions |
|
parameters |
|
statements |
|
assignment statements |
|
expressions |
|
arrays |
|
input |
|
predefined names |
|
classes |
|
constructors |
|
this |
|