Blog/Components/Pages/Concat.razor 6.2 K · 152 lines · raw · history

1 @page "/Concat"
2 <PageTitle>Concatenator</PageTitle>
3 <script type="module" src="@Assets["Components/Pages/Concat.razor.js"]"></script>
4 <main>
5 <p>A "concatenative language"</p>
6 <form id="form">
7 <textarea id="input" placeholder="1 2 +" rows="5"></textarea>
8 <input type="submit" value="Run program">
9 <label for="instant">
10 Run instantly
11 <input type="checkbox" id="instant">
12 </label>
13 </form>
14 <Log/>
15
16 <Panel Legend="Predefined operations">
17 <StackOps/>
18
19 <StackOp Name="if ... then"
20 Description="Drops the top value on the stack and tests it. If it is false, or 0, the program skips ahead past the matching 'then', otherwise the words in between are run. The 'then' itself is removed either way: it only marks the end of the branch, it never runs.">
21 <StackStep Stack="[1, 2, 3]" Program="if dup then drop"/>
22 <StackStep Stack="[2, 3]" Program="dup drop"/>
23 <StackStep Stack="[2, 2, 3]" Program="drop"/>
24 <StackStep Stack="[2, 3]"/>
25 <p>Or</p>
26 <StackStep Stack="[0, 2, 3]" Program="if dup then drop"/>
27 <StackStep Stack="[2, 3]" Program="drop"/>
28 <StackStep Stack="[3]"/>
29 </StackOp>
30
31 <StackOp Name="= <> < > <= >="
32 Description="Compares the top two values and leaves a flag in their place, true or false, which 'if' can take straight off the stack. They read in the order they are written, so '2 3 <' asks whether 2 is below 3.">
33 <StackStep Stack="[]" Program="2 3 < if 10 then"/>
34 <StackStep Stack="[2]" Program="3 < if 10 then"/>
35 <StackStep Stack="[3, 2]" Program="< if 10 then"/>
36 <StackStep Stack="[true]" Program="if 10 then"/>
37 <StackStep Stack="[]" Program="10"/>
38 <StackStep Stack="[10] <=="/>
39 </StackOp>
40
41 <StackOp Name="true false" Description="Puts a flag on the stack, the same one a comparison leaves behind.">
42 <StackStep Stack="[3]" Program="true"/>
43 <StackStep Stack="[true, 3]"/>
44 </StackOp>
45
46 <StackOp Name="and" Description="True only if both flags on top of the stack are true.">
47 <StackStep Stack="[true, false]" Program="and"/>
48 <StackStep Stack="[false]"/>
49 </StackOp>
50
51 <StackOp Name="or" Description="True if either of the two flags on top of the stack is true.">
52 <StackStep Stack="[true, false]" Program="or"/>
53 <StackStep Stack="[true]"/>
54 </StackOp>
55
56 <StackOp Name="invert" Description="Turns the flag on top of the stack into its opposite.">
57 <StackStep Stack="[false]" Program="invert"/>
58 <StackStep Stack="[true]"/>
59 </StackOp>
60
61 <StackOp Name=": word ... ;" Description="Creates a new definition.">
62 <p>
63 Example: ": double 2 * ;" defines a new word called double. Any subsequent mention of double will
64 replace the word with its definition.
65 </p>
66 <StackStep Stack="[]" Program=": double 2 * ; 3 double"/>
67 <StackStep Stack="[]" Program="3 double"/>
68 <StackStep Stack="[3]" Program="double"/>
69 <StackStep Stack="[3]" Program="2 *"/>
70 <StackStep Stack="[2, 3]" Program="*"/>
71 <StackStep Stack="[6] <=="/>
72 </StackOp>
73
74 <StackOp Name=",,"
75 Description="Unquotes the string on top of the stack: its words are put back in front of the program and run as if they had been written there.">
76 <StackStep Stack="[5]" Program="&quot; 2 * &quot; ,,"/>
77 <StackStep Stack="[ 2 * , 5]" Program=",,"/>
78 <StackStep Stack="[5]" Program="2 *"/>
79 <StackStep Stack="[2, 5]" Program="*"/>
80 <StackStep Stack="[10] <=="/>
81 </StackOp>
82 </Panel>
83
84 <Panel Legend="Example programs">
85 <details>
86 <summary>Fahrenheit to Celsius</summary>
87 <NavLink href="/concat?in=FwAgZgfAxisMwCYQFoQFYQCoQE4QHoQBuAKAQEYlIog">
88 Replace program
89 </NavLink>
90 <pre>
91 : f>c 32 - 5 * 9 / ;
92 212 f>c
93 </pre>
94 </details>
95
96 <details>
97 <summary>Countdown</summary>
98 <NavLink
99 href="/concat?in=FwAgxg9grgdgLgEwgdxidCoAcQEsBmIAjCALTjTxKohwAWApmgNwBQArBbIijEA">
100 Replace program
101 </NavLink>
102 <p>A word that calls itself is the only loop there is, and 'if' is what stops it.</p>
103 <pre>
104 : countdown dup if 1 - countdown then ;
105 5 countdown
106 </pre>
107 </details>
108
109 <details>
110 <summary>Factorial</summary>
111 <NavLink
112 href="/concat?in=FwAghCkCYK4A4gIwgHwgJYDMSwcgtOCAFQgAuAFgKYB2IA3AFADs4QA">
113 Replace program
114 </NavLink>
115 <pre>
116 : ! dup 1 > if dup 1 - ! * then ;
117 7 !
118 </pre>
119 </details>
120
121 <details>
122 <summary>Fibonacci</summary>
123 <NavLink
124 href="/concat?in=FwAgZglgRisCYFcAOICMIB8IJhIl6AtONCAM4DuAhigEwjGQwDUIALgBYCmAdiANwAoAGwkoQA">
125 Replace program
126 </NavLink>
127 <p>
128 Every number in the sequence 0, 1, 1, 2, 3, 5, 8 is the sum of the two before it, so 'fib' calls
129 itself twice: once for each of them, with 'swap' digging the original number back out from under the
130 first result.
131 </p>
132 <pre>
133 : fib dup 1 > if dup 1 - fib swap 2 - fib + then ;
134 6 fib
135 </pre>
136 </details>
137
138 <details>
139 <summary>Quoting</summary>
140 <NavLink
141 href="/concat?in=FwAgJg9grgRgNgUxMgRCATCAVCNAaPEAbgChQBHKAQzACcoAHRZcaeJSWZ0gVhEpr0mCIA">
142 Replace program
143 </NavLink>
144 <p>A string is data sitting on the stack until ',,' puts it back into the program, where it is code again.</p>
145 <pre>
146 : double " 2 * " ,, ;
147 : quadruple double double ;
148 5 quadruple
149 </pre>
150 </details>
151 </Panel>
152 </main>