For this assignment, you are to complete an interpreter for a simple, procedural programming language named SILLY (Simple, Interpreted, Limited Language for You). The grammar rules for the SILLY language are as follows:
There are no spaces between the characters in an identifier, integer, or string. Otherwise, tokens in the other rules are all separated by whitespace.
The SILLY language is case sensitive, so variables a and A are considered unique. There are two data types in SILLY: integer and string. Variables are not explicitly declared but must be assigned a value before they can be used in an expression or statement. An assignment statement assigns a value to a variable. An output statement displays a value on a line by itself. If statements and while loops are controlled by an expression, where any nonzero integer value or nonempty string value is considered to be true. A repeat loop will repeat its statements a specified number of times, specified either by a number or the length of a string. Finally, a quit statement terminates the interpreter.
For example:
SAMPLE CODE (output in red) >>> x = 4 >>> output x 4 >>> y = ( x + 1 ) >>> x = ( 1 + 5 - 2 ) >>> output ( y + x ) 9 >>> word1 = "foo" >>> word2 = "bar" >>> output ( word1 + word2 ) "foobar" >>> output ( word1 + 99 ) "foo99" >>> val1 = 1023 >>> val2 = 1024 >>> output ( val1 + 1 / 2 ) 512 >>> output ( val1 - val2 ) -1 >>> output ( 65 - 1 / 8 / 2 ) 4 >>> quit BYE >>> num1 = 4 >>> if num1 output ( "num1=" + num1 ) else output "nope" end "num1=4" >>> x = 10 >>> y = 1 >>> while ( x - y ) x = ( x - 1 ) y = ( y + 2 ) end output ( x + "," + y ) "7,7" >>> repeat ( 2 + 1 ) output "foo" end "foo" "foo" "foo" >>> val = 0 >>> repeat "abcd" val = ( val + 1 ) end output val 4 >>> quit BYE
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. By default, the interpreter reads statements from and displays output to the console. If you specify a file name as a command line argument, however, the interpreter will read statements directly from the file.
- MemoryStack.java, MemoryHeap.java : These classes define the memory partitions for storing variables and their values, with integer values stored directly on the stack and strings stored on 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.
- Assignment.java, Output.java, If.java, Quit.java : These classes, derived from
Statement
, define the specific statements of the SILLY language.- DataValue.java, IntegerValue.java, StringValue.java: This interface and implementing classes defines the types of values that can be stored in SILLY, which are integer and string. When used to control an if statement or while loop, any non-zero integer or nonempty string value is interpreted as true.
- Expression.java : This class defines an expression, which is either an integer, a string, an identifier, or a complex expression involving operators.
To produce a fully functional interpreter for the SILLY language, you will need to make the following modifications/additions:
( 12 + "foo" ) --> ( "12" + "foo" ) --> "12foo"
.
end
'
keyword for an if statement - if there is an else case, the keyword 'else
'
separates the statements to be executed if the test expression evaluates to true (i.e., nonzero/nonempty) or
false (i.e., zero/empty).
Note that in making these additions, the main progam file (Interpreter.java) need not be modified at all. Instead, you will primarily be making changes to the various Statement classes, with some minor modifications to Statement and Expression. As you add new features, be sure that syntax errors result in exceptions being thrown with informative messages.
For extra credit, add a comment feature to the language. A comment can begin at any point on a line, starting with '//', and continues to the end of that line. A comment is ignored when executing the program.