diff --git a/vcalc/impl/assertions.rst b/vcalc/impl/assertions.rst index 0ecfbd62..dd1b1455 100644 --- a/vcalc/impl/assertions.rst +++ b/vcalc/impl/assertions.rst @@ -67,8 +67,8 @@ specification particulars. **expression-size**: - All expressions will result in a value that will fit in 32 signed - bits. This means the result of an expression can be anywhere in the + Every integer an expression produces, including each vector element, + will fit in 32 signed bits. This means the result of an expression can be anywhere in the range :math:`[-2^{31}, 2^{31} - 1]` or :math:`[-2147483648, 2147483647]`. Any operation that results in underflow or overflow will render the input invalid. For example, the following tests would diff --git a/vcalc/impl/clarifications.rst b/vcalc/impl/clarifications.rst index aedafa9e..5154bac4 100644 --- a/vcalc/impl/clarifications.rst +++ b/vcalc/impl/clarifications.rst @@ -16,9 +16,7 @@ specification without cluttering it. Empty input should result in empty output. This is in keeping with all of the output rules defined. There are no ``print`` :term:`statements ` so - there would be no numbers, newlines or output of any kind. All that - you are left with is a single empty line, which matches "*should* be - an empty line at the end of your output". + there would be no numbers, newlines or output of any kind. #. @@ -116,3 +114,29 @@ specification without cluttering it. [1] +#. + + .. _clarify:int-div: + + .. container:: + :name: int-div + + **int-div**: + + Division is integer division. This means that any decimal portion of + a division operation result is truncated (not rounded). No extra work + is required: this is the default in C++, RISC-V, ARM, and X86. For + example: + + :: + + print(5 / 3); + print((0 - 5) / 3); + + produces the following output: + + :: + + 1 + -1 + diff --git a/vcalc/impl/output.rst b/vcalc/impl/output.rst index a35ff966..6b2633c8 100644 --- a/vcalc/impl/output.rst +++ b/vcalc/impl/output.rst @@ -14,23 +14,3 @@ output file should be overwritten if it already exists. The output of your compiler is the *LLVM IR* that corresponds to the given input program. The output file can be used as input to ``llc``, for example, which compiles *LLVM IR* input into assembly language for a specified machine. - -Program Output -============== - -Output content is standardized to ensure everyone can pass everyone’s -tests. Follow these specifications: - -- Each number printed should be on its own line followed by a new line. - -- There *must* be a new line after each ``print`` statement’s printed - value. - -- There *must not* be any trailing space after the final number and - before the newline. - -- There *must* be an empty line at the end of your output. - -**Clarification:** Empty input should result in empty output. -(:ref:`empty-input `) - diff --git a/vcalc/spec/booleans.rst b/vcalc/spec/booleans.rst new file mode 100644 index 00000000..3cbad0b4 --- /dev/null +++ b/vcalc/spec/booleans.rst @@ -0,0 +1,40 @@ +Booleans +-------- + +In this assignment, booleans can only be produced using comparison +operators, there is no :term:`literal` to express them. As well, they are +ephemeral: there is no way to store them. They can only exist when +created using one of the comparison operators. + +When printed, booleans take on a value of 1 (true) or 0 (false). For +example: + +:: + + print(1 == 1); + print(1 == 0); + +produces the following output: + +:: + + 1 + 0 + +As well booleans *are* usable in :term:`expressions ` and must +undergo :term:`type promotion` to an integer. This means if a boolean is +used in an arithmetic expression it takes on the integer value described +above. For example: + +:: + + print(1 + (1 == 1)); + print(1 + (1 == 0)); + +produces the following output: + +:: + + 2 + 1 + diff --git a/vcalc/spec/expressions.rst b/vcalc/spec/expressions.rst index 9139f01e..6332eb12 100644 --- a/vcalc/spec/expressions.rst +++ b/vcalc/spec/expressions.rst @@ -7,6 +7,9 @@ Valid formats for expressions are () + [] + [ in | ] + [ in & ] @@ -16,8 +19,9 @@ Valid formats for expressions are - ``id`` is the identifier of a variable. -| **Assertion:** All expressions will result in a value that fits in a - 32 bit signed integer. (:ref:`expression-size `) +| **Assertion:** Every integer an expression produces, including each + vector element, fits in a 32 bit signed integer. + (:ref:`expression-size `) | **Assertion:** No expression will contain a division by 0. (:ref:`zero-divide `) @@ -61,6 +65,9 @@ For example, addition and subtraction have an equal level of precedence. | | is not equal | ``!=`` | ``expr != expr`` | left | +------------+----------------+------------+------------------+-------------------+ +| **Clarification:** Division is integer division. + (:ref:`int-div `) + Binary Operations on Vectors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -196,15 +203,16 @@ Vector Indexing Vectors can be indexed by a scalar to produce the integer value at a specified index. Vectors in *VCalc* are *zero indexed*. As well, indexing outside of the bounds of a vector (e.g. ``v[i]`` where -:math:`0 <= |v| < l` and :math:`i < 0` or :math:`i >= l`) is *not an +:math:`|v| = l` and :math:`i < 0` or :math:`i >= l`) is *not an error*. An index out of bounds *always returns zero*. Index domains must be vectors: - Domain can be an :term:`identifier` for a vector. -- Domain can be the result of a range, generator, filter, or another - index expression with a vector index (see below). +- Domain can be the result of a range, generator, filter, binary + operation with a vector operand, or another index expression with a + vector index (see below). - Domain cannot be an integer. For example, this is :term:`ill-formed`: diff --git a/vcalc/spec/filters.rst b/vcalc/spec/filters.rst index d5d5e8b0..75e8a9b7 100644 --- a/vcalc/spec/filters.rst +++ b/vcalc/spec/filters.rst @@ -12,12 +12,12 @@ The identifier and vector are still called the :term:`iterator variable` and domain vector, however, the right-hand-side :term:`expression` is now called the *predicate*. The iterator variable is an integer typed variable defined only in -the scope of the generator. +the scope of the filter. As in a generator, the :term:`domain` may be any vector-valued expression which includes identifiers (that are vector typed), -ranges, generators, filters, and index expressions with a vector -index. The predicate must evaluate to a boolean. This means that if +ranges, generators, filters, index expressions with a vector +index, and binary operations with a vector operand. The predicate must evaluate to a boolean. This means that if the result of the expression is an integer it will undergo an :term:`implicit conversion` to a boolean, but a vector result is an *error*. diff --git a/vcalc/spec/generators.rst b/vcalc/spec/generators.rst index 0b246f34..499ac626 100644 --- a/vcalc/spec/generators.rst +++ b/vcalc/spec/generators.rst @@ -15,8 +15,9 @@ right-hand-side expression. The iterator variable is an integer typed variable defined only in the scope of the generator. The domain may be any vector-valued expression which includes -identifiers (that are vector typed), ranges, generators, filters, and -index expressions with a vector index. The expression must evaluate to +identifiers (that are vector typed), ranges, generators, filters, +index expressions with a vector index, and binary operations with a +vector operand. The expression must evaluate to an integer. This means that if the result of the expression is a boolean it will undergo :term:`type promotion` to an integer, but a vector result is an *error*. diff --git a/vcalc/spec/identifiers.rst b/vcalc/spec/identifiers.rst new file mode 100644 index 00000000..288f2bac --- /dev/null +++ b/vcalc/spec/identifiers.rst @@ -0,0 +1,28 @@ +Identifiers +----------- + +For the purpose of this assignment, identifiers are simple. They must +start with an alphabetical character. This character may be followed by +numbers or alphabetical characters. A keyword cannot be used as an +identifier. + +Examples of valid identifiers: + +:: + + hello + h + h3llo + Hi + h3 + +Examples of invalid identifier: + +:: + + 3d + a-bad-variable-name + no@twitter + we.don't.like.punctuation + or_spelling + diff --git a/vcalc/spec/integers.rst b/vcalc/spec/integers.rst new file mode 100644 index 00000000..dfc45464 --- /dev/null +++ b/vcalc/spec/integers.rst @@ -0,0 +1,50 @@ +Integers +-------- + +In this assignment, integers are the *only* numerical :term:`type` (there +is no floating point type). + +In this assignment integer :term:`literals ` are defined as +being a string that contains only the numerals 0-9 with no spaces. + +| **Assertion:** All integer literals will be :math:`\geq 0`. + (:ref:`nonnegative-literals `) +| Examples of valid integers: + +:: + + 1 + 123 + 5234 + 01 + 10 + +Examples of invalid integers: + +:: + + 1.0 + one + 1_1 + 1o + +As well, integers *are* usable in conditions and must undergo +:term:`implicit conversion` to booleans. This means in a condtional, an +integer that *is not* zero will be considered true and an integer that +*is* zero will be considered false. For example: + +:: + + if (999) + print(999); + fi; + if (0) + print(0); + fi; + +produces the following output: + +:: + + 999 + diff --git a/vcalc/spec/statements.rst b/vcalc/spec/statements.rst index 4d679ebd..11adf3e2 100644 --- a/vcalc/spec/statements.rst +++ b/vcalc/spec/statements.rst @@ -72,7 +72,7 @@ following form: - ``expr`` is an expression. -There are a few new important points when dealing with assignments. +There are a few important points when dealing with assignments. #. The size of a vector may change while the program is executing if a vector variable is assigned another value. For instance, the @@ -231,8 +231,6 @@ tests. Follow these specifications: - There *must not* be any trailing space after printed value and before the newline. -- There *must* be an empty line at the end of your output. - - There *must not* be spaces between the first and last number and the accompanying brackets in a vector. diff --git a/vcalc/spec/vectors.rst b/vcalc/spec/vectors.rst index 82ace038..e42903e8 100644 --- a/vcalc/spec/vectors.rst +++ b/vcalc/spec/vectors.rst @@ -1,7 +1,7 @@ Vectors ------- -*VCalc* has a new :term:`type`, ``vector``, that is a vector of integer values. +*VCalc* has a :term:`type`, ``vector``, that is a vector of integer values. Vectors are restricted to the length that can be represented by the *largest possible index*. Indices are integers and integers are signed 32 bit integers. Because the largest possible integer is @@ -12,8 +12,8 @@ the range :math:`[0, 2^{31}-1]`. :math:`0 \leq l \leq 2^{31}-1`. (:ref:`vector-length `) There is no way to specify a vector literal, they must be created -through ranges, generators, filters, or index expressions with a vector -index. +through ranges, generators, filters, index expressions with a vector +index, or binary operations with a vector operand. The only way to create an empty vector is through the use of a filter whose predicate is evaluated to false at each index of the :term:`domain`