SpectNetIde provides a somple programming language to describe Z80-related unit tests. You can add the
.z80test
files to your project and run the test in the Unit Test Explorer tool window. This document
treats the syntax and semantics of the language.
Syntax Basics
The test language uses a special way of case-sensitivity. You can write the reserved keywords on lowercase. When you refer to Z80 CPU registers or flags, you can use either with lowercase or uppercase letters, but you cannot mix these cases. You can mix cases for identifiers, though they are searched for a case-insensitive manner.
Test Structure
A ZX Spectrum project may have zero, one, or more test files (files with .z80test
extension). Before
running them, the engine collects all .z80test
files from the current project, and compiles them all.
A single test file may contain one or more test set. A test set is a collection of cohesive tests that all use the very same source code, as the basis of testing:
testset Introduction
{
source "../Z80CodeFiles/CodeSamples.z80asm";
// --- Other testset attributes
test AddAAndBWorksAsExpected
{
// --- Other test attributes
act call AddAAndB;
assert
{
// --- Here we describe the test assertions
}
}
}
A test can have a default act, such as in the sample above, or may have parameterized test cases:
// --- Wrapping test set omitted
test AddAAndBCallWorksAsExpected2
{
params parA, parB, Z;
case 1, 2, 0;
case 2, 3, 0;
case -6, 6, 1;
arrange
{
a: parA;
b: parB;
}
act call AddAAndB;
assert
{
a == parA + parB;
b == parB;
.z == Z;
}
}
This test has three cases, as declared by the lines starting with the case
keyword.
When running them, the engine substitutes the parA
, parB
, and Z
values with the
values after case
(fore each case
).
To summarize:
Concept | Description |
---|---|
test file | A single container for test sets. Besides keeping test sets together in a single file, there’s no additional semantics. |
test set | A cohesive set of tests. A test set has a single source code file — this contains the code to test — shared between the test within the set. |
test | A single test that runs a piece of the source code to test. It may nest test cases. |
test case | Parameterized test. It runs the same code (although you can run different code) with the case-related parameters. |
Syntax Elements
The test language contains several constituting elements that you can use in many places within the code, such as comments, expressions, identifiers, and so on. Here you can learn about them.
Comments
Comments can be single line or multi-line comments with the same syntax construct as you may use them in many curly-brace-languages, such as C++, Java, C#, etc.:
// --- This is a single line comment you can add to the end of the code lines
/* This is a multi-line comment the spans accross multiple lines,
including empty ones
*/
Literals
The language syntax provides these types of literals:
- Decimal numbers. You can use adjacent digits (0..9) to declare a decimal number. Examples: 16, 32768, 2354.
- Hexadecimal numbers. You can use up to 4 hexadecimal digits (0..9, a..f or A..F) to declare
a hexadecimal literal. The compiler looks for one of the
#
or0x
prefix, or one of theh
orH
suffixes to recognize them as hexadecimal. Here are a few samples:
#12AC
0x12ac
12ACh
12acH
- Binary numbers. Literal starting with the one of the
%
or0b
prefix are taken into account as binary literals. You can follow the prefix with up to 160
or1
digits. To make them more readable, you can separate adjacent digits with the underscore (_
) character. These are all valid binary literals:
%01011111
0b01011111
0b_0101_1111
You can use negative number with the minus sign in front of them. Actually, the sign is not the part of the numeric literal, it is an operator.
- Characters. You can put a character between double quotes (for example:
"Q"
). - Strings. You can put a series of character between double quotes (for example:
"Sinclair"
).
Here are a few samples:
"This is a string. The next sample is a single character"
"c"
Character and String Escapes
ZX Spectrum has a character set with special control characters such as AT, INK, PAPER, and so on.
SpectNetIde allows you to utilize special escape sequences to define ZX Spectrum-specific characters:
Escape | Code | Character |
---|---|---|
\i |
0x10 | INK |
\p |
0x11 | PAPER |
\f |
0x12 | FLASH |
\b |
0x13 | BRIGHT |
\I |
0x14 | INVERSE |
\o |
0x15 | OVER |
\a |
0x16 | AT |
\t |
0x17 | TAB |
\P |
0x60 | pound sign |
\C |
0x7F | copyright sign |
\\ |
0x5C | backslash |
\' |
0x27 | single quote |
\" |
0x22 | double quote |
\0 |
0x00 | binary zero |
Observe, some of these sequences have different values than their corresponding pairs in other languages, such as C, C++, C#, or Java.
To declare a character by its binary code, you can use the \xH
or
\xHH
sequences (H
is a hexadecimal digit). For example, these
escape sequence pairs are equivalent:
"\i"
"\x10"
"\C by me"
"\x7f \x62y me"
Identifiers
You can use identifiers to refer to labels and other constants. Identifiers must start with
a letter (a..z or A..Z) or the underscore character (_
). The subsequent characters
can be digits (0..9), too. Here are a few samples:
MyCycle
ERR_NO
Cycle_4_Wait
Theoretically, you can use as long identifiers as you want. I suggest you to make them no longer than 32 characters so that readers may read your code easily.