Project 5: Arrays

Description

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.

The "array" Meta-type

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.

String literals

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 quotes ('\"'), 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.

Array size

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.

Array resize

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.

Legal assignment lvalues

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"[5] = 'x';

Bad Lang (New Instructions)

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:

Name Arguments Description
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.

Error Reporting

Your compiler must still catch errors from previous projects as well as some new errors. For reference, the previous errors are:

  • ERROR(line #): unknown token '@'
  • ERROR(line #): syntax error
  • ERROR(line #): unknown variable 'var_name'
  • ERROR(line #): redeclaration of variable 'var_name'
  • ERROR(line #): 'break' command used outside of any loops
  • ERROR(line #): types do not match for assignment (lhs='type1', rhs='type2')
  • ERROR(line #): types do not match for relationship operator (lhs='type1', rhs='type2')
  • ERROR(line #): cannot use type 'type' in mathematical expressions

    (note that the above error should be triggered for all of +, -, *, /, &&, ||, !, +=, -=, *=, and /=)

  • ERROR(line #): condition for if statements must evaluate to type val
  • ERROR(line #): condition for while statements must evaluate to type val
  • ERROR(line #): cannot use type 'type' as an argument to random

And the new errors associated with this project are:

  • ERROR(line #): cannot index into a non-array type
  • ERROR(line #): array indices must be of type val
  • ERROR(line #): array methods cannot be run on type 'type'

    size() and resize() are the two legal array methods; the identifier before them must represent an array variable.

  • ERROR(line #): array size() method does not take any arguments.
  • ERROR(line #): array resize() method takes exactly one (val) argument.
  • ERROR(line #): array resize() method argument must be of type val.

Allowed Operators:

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".

Non-Specific Exceptions

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.

Submission

When you submit your program, you must include:

  • A project.py with the "generate_bad_code_from_string" function.
  • A README.txt file that includes the your name, a brief summary of what does and does not work in your code. Your README may also include any notes that you want us to read before grading your program, such as any external resources you used in its development.
  • You may divide your project code into multiple files to do so you will need to use relative imports (if that doesn't mean anything to you, just keep everything in the project.py file).