Write the usage guide as thirteen chapters in docs/
Some checks failed
akbasic CI Build / cmake_build (push) Successful in 3m0s
akbasic CI Build / sanitizers (push) Successful in 3m45s
akbasic CI Build / coverage (push) Failing after 3m22s
akbasic CI Build / akgl_build (push) Failing after 21s
akbasic CI Build / mutation_test (push) Successful in 11m26s
Some checks failed
akbasic CI Build / cmake_build (push) Successful in 3m0s
akbasic CI Build / sanitizers (push) Successful in 3m45s
akbasic CI Build / coverage (push) Failing after 3m22s
akbasic CI Build / akgl_build (push) Failing after 21s
akbasic CI Build / mutation_test (push) Successful in 11m26s
Organised the way the C128 Programmer's Reference Guide is: the language first, then each hardware area, then the reference sections. One markdown file per chapter. The verb and function references are generated from the interpreter's own dispatch table, with an assertion that every row is described, so they cannot drift out of step with what the program accepts. 98 verbs and 30 functions. Every example was run before it was written down, which caught three claims that were wrong: a whole FOR loop on one line prints nothing rather than looping once, MID and INSTR count from zero where a C128 counts from one, and a multi-line DEF returns a value the caller has to assign away. Chapter 13 is the list a BASIC 7.0 programmer needs -- roughly sixty documented differences, including the two known FOR defects and the fact that drawing does not survive a frame. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
128
docs/05-strings-and-formatting.md
Normal file
128
docs/05-strings-and-formatting.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# 5. Strings and formatting
|
||||
|
||||
## The string functions
|
||||
|
||||
| Function | What it gives you |
|
||||
|---|---|
|
||||
| `LEN(A$)` | how many characters, or how many elements in an array |
|
||||
| `LEFT(A$, N#)` | the leftmost `N#` characters |
|
||||
| `RIGHT(A$, N#)` | the rightmost `N#` characters |
|
||||
| `MID(A$, START#, LENGTH#)` | a substring, counting from **zero** |
|
||||
| `INSTR(A$, B$)` | where `B$` appears in `A$` counting from **zero**, or -1 |
|
||||
| `CHR(N#)` | the character for a Unicode code point |
|
||||
| `STR(N#)` | a number as a string |
|
||||
| `VAL(A$)` | a string as a number |
|
||||
| `HEX(N#)` | a number as hexadecimal text |
|
||||
| `SPC(N#)` | that many spaces |
|
||||
|
||||
`LEFT` and `RIGHT` clamp rather than failing, so asking for more characters than the
|
||||
string has gives you the whole string.
|
||||
|
||||
**`MID` and `INSTR` count from zero**, where a C128's `MID$` and `INSTR` count from one.
|
||||
`MID("HELLO WORLD", 6, 5)` is `WORLD`, and `INSTR("HELLO WORLD", "WORLD")` is `6`. A
|
||||
failed `INSTR` gives -1, not 0, so there is no ambiguity with a match at the start.
|
||||
|
||||
```
|
||||
10 A$ = "HELLO WORLD"
|
||||
20 PRINT LEN(A$)
|
||||
30 PRINT LEFT(A$, 5)
|
||||
40 PRINT RIGHT(A$, 5)
|
||||
50 PRINT MID(A$, 6, 5)
|
||||
60 PRINT INSTR(A$, "WORLD")
|
||||
```
|
||||
|
||||
`VAL` refuses text that is not a number rather than quietly returning zero, so a
|
||||
program can tell "the user typed 0" from "the user typed nonsense".
|
||||
|
||||
## PRINT USING
|
||||
|
||||
`PRINT USING` lays a value out in a fixed field, which is what makes columns line up.
|
||||
|
||||
```
|
||||
10 PRINT USING "###.##"; 3.14159
|
||||
20 PRINT USING "TOTAL: $#,###.##"; 1234.5
|
||||
30 PRINT USING "####-"; -42
|
||||
```
|
||||
|
||||
```
|
||||
3.14
|
||||
TOTAL: $1,234.50
|
||||
42-
|
||||
```
|
||||
|
||||
The field is built from these characters, and any text around it is printed as it
|
||||
stands:
|
||||
|
||||
| In the field | Means |
|
||||
|---|---|
|
||||
| `#` | one digit position |
|
||||
| `.` | the decimal point |
|
||||
| `,` | group the integer part in threes |
|
||||
| `$` | a currency sign |
|
||||
| `+` or `-` at the front | a sign position before the number |
|
||||
| `+` or `-` at the end | a sign position after it |
|
||||
| `=` | centre a string in the field |
|
||||
| `>` | right-justify a string |
|
||||
|
||||
**A value too wide for its field fills the field with `*`.** That is deliberate and it
|
||||
is loud: printing more digits than the field asked for would push every later column
|
||||
out of line.
|
||||
|
||||
```
|
||||
10 PRINT USING "###"; 99999
|
||||
```
|
||||
|
||||
```
|
||||
***
|
||||
```
|
||||
|
||||
A negative number in a field with no sign position overflows the same way, because
|
||||
printing `-5` as `5` would be worse.
|
||||
|
||||
String fields centre and right-justify:
|
||||
|
||||
```
|
||||
10 PRINT USING "=========="; "MID"
|
||||
20 PRINT USING ">>>>>>>>>>"; "RIGHT"
|
||||
```
|
||||
|
||||
```
|
||||
MID
|
||||
RIGHT
|
||||
```
|
||||
|
||||
One field per statement. `PRINT USING "### ###"; A, B` is not supported — see
|
||||
Chapter 13.
|
||||
|
||||
## PUDEF
|
||||
|
||||
`PUDEF` changes the characters a numeric field pads and punctuates with. It takes up
|
||||
to four, in this order: the leading blank, the thousands separator, the decimal point,
|
||||
and the currency sign.
|
||||
|
||||
```
|
||||
10 PUDEF "*"
|
||||
20 PRINT USING "#####"; 42
|
||||
```
|
||||
|
||||
```
|
||||
***42
|
||||
```
|
||||
|
||||
Positions you leave out keep what they had, so the one-character form above changes
|
||||
only the padding.
|
||||
|
||||
## CHAR
|
||||
|
||||
`CHAR` puts text at a character position rather than at the cursor:
|
||||
|
||||
```
|
||||
10 CHAR 1, 10, 5, "HERE"
|
||||
```
|
||||
|
||||
The arguments are colour, column, row and the text. It needs a text device with a
|
||||
cursor, which means the SDL build — a terminal's cursor is not this library's to move,
|
||||
and it refuses by name in the default build.
|
||||
|
||||
The colour argument is accepted and ignored; the sink draws in one colour, chosen by
|
||||
whoever built it.
|
||||
Reference in New Issue
Block a user