For this stage of the Sloth interpreter, we will be adding arrays into the language. This will involve changes to the lexer, parser, and tree-walking interpreter.
We can make arrays in Sloth using this literal notation:
numbers := [];
names := ["Alice", "Bob", "Claire"];
We can then index a list using the familiar syntax to either read or set a value:
print(names[1]);
names[2] := "Charlie";
We can join two lists using the + operator, and get the length of one using the new length function:
numbers := numbers + [1, 2, 3];
size := length(numbers);
We can also pass an array into the print or println functions.
To keep things simple, we will only have "one-dimensional" arrays — that is we can only have arrays of the other types, not arrays containing other arrays.
We will use the following new test programs for this stage of the assignment:
Program | Description |
arrays.sl | Makes an array and then loops through it. |
sort.sl | Reads in an array of data and then bubble sorts it. |
You should also make shorter test programs to test each new language feature as you implement it. For instance, when you support printing an array literal, write a test program to do just that and try it.
Your lexer will need to capture the following new tokens:
These will allow us to recognize the lexical forms to support arrays in Sloth.
We will need to make several changes to the parser in order to recognize the ways arrays will be used:
[]
[1, 2, 3]
[a * 3]
[3, "hello", true, (x + 1) * 3]
:=
operator was an ID
. Now we can also assign into the slots of an array as well. For example, in code like
array[i] := i * 10;
. The technical term for what may appear on the left-hand side of the assignment operator is an L-value.
We need to modify the assignment operator so that the left-hand side may be either a simple ID
, or be followed by a '[', any expression,
and then a ']'.length
function which takes one parameter inside of parentheses. This should be parsed similarly to the
print
function.Now we need to make the following changes in the interpreter to support the syntax we've added:
SlothType
enum, and also adding supporting code to the
SlothValue
class. Make a constructor that takes an ArrayList as a parameter, and store it in the object wrapped by the class.toArray
method to this class. It should return array objects as ArrayLists. Other types should be converted
into arrays of length one with, with the value as the only element. (This will allow us to append to arrays more easily).visitAssign
method to account for assigning into an array slot. If there
is a subscript, we need to evaluate the expression used, take the result as an index and write to the array at that slot. When there are options
like this in a rule, calling the sub-tree method (such as .expression()) will return null if it is not present.ID
of the array from the symbol table, get it as an ArrayList, and then perform the indexing.length
function to find the length of an array. While we are here, we could also make it
work for strings, but none of the test programs use that.There are many things that can go wrong in the methods above: the index might be a non-integer, it might be negative, or too big, etc. You don't need to check for these things for this assignment. If something goes wrong, the Java VM will kill our interpreter. Making good error messages for our language would take a bit of doing and we won't worry about it here.
Submit the files for your interpreter to Canvas for this assignment.
Copyright © 2024 Ian Finlayson | Licensed under a Creative Commons BY-NC-SA 4.0 License.