For this assignment, you are to complete an interpreter for a subset of the SILLY (Simple, Interpreted, Limited Language for
You) programming language. Recall that the syntax rules for SILLY v. 20 were provided in HW1.
To keep the interpreter simple, it assumed that there is whitespace (spaces, tabs and/or blank lines) between individual tokens in the language. There can be no spaces between the characters in an identifier, integer, or string, however. The SILLY language is case-sensitive, so variables a
and A
are considered unique.
There are three data types in SILLY: integer, string, and Boolean. Every variable must be declared before it can be used, and the language is strongly typed. Each variable is given a type when declared and can only be assigned values of that type. Assigning a value of the incorrect type should result in a run-time error.
There are a number of operators in SILLY for building expressions, as listed below:
DESCRIPTION OPERATOR(S) OPERAND(S) EXAMPLE ------------------------ ----------- ------------------------------- --------------------------- standard math operations + - * / % applied to 2 integers 4 * 7 → 28 string concatenation + applied to 2 strings "foo" + "bar" → "foobar" string length #chars applied to a string #chars "foo" → 3 string indexing @index applied to a string and integer "foo" @index 0 → "f" Boolean negation not applied to a Boolean not true → false Boolean connectives and or applied to 2 Booleans true or false → true comparison operators == != < > <= >= applied to two value of same type 3 <= 4 → true4>
Note that the '+' operator can be applied to two numbers (addition) or to two strings (concatenation). The comparison operators can be applied to any two values of the same type. Integers are ordered numerically (e.g., 2 < 3); strings are ordered alphabetically (e.g., "bar" < "foo"); and Booleans are ordered truthfully (e.g., false < true). Any type mismatch within an expression (e.g., applying the '*' operator to two string values or comparing values of different types) should result in a run-time error with a descriptive message.
SILLY provides a number of different statement types: variable declaration, assignment, output statement, compound statement, if statement, while loop, and repeat loop. Simple subroutines (with typed parameters and no return value) can also be declared and called (more detail in a later assignment).
SAMPLE CODE (output in red) >>> int num = 99 ; >>> output num ; 99 >>> int expr1 = ( 10 * 2 ) + 1 ; >>> int expr2 = 1 + ( 10 * 2 ) ; >>> output expr1 == expr2 ; true >>> str w1 = "foo" ; >>> output w1 ; foo >>> boo flag = true ; >>> output flag ; true >>> output "foo" != "foo" ; false >>> output 3 > 2 ; true >>> boo test = "smith" < "smooth" ; >>> output test ; true >>> repeat 3 { output "Hello" ; } Hello Hello Hello >>> int count = 4 ; while count > 0 { output count ; count = ( count - 1 ) ; } 4 3 2 1 >>> str word = "banana" ; >>> str reverse = "" ; >>> int i = 0 ; >>> while i < ( #chars word ) { reverse = ( word @index i ) + reverse ; i = i + 1 ; } >>> output reverse ; ananab >>> boo check = true ; >>> boo opp = not check ; >>> output opp ; false >>> output ( check and opp ) , ( check or opp ) ; false true >>> if ( not ( check and opp ) ) { output "one" ; output ; output "two" ; } else { output "three" ; output ; output "four" ; } one two >>> int blen = #chars "banana" ; >>> if blen < 5 { } else { output "long" ; } long >>> int num = 6 ; >>> output "Hailstone" , "sequence" , "from" , num ; Hailstone sequence from 6 >>> while num != 1 { if ( num % 2 ) == 0 { num = num / 2 ; } else { num = ( 3 * num ) + 1 ; } output num ; } 3 10 5 16 8 4 2 1
An incomplete version of the SILLY interpreter is provided for you via the following classes/files:
Token.java
,TokenStream.java
: These classes define the different types of tokens that make up the language, and define an input stream for reading in program tokens.Interpreter.java
: This is the main interpreter class for the language, which runs an infinite loop to read and execute statements entered at the keyboard.MemorySpace.java
: This class defines the memory space for storing variables and their values. Integer and Boolean values are stored directly in the stack segment, while string values are stored in the heap.Statement.java
: This abstract class provides the framework for all types of statements and includes a general-purpose method for reading a statement.VarDeclaration.java
,Assignment.java
,Output.java
,Compound.java
,Repeat.java
,While.java
: These classes, derived fromStatement
, define specific statements of the SILLY language.DataValue.java
,IntegerValue.java
,StringValue.java
,BooleanValue.java
: This interface and implementing classes define the types of values that can be stored in SILLY.Expression.java
,Term.java
: These interacting classes define an expression, which is either a simple term (integer, string, Boolean, or identifier), an expression involving operators, or a parenthesized expression.
As provided, the interpreter runs a subset of the SILLY language. Variable declarations, assignments and output statements are implemented, although output statements are currently limited to displaying only a single value (instead of an arbitrary sequence of comma-separated values). Repeat and while loops are implemented, but if statements are not. The three data types (numbers, strings and Booleans) are implemented, as are most of the operators that can be used in expressions. Missing are the Boolean operators (not
, and
and or
). So, you should be able to test the interpreter out on basic statements (such as in the left column above). Statements in the right column depend on language features that you will be implementing in this assignment.
For this assignment, you will need to make the following modifications/additions:
execute
method of each Statement
class, as well as in the evaluate
methods of the Expression
and Term
classes. not
, and
and or
are not. Make the appropriate additions to the appropriate classes so that these operators are recognized and evaluated correctly. A runtime exception should be thrown if any Boolean operator is applied to a non-Boolean value.
Output
class so that multiple (or no) expressions, separated by commas, can be printed in a single statement. Note: this requires storing all the expressions when an output statement is created, since the expressions cannot be evaluated until the statement is executed. Be sure to update the toString
method so that it accommodates the full format. If
class that defines if statements. This class will have significant similarities to the While
class due to their structural similarity (both contain a compound statement that is controlled by a Boolean test). However, an if statement has an else case that must also be handled. You will need to update the Token
and Statement
classes to recognize this new type of statement. Also, be sure to catch any syntax and run-time errors that might occur in your if statement, and implement the toString
method as required. To make testing your code easier, you can enter your test statements into a text file then execute them using the provided (Batch.java
) class. When executed, the batch interpreter prompts the user for a file name, reads SILLY statements from the file, and executes them. By default, the text file is assumed to be in the top-level directory of the project.