1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
Format
======
This file showcases the plain-text humble type instruction format,
which simplifies the arrangement of TrueType instruction names,
flags, and arguments. The code examples follow a side-by-side format:
```
Humble type instruction source | Compiled TrueType instructions
```
Comments
--------
Text between `#` and the end of the line is ignored.
If the `#` is not the first character of a line,
it must be preceded by whitespace.
```
RTG # Hello | RTG
```
Flags
-----
As established by the standard, instruction flags are enclosed
in square brackets and directly appended to instruction names.
They can be written in binary form, or as a name from the
`flags` [block](blocks.md). Omitted flags default to zero.
```
SVTCA | SVTCA[0]
SVTCA[1] | SVTCA[1]
SVTCA[x] | SVTCA[1]
```
Arguments
---------
Instruction arguments are listed after the instruction name,
on the same line, separated by at least one space.
The compiler then creates optimized push instructions.
```
ALIGNPTS 7 8 | PUSHB[010]
FLIPPT 9 | 9 7 8
| ALIGNPTS
| FLIPPT
```
Automatic Looping
-----------------
If more than one argument follows an `ALIGNRP`, `FLIPPT`, `IP`,
or `SHP` instruction, the compiler will split them up appropriately,
either by repeating the instruction or by inserting `SLOOP`.
```
ALIGNRP 6 7 8 9 | PUSHB[100]
| 6 7 8 9 4
| SLOOP
| ALIGNRP
```
Numeric Conversion
------------------
Numeric arguments can be provided in different formats.
Integers can be written as binary values with a `0b` prefix,
as case insensitive hexadecimal values with a `0x` prefix,
or as signed decimal values.
Fixed-point numbers start with a decimal integer, followed
by a decimal point, followed by an unsigned decimal fraction.
In case of f2dot14 values, the point is replaced with a colon.
Fixed-point numbers are rounded when necessary.
```
SMD 0x60 | PUSHB[100]
SMD 0b1100000 | 96 96 96 96 96
SMD 96 | SMD SMD SMD SMD SMD
SMD 1.5 |
SMD 0:005859375 |
```
Identifiers
-----------
Unique names are used to address control values, storage locations,
or functions. The compiler takes care of mapping each name to an index.
Identifiers are declared in the `cvt` or `storage` [block](blocks.md).
```
WS foo 8 | PUSHB[001]
| 3 8
| WS
```
Nested Instructions
-------------------
To use the output of an instruction as an argument,
it is nested in parentheses.
```
MIAP (RS foo) bar | PUSHB[000]
| 3
| RS
| PUSHB[000]
| 23
| MIAP[0]
```
Operator Symbols
----------------
Instead of writing mathematical instructions in prefix
notation, it is possible to write their symbols
`==` `!=` `<=` `<` `>=` `>` `+` `-` `*` `/` `and` `or`
between their two arguments. When possible, nested instructions
should be placed on the right side, for an optimal push optimization.
```
IF (2 > (1 + 3)) | PUSHB[010]
| 2 1 3
| ADD
| GT
| IF
```
Stack Management
----------------
When arguments are listed after the instruction name, the compiler
creates optimized `PUSH` instructions. However, sometimes it is
desirable to manage the stack manually, for example in function
definitions.
For that case, it is possible to omit arguments after an instruction
and instead push them with the custom `push` instruction. Mixing
automatic and manual pushes within the same scope, e.g. the body
of a function definition, is not recommended.
```
FDEF 31 align pt | PUSHB[000]
DUP | 31
push 1 | FDEF
ADD | DUP
ALIGNPTS | PUSHB[000]
ENDF | 1
| ADD
| ALIGNPTS
| ENDF
```
|