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 ] : function* | A program consists of zero or more declarations (global variables) followed by zero or more 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. |
declarations | type name ( , type name )* | Each declaration is a type followed by a name. |
type | int | boolean | void | There are predefined types (int, boolean, void). Void is only used as a return type for functions. |
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 used iff 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 [ functionArgs ] | A reference typically evaluates to a specific "location" appropriate for storage or retrieval. |
functionArgs | ( [ expression ( , expression )* ] ) | Function arguments. |
expression | [ + | - | not ] term ( binaryOp term )* | An expression is 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 ) | inputValue | reference | A term is a literal, a parenthesized expression, an input value, or a reference. |
literal | integer | true | false | Unsigned integers (e.g., 123, 6, 44) and boolean constants. |
inputValue | readInt | This "value" is read from standard input; readInt expects an integer (initial blanks are ignored, an initial + or - is OK). |
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 |
|
expressions |
|
input |
|
predefined names |
|