Commit | Line | Data |
---|---|---|
048de9cc AT |
1 | # Overview # |
2 | ||
3 | This example starts with the `Hello, world!` example from Wikipedia's | |
4 | Whitespace page, gradually rewriting it to use the ASCII string feature of the | |
5 | VVhitespace compiler and the `printf` subroutine from the stdlib. | |
6 | ||
7 | # "Hello, World!" in VVhitespace # | |
8 | ||
9 | Wikipedia's `Hello, World!` example is reproduced below. It follows a simple | |
10 | form, pushing an integer corresponding to an ASCII character onto the stack and | |
11 | then printing it with an IO instruction, repeating this two part process for | |
12 | each character before terminating with the final instruction. | |
13 | ||
14 | SSSTSSTSSSN | Push +72 (ASCII H) | |
15 | TNSS | Output character | |
16 | SSSTTSSTSTN | Push +101 (ASCII e) | |
17 | TNSS | Output character | |
18 | SSSTTSTTSSN | Push +108 (ASCII l) | |
19 | TNSS | Output character | |
20 | SSSTTSTTSSN | Push +108 (ASCII l) | |
21 | TNSS | Output character | |
22 | SSSTTSTTTTN | Push +111 (ASCII o) | |
23 | TNSS | Output character | |
24 | SSSTSTTSSN | Push +44 (ASCII ,) | |
25 | TNSS | Output character | |
26 | SSSTSSSSSN | Push +32 (ASCII space) | |
27 | TNSS | Output character | |
28 | SSSTTTSTTTN | Push +119 (ASCII w) | |
29 | TNSS | Output character | |
30 | SSSTTSTTTTN | Push +111 (ASCII o) | |
31 | TNSS | Output character | |
32 | SSSTTTSSTSN | Push +114 (ASCII r) | |
33 | TNSS | Output character | |
34 | SSSTTSTTSSN | Push +108 (ASCII l) | |
35 | TNSS | Output character | |
36 | SSSTTSSTSSN | Push +100 (ASCII d) | |
37 | TNSS | Output character | |
38 | SSSTSSSSTN | Push +33 (ASCII !) | |
39 | TNSS | Output character | |
40 | SSSTSTSN | Push +10 (ASCII '\n') | |
41 | TNSS | Output character | |
42 | NNN | Terminate program | |
43 | ||
44 | If we push the string onto the stack in reverse order we can rearrange the | |
45 | code as shown below. Now we're first pushing all the ASCII characters onto the | |
46 | stack, then printing them all at once. | |
47 | ||
48 | SSSTSTSN | Push +10 (ASCII '\n') | |
49 | SSSTSSSSTN | Push +33 (ASCII !) | |
50 | SSSTTSSTSSN | Push +100 (ASCII d) | |
51 | SSSTTSTTSSN | Push +108 (ASCII l) | |
52 | SSSTTTSSTSN | Push +114 (ASCII r) | |
53 | SSSTTSTTTTN | Push +111 (ASCII o) | |
54 | SSSTTTSTTTN | Push +119 (ASCII w) | |
55 | SSSTSSSSSN | Push +32 (ASCII space) | |
56 | SSSTSTTSSN | Push +44 (ASCII ,) | |
57 | SSSTTSTTTTN | Push +111 (ASCII o) | |
58 | SSSTTSTTSSN | Push +108 (ASCII l) | |
59 | SSSTTSTTSSN | Push +108 (ASCII l) | |
60 | SSSTTSSTSTN | Push +101 (ASCII e) | |
61 | SSSTSSTSSSN | Push +72 (ASCII H) | |
62 | TNSS | Output character | |
63 | TNSS | Output character | |
64 | TNSS | Output character | |
65 | TNSS | Output character | |
66 | TNSS | Output character | |
67 | TNSS | Output character | |
68 | TNSS | Output character | |
69 | TNSS | Output character | |
70 | TNSS | Output character | |
71 | TNSS | Output character | |
72 | TNSS | Output character | |
73 | TNSS | Output character | |
74 | TNSS | Output character | |
75 | TNSS | Output character | |
76 | NNN | Terminate program | |
77 | ||
78 | As a convenience, the VVhitespace compiler will accept `A""` syntax, generating | |
79 | a sequence of `PUSH` instructions, just like the prior examples, that places a | |
80 | null-terminated ASCII string on the stack. This allows us to shorten the | |
81 | program. Like before, the start of the string is closest to the top of the | |
82 | stack. Unlike before, there is now a null terminator at the end of the string. | |
83 | For now, we'll just leave that on the stack when the program terminates. | |
84 | ||
85 | A"Hello, world!\n" | |
86 | TNSS | Output character | |
87 | TNSS | Output character | |
88 | TNSS | Output character | |
89 | TNSS | Output character | |
90 | TNSS | Output character | |
91 | TNSS | Output character | |
92 | TNSS | Output character | |
93 | TNSS | Output character | |
94 | TNSS | Output character | |
95 | TNSS | Output character | |
96 | TNSS | Output character | |
97 | TNSS | Output character | |
98 | TNSS | Output character | |
99 | TNSS | Output character | |
100 | NNN | Terminate program | |
101 | ||
102 | Finally, we will use `printf` from the stdlib to shorten that mass of IO | |
103 | instructions. Every stdlib subroutine includes a text description as well as | |
104 | diagrams of the call and return stack. From `stdio.pvvs` we see the call stack | |
105 | for `printf` reproduced below. | |
106 | ||
107 | Call Stack: | |
108 | ACSII '\0' | |
109 | string word n | |
110 | ... | |
111 | string word 1 | |
112 | substitution n | |
113 | ... | |
114 | substitution 1 | |
115 | number of substitutions <-- TOS | |
116 | ||
117 | The text description for `printf` also informs us that, if we are printing a | |
118 | static string (i.e. no substitutions like '%d'), the `number of substitutions` | |
119 | should be `0` and it should be immediately followed by `string word 1`. Looking | |
120 | at the call stack, that makes sense since we have no substitutions to place | |
121 | between those two things. | |
122 | ||
123 | Note the ASCII `\0` on the call stack. That corresponds to the null terminator | |
124 | at the end of our string that was automatically placed by the `A""` syntax. | |
125 | ||
126 | Don't forget to `#include` the relevant stdlib files. This is done at the | |
127 | bottom of the file since VVhitespace files are executed from top to bottom. You | |
128 | wouldn't want to accidentally start executing random library code! | |
129 | ||
130 | Putting all that together, we discover a greatly simplified program. | |
131 | ||
132 | A"Hello, world!\n" | |
133 | SSSSN | PUSH 0 (number of substitutions) | |
134 | NSTTSSSN | JSR > 1000 (stdlib:printf) | |
135 | NNN | Terminate program | |
136 | #include <stdio.pvvs> | |
137 | ||
138 | This is already saved in `hello.pvvs` which you can execute with `make run`. |