The purpose of this project is to extend Good Lang to allow the specification of meta types (types composed of other types), specifically the array.
Now that your compiler implements a language where you can manipulate two types of scalar variables (floating-point values and characters), our next step is to implement arrays. For this project, you will implement a new meta-type for Good Lang called "array". To declare a variable of type array, a programmer must use "array(type) var_name;" where type is the data type that you want all of the array elements to have and var_name is the name of the array variable you are defining. Do not implement arrays-of-arrays; there should now be four variable types: val, char, array(val), and array(char). Additionally, you must allow the new variable type "string" to work, which should be identical to "array(char)".
To use an array in Good Lang, follow an array identifier with a pair of brackets containing an expression. That expression is evaluated and used to index into the array. Note that there are three aspects of this that you must include in your semantic checking. Given: "identifier '['expression ']'", the identifier must be of an array type, the expression must evaluate to type val, and the whole sequence evaluates to the internal type of the array.
Note that the print command must also handle array variables or expressions that evaluate to arrays. When an array is printed, the contents of the array should just be printed all in a row, with no spaces in-between. Typically this will only be used to print strings, but should still functions for arrays of vals, even if they are difficult to read.
Any string contained between double-quotes should be taken as a literal of type "array(char)".
String literals must support escaped newline characters (
'\n'), tabs (
'\t'), backslashes (
'\\') and double
'\"'), as well as pound signs (
'#') without triggering comments.
Be sure your strings can handle single quotes as well.
For example, consider the following Good Lang code:
array(char) my_array = "A pound-sign (\"#\") is okay in strings."; print(my_array);
When compiled and run by bad_interpreter.py, this code should output:
A pound-sign ("#") is okay in strings.
You must implement a method to access the number of elements in an array. Specifically, any array followed by ".size()" will be treated as a value representing the size of that array. For example
string a = "This is a string!"; print(a.size());
should print the value
17 to the screen.
You must implement a method to alter the number of elements in an array. Specifically, any array variable followed by ".resize(x)" will have its number of elements changed to the value of x. Any element indices that persist will keep the same value. Any new indices will have their values undefined until assigned.
The left hand side (lvalue) of an assignment statement must evaluate to a variable (either a scalar variable or an array) or else it must be an index within an array variable. It is not legal to assign to temporary values created by commands, literals, or functions. For example, the following statement is illegal:
"string literal" = 'x';
To implement these features in Bad Lang, you have access to array variables. Like scalar variables, array variables are accessed by a single letter ('a' in this case) followed by a unique number identifier (for example, "a23" would be an array). There are four array-specific instructions that you can use:
|ar_get_idx||[ARRAY: array] [NUM: num] [VAR: result]||In array, find value at index num, and put into result.|
|ar_set_idx||[ARRAY: array] [NUM: num1] [VAR: num2]||In array, set value at index num1 to the value num2|
|ar_get_size||[ARRAY: array] [VAR: result]||Calculate the size of array and put into result.|
|ar_set_size||[ARRAY: array] [NUM: num]||Resize array to have num entries.|
|ar_copy||[ARRAY: array1] [ARRAY: array2]||Duplicate all values within array1 into array2.|
The full specification of the Bad Lang is found here: Bad Lang Specification
Note that in order to use an array you must first initialize it with the ar_set_size instruction.
Your compiler must still catch errors from previous projects as well as some new errors. For reference, the previous errors are:
(note that the above error should be triggered for all of +, -, *, /, &&, ||, !, +=, -=, *=, and /=)
And the new errors associated with this project are:
size() and resize() are the two legal array methods; the identifier before them must represent an array variable.
The only expressions the type array(val) and array(char) are legal for is simple assignment "=". All others should raise " ERROR(line #): cannot use type 'type' in mathematical expressions".
From this project onwards, if you encounter an error, you can raise any type of exception (e.g. NameError, SyntaxError, JoshIsSillyError).
As long as the exception inherits from Python's base
Exception, it will work.
See (https://docs.python.org/3.6/tutorial/errors.html#tut-userexceptions) for details.
When you submit your program, you must include: