Bali Specifications for Part 3

CS 212 - Spring 2004

As discussed in lecture, we can specify a language in terms of its syntax (structural rules) and semantics (meaning). Although formal description methods exist for both kinds of specifications, we only formalize the Bali syntax. Bali's semantics are informally defined using English-language descriptions.

We use the following notation throughout this document:

Bali Syntax

Functions, Classes, and Methods
program  ->   function* There must be a 
main function
(see below)
function -> functionHeader functionBody
functionHeader -> ( type | void ) name ( [ parameters ] )
functionBody -> { variableDeclaration*
{
statement* }
Variable declarations
come before statements;
both are surrounded by
braces
type -> ( int | boolean) [ [ ] ] Integer, boolean, integer
array, or boolean array
parameters -> type name (, type name )* Parameters are
separated by commas
variableDeclaration -> type name ( , name )* ;

Statements
statement ->   return [ expression ] ;
statement -> { statement* }
statement -> if expression then statement 
[ else statement ]
statement -> while expression do statement
statement -> do statement while expression ;
statement -> expression ;
statement -> print expression ; Output
statement ->  ; Empty statement
statement -> target = expression ;
target -> name [ subscript ] Can assign to a variable
or an array element

Expressions
expression ->   expPart [ binaryOp expPart ] Single operator (no 
precedence necessary)
expPart -> unaryOp expPart
expPart -> literal
expPart -> ( expression ) Parenthesized expression
expPart -> name [ functionArgs | subscript ] Variable, function, or
subscripted variable
functionArgs -> ( [ expressionList ] ) Function arguments
expressionList -> expression ( , expression )*
subscript -> [ expression ] Array subscript
literal -> integer | true | false | null The various kinds 
of literals
binaryOp -> arithmeticOp | comparisionOp | booleanOp
arithmeticOp -> + | - | * /  | % % is mod (as in Java)
comparisonOp -> < | > | <= | >= | == | !=
booleanOp -> && |  | |  | ^ And (short circuiting),
or (short circuiting),
and xor
unaryOp ->  - | ! Unary minus, not

Tokens
name -> ( a-z | A-Z | _ ) ( a-z | A-Z | _ | 0-9 )*
Names are case sensitive.
integer -> Legal Java integers

Comments
  • Double slash // indicates that the remainder of the current line is a comment.
  • There are no multi-line comments.

Bali Semantics

program
  • All functions of a program must be in the same file.
  • Like Java, Bali relies on automatic garbage collection.
  • Running a program means that the program's main function is executed.
mainFunction
  • There must be a function called main that has an empty parameter list. It is a semantic error if this function does not exist.
  • The return type for the main function must be int.
  • This integer value appears as the exit code when the SaM Simulator halts.
function
  • The type of the expression in the return statement must match the type specified in the function header.
  • If you "fall off the end" of the function body (i.e., you execute the last statement and that statement is not a return statement) then a default return is automatically executed.  If appropriate, this default-return returns a value using the same default rules as for a variable declaration (i.e., 0 for int, false for boolean, null for an array).
  • Functions can be overloaded if the parameters specified in the function header differ by type or by number of parameters or by order of parameter types.  Overloaded functions with the same function name must all have the same return type.
  • The declared type (i.e., the type that can be determined from declarations within the program) for an argument of a function call must match the corresponding parameter type exactly.
  • Functions cannot be assigned to variables since there is no type that can be used to declare such a variable. 
parameters
  • Parameters pass by value.
  • Parameters are local to the current function scope.
variableDeclaration
  • Variables have default values : 0 for int, false for boolean, and null for an array..
  • Variables must be declared before use.
  • Variables are local to the current function scope.
statement
  • Expressions in if, while, and do-while statements must be of type boolean.
  • For assignment statements, the types of the left-hand and right-hand sides must match.
  • The syntax allows the following problematic construct.
    if expression then if expression then statement else statement
    The else should be matched with the closest if.  This rule could have been incorporated into the syntax, but it would have made the syntax more complicated.
  • Rudimentary output is available via the print statement.
expression
  • For all binary operators, the operands must be of the same type.
    • For logical operators (&&, | |, ^, !), operands must be of type boolean.
    • For arithmetic operators (+, -, *, /), operands must be of type int or of type float.  Division (/) is integer division when operands are of type int.
    • For the mod operator (%), operands must be of type int.
    • For the relational operators (<, <=, >, >=), operands must be of type int, char, or float.
    • The equality (==) and inequality (!=) operators both work with all types of values.  Two arrays are equal if and only if they are both the same object.
    • Bali does not support division by zero, NaN, or infinity.
arrays
  • When an array is declared, its initial value is null.
  • The expression type[size] creates an array of the given size. Each element of the array is set to the appropriate default value (see variableDeclaration, above).
predefined functions
  • Rudimentary input is available via readInt( ).  This function returns a value of type int.