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:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
|
HuKiM:
^^^^^^
1) Inhaltsverzeichnis:
°°°°°°°°°°°°°°°°°°°
1) Inhaltsverzeichnis
2) Obligatorisches
3) HuKiM?
4) Funktionsweise und Befehlsumfang
5) Hallo, Welt!
6) Referenz
2) Obligatorisches:
°°°°°°°°°°°°°°°°
Diese Dokumentation unterliegt der GPL (GNU General Public License). Der
Text ist also frei verfügbar und verwendbar. Das heißt, er darf abgeändert,
kopiert, verschenkt und verkauft werden, muss jedoch in allen späteren
Versionen immer der GPL unterliegen.
Der ursprüngliche Autor dieses Textes ist unter webmaster@bauspezis.com
zu erreichen.
3) HuKiM?:
°°°°°°°
Jeden normal Sterblichen macht schon allein die Bezeichnung 'HuKim' stutzig.
Schauen wir uns die Sache also mal näher an und lüften wir das Geheimnis
hinter diesem kryptischen Begriff.
HuKiM ist eine Programmiersprache. Die allgemein übliche Vorstellung von
einer normalen Programmiersprache trifft auf HuKiM allerdings überhaupt nicht
zu. Das wesentliche Merkmal einer Programmiersprache ist, dass man mit ihr
programmieren kann. Das kann man natürlich auch mit HuKiM. Allerdings sehr
• zeitaufwändig,
• unübersichtlich,
• nervenzehrend,
• eingeschränkt und
• fehlerreich.
Was bringt uns also diese Programmiersprache? Welche Vorteile bietet sie?
Machen wir's kurz: Sie bietet überhaupt keine Vorteile und sie bringt uns
überhaupt nichts. Jeder, der nicht Spaß am Gerät hat und auch ein reales
Leben führt, sollte hier schon aufhören, zu lesen.
Und für alle anderen: HuKiM ist ein Derivat (ich möchte es nicht unbedingt
'Weiterentwicklung' nennen — das wäre dann doch zu sarkastisch) von
Brainfuck. Diese Dokumentation baut auf vorhandenem Brainfuck-Wissen auf.
Wer noch nicht weiß, was eigentlich Brainfuck sein soll bzw. sich noch nicht
intensiv damit beschäftigt hat, sollte sich vor dem Weiterlesen informieren.
Keine Panik! Das ist gar nicht schwer. Brainfuck (und damit auch HuKiM) ist
eine der am leichtesten zu erlernenden Sprachen. In fünf Minuten ist das
erledigt.
4) Funktionsweise und Befehlsumfang:
°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
Das Ziel von Brainfuck war es, den Code möglichst lang, unleserlich und
unverständlich zu gestalten und das Programmieren so schwierig zu machen,
dass es schwieriger fast nicht mehr geht. Das ist Urban Müller offensichtlich
gut gelungen, denn seine Sprache gehört heute zu den bekanntesten
esoterischen Programmiersprachen.
Allerdings hat er noch nicht alle Register gezogen. Das versucht HuKiM nun
nachzuholen: Die Länge von Quellcodes wird bis aufs Letzte ausgereizt. Die
Unverständlichkeit steigt rapide an, was ein wenig auf Kosten der
Unleserlichkeit geht. Aber was nützt einem leserlicher Code, wenn man ihn
nicht versteht :)? Das Umsetzen von Ideen gestaltet sich nun noch einen Deut
komplizierter, da viel mehr Code geschrieben werden muss und das Einfügen
von Kommentaren nicht allzu leicht von der Hand geht.
In Brainfuck gibt es keine eindeutige Regelung dafür, wie groß bzw. klein die
Zahlen sein dürfen, die ein Speicherplatz annimmt, wie groß das Speicherband
ist und auf welcher Anfangsposition der Pointer steht. HuKiM regelt das so:
Jeder Speicherplatz nimmt eine ganze Zahl von minus unendlich bis plus
unendlich an. Bei der Ausgabe wird per Modularrechnung des absoluten
Betrages der Zahl mit 256 der ASCII-Code des Zeichens bestimmt. Nach einer
Eingabe fasst das aktuelle Feldelement grundsätzlich eine Zahl von 0 bis 255.
Die Ausdehnung des Feldes ist ebenfalls unendlich. Die Position des
Schreib-|Lesekopfes spielt demnach keine Rolle. Der Programmierer kann sich
frei in alle Richtungen bewegen.
Warum eigentlich HuKiM? Das liegt am Schreibaufwand: HuKiM ist die
Abkürzung für hundert Kilometer (Quellcode).
Nun fangen wir aber mal an, HuKiM zu lernen! Da HuKiM von Brainfuck
abgeleitet ist, können wir zumindest die acht BF-Kommandos übernehmen.
Die folgende Tabelle listet diese acht Befehle und ihre HuKiM-Entsprechungen
auf:
BF | HuKiM
~~~~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> | movePointerRight
< | movePointerLeft
+ | incrementOnCurrentPosition
- | decrementOnCurrentPosition
[ | startJJZeroLoop
] | exitJJZeroLoop
. | outputByteToConsole
, | inputByteFromConsole
Außerdem sind folgende Befehle definiert:
movePointerDown
movePointerUp
startComment
exitComment
Groß-|Kleinschreibung wird nicht beachtet. Ich erkläre die Sprache nur in
dieser leicht lesbaren Schreibweise. In der Praxis sollten die Befehle etwa
mo __VEPO()
{
int err,ight;
}
lauten. Da in HuKiM — Achtung, jetzt wirs wichtig — NUR BUCHSTABEN (A—Z)
ZUR VERWENDUNG KOMMEN, wird jedes andere Zeichen nicht beachtet. Da
Kommentare im Wesentlichen aus Buchstaben bestehen, haben wir ein
Problem: Wie kommentieren wir den Code? Eine elegante Möglichkeit ist es,
zwei von Leerzeichen getrennte Spalten einzurichten, wobei beide Spalten
Buchstaben und damit Code enthalten. Der Code ist allerdings so justiert,
dass die rechte Spalte einen lesbaren Text ergibt, der als Kommentar
aufgefasst werden kann. Wer sich für diese Variante entscheidet — viel Spaß
dabei! Eine andere Möglichkeit besteht darin, einfach die Befehle
'startComment' und 'exitComment' zu benutzen. Alles, was dazwischen steht,
hat keine Bedeutung. Diese Kommentarblöcke können verschachtelt werden.
Es lässt sich also auch kommentierter Code weg kommentieren.
So. Jetzt wissen wir also, worauf beim Programmieren zu achten ist. Dann
können wir anfangen.
Die Befehle 'movePointerRight', 'movePointerLeft',
'incrementOnCurrentPosition', 'decrementOnCurrentPosition',
'outputByteToConsole' und 'inputByteFromConsole' sind aus Brainfuck
bekannt und machen in HuKiM nichts anderes. Überspringen wir sie!
Neu sind neben den Kommentaren 'movePointerDown' und 'movePointerUp'.
Nomen est omen: Wir bewegen uns in einem zweidimensionalen Feld. Alan
Turing hat sich die Sache zwar ein Bisschen anders vorgestellt, aber das stört
nicht. Was er wollte, ist eine Maschine, mit der man theoretisch alles machen
kann. Sie scheitert aber in der Praxis an zwei Punkten:
• Der Programmieraufwand ist extrem.
• Es gibt keine unendlichen Speicherbänder.
Demnach brauchen wir uns auch nicht streng an die Vorgaben zu halten,
sondern können die Sache ein Wenig interessanter gestalten. Der
Programmieraufwand ist immer noch genau so extrem und das Speicherband
ist in einer weiteren Dimension unendlich.
Spannend wird es jetzt bei den Schleifen-Befehlen. Warum steht da eigentlich
nicht einfach 'startZeroLoop', sondern 'startJJZeroLoop'? Das liegt daran, dass
es in HuKiM nicht nur Nullschleifen gibt. Vielmehr kann jede beliebige Zahl als
Abbruchbedingung eingesetzt werden. Das erleichtert zwar leider in
bestimmten Fällen die Programmierung, verlängert allerdings den Code. Und
darauf wurde hier das Hauptaugenmerk gerichtet. Außerdem sollten alle
Buchstaben des lateinischen Alphabets eine Bedeutung haben. Ohne die
Zahlen gäbe es für J, K und Q keine Verwendung.
Zahlen kommen nur bei Schleifen zum Einsatz. Es gibt 4 Zahlensysteme: 'Q',
'JJ', 'JK', 'KJ' und 'KK'. 'Q' ist ein einfaches Strichsystem. 'QOne' steht für 1,
'QOneOneOneOneOne' für 5. Die einzige Ziffer in diesem Zahlensystem ist
'one'. Demnach kann eine 0 nicht dargestellt werden. 'JJ' entspricht dem
Dualsystem. Es kommen 'zero' und 'one' zur Verwendung. Beispiel:
'JJOneOneZero' für 6. 'JK' stellt ein Oktalsystem (Basis 8) und 'KJ' ein
Dezimalsystem (Basis 10) zur Verfügung. Der vollständige Ziffernumfang des
Systems 'KJ' besteht aus 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven',
'eight' und 'nine'. Die sechs zusätzlichen Ziffern für das Hexadezimalsystem
'KK' bilden 'letterA', 'letterB', 'letterC', 'letterD', 'letterE' und 'letterF'. Negative
Zahlen können natürlich auch erzeugt werden. Dazu steht vor der Definition
des Zahlensystems ein 'Q'. 'QKJTwoTwoNine' steht beispielsweise für -229 im
klassischen Dezimalsystem. 'QQOne' bedeutet -1.
Übrigens kann die Überspringbedingung einer Schleife auch von der
Abbruchbedingung abweichen:
inputByteFromConsole
startKJSixSixLoop startComment Wurde kein B (ASCII 66) eingegeben? exitComment
incrementOnCurrentPosition
exitKJNineZeroLoop startComment Bis zum Z (ASCII 90) erhöhen. exitComment
outputByteToConsole
Dieser Code-Abschnitt liest ein Zeichen von der Standardeingabe. Wenn es
ein großes B ist, wird ein B ausgegeben. Wenn der ASCII-Code des
eingegebenen Zeichens kleiner als 90, aber ungleich 66 ist, wird ein Z
ausgegeben. Ansonsten landet das Programm in einer Endlosschleife.
5) Hallo, Welt!:
°°°°°°°°°°°°°
Puh. Jetzt wirds interessant. Schreiben wir ein Hallo-Welt-Programm in HuKiM!
Probier es erstmal selber und vergleich dann mit diesem Code!:
movePointerUp
startQOneLoop
incrementOnCurrentPosition
exitKJOneZeroLoop
startJJZeroLoop
movePointerDown
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
movePointerUp
exitJJZeroLoop
movePointerDown
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition
startComment 65 (A) gespeichert exitComment
movePointerRight
movePointerUp
startQOneLoop
incrementOnCurrentPosition
exitKJOneZeroLoop
startJJZeroLoop
movePointerDown
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
movePointerUp
exitJJZeroLoop
movePointerDown
decrementOnCurrentPosition decrementOnCurrentPosition
decrementOnCurrentPosition
startComment 97 (a) gespeichert exitComment
movePointerRight
movePointerUp
startQOneLoop
incrementOnCurrentPosition
exitKJOneZeroLoop
startJJZeroLoop
movePointerDown
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
movePointerUp
exitJJZeroLoop
movePointerDown
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
startComment 44 (,) gespeichert exitComment
movePointerRight
movePointerUp
startQOneLoop
incrementOnCurrentPosition
exitKJOneZeroLoop
startJJZeroLoop
movePointerDown
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition
movePointerUp
exitJJZeroLoop
movePointerDown
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition
startComment 33 (!) gespeichert exitComment
movePointerRight
movePointerUp
startQOneLoop
incrementOnCurrentPosition
exitKJOneZeroLoop
startJJZeroLoop
movePointerDown
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition
movePointerUp
exitJJZeroLoop
movePointerDown
incrementOnCurrentPosition incrementOnCurrentPosition
startComment 32 ( ) gespeichert exitComment
startComment
Gespeicherte Zeichen: Aa,!
exitComment
movePointerLeft movePointerLeft movePointerLeft movePointerLeft
startComment A exitComment
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition
outputByteToConsole
movePointerRight
startComment a exitComment
outputByteToConsole
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition
outputByteToConsole
outputByteToConsole
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition
outputByteToConsole
movePointerRight
startComment , exitComment
outputByteToConsole
movePointerRight movePointerRight
startComment exitComment
outputByteToConsole
movePointerLeft movePointerLeft movePointerLeft movePointerLeft
startComment A exitComment
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition
outputByteToConsole
movePointerRight
startComment a exitComment
decrementOnCurrentPosition decrementOnCurrentPosition
decrementOnCurrentPosition decrementOnCurrentPosition
decrementOnCurrentPosition decrementOnCurrentPosition
decrementOnCurrentPosition decrementOnCurrentPosition
decrementOnCurrentPosition decrementOnCurrentPosition
outputByteToConsole
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition
outputByteToConsole
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
incrementOnCurrentPosition incrementOnCurrentPosition
outputByteToConsole
movePointerRight movePointerRight
startComment ! exitComment
outputByteToConsole
Noch interessanter sieht der Code in dieser Form aus:
movepointerupstartqoneloopincrementoncurrentpositionexitk
jonezeroloopstartjjzeroloopmovepointerdownincrementoncurr
entpositionincrementoncurrentpositionincrementoncurrentpo
sitionincrementoncurrentpositionincrementoncurrentpositio
nincrementoncurrentpositionmovepointerupexitjjzeroloopmov
epointerdownincrementoncurrentpositionincrementoncurrentp
ositionincrementoncurrentpositionincrementoncurrentpositi
onincrementoncurrentpositionmovepointerrightmovepointerup
startqoneloopincrementoncurrentpositionexitkjonezeroloops
tartjjzeroloopmovepointerdownincrementoncurrentpositionin
crementoncurrentpositionincrementoncurrentpositionincreme
ntoncurrentpositionincrementoncurrentpositionincrementonc
urrentpositionincrementoncurrentpositionincrementoncurren
tpositionincrementoncurrentpositionincrementoncurrentposi
tionmovepointerupexitjjzeroloopmovepointerdowndecrementon
currentpositiondecrementoncurrentpositiondecrementoncurre
ntpositionmovepointerrightmovepointerupstartqoneloopincre
mentoncurrentpositionexitkjonezeroloopstartjjzeroloopmove
pointerdownincrementoncurrentpositionincrementoncurrentpo
sitionincrementoncurrentpositionincrementoncurrentpositio
nmovepointerupexitjjzeroloopmovepointerdownincrementoncur
rentpositionincrementoncurrentpositionincrementoncurrentp
ositionincrementoncurrentpositionmovepointerrightmovepoin
terupstartqoneloopincrementoncurrentpositionexitkjonezero
loopstartjjzeroloopmovepointerdownincrementoncurrentposit
ionincrementoncurrentpositionincrementoncurrentpositionmo
vepointerupexitjjzeroloopmovepointerdownincrementoncurren
tpositionincrementoncurrentpositionincrementoncurrentposi
tionmovepointerrightmovepointerupstartqoneloopincrementon
currentpositionexitkjonezeroloopstartjjzeroloopmovepointe
rdownincrementoncurrentpositionincrementoncurrentposition
incrementoncurrentpositionmovepointerupexitjjzeroloopmove
pointerdownincrementoncurrentpositionincrementoncurrentpo
sitionmovepointerleftmovepointerleftmovepointerleftmovepo
interleftincrementoncurrentpositionincrementoncurrentposi
tionincrementoncurrentpositionincrementoncurrentpositioni
ncrementoncurrentpositionincrementoncurrentpositionincrem
entoncurrentpositionoutputbytetoconsolemovepointerrightou
tputbytetoconsoleincrementoncurrentpositionincrementoncur
rentpositionincrementoncurrentpositionincrementoncurrentp
ositionincrementoncurrentpositionincrementoncurrentpositi
onincrementoncurrentpositionincrementoncurrentpositioninc
rementoncurrentpositionincrementoncurrentpositionincremen
toncurrentpositionoutputbytetoconsoleoutputbytetoconsolei
ncrementoncurrentpositionincrementoncurrentpositionincrem
entoncurrentpositionoutputbytetoconsolemovepointerrightou
tputbytetoconsolemovepointerrightmovepointerrightoutputby
tetoconsolemovepointerleftmovepointerleftmovepointerleftm
ovepointerleftincrementoncurrentpositionincrementoncurren
tpositionincrementoncurrentpositionincrementoncurrentposi
tionincrementoncurrentpositionincrementoncurrentpositioni
ncrementoncurrentpositionincrementoncurrentpositionincrem
entoncurrentpositionincrementoncurrentpositionincrementon
currentpositionincrementoncurrentpositionincrementoncurre
ntpositionincrementoncurrentpositionincrementoncurrentpos
itionoutputbytetoconsolemovepointerrightdecrementoncurren
tpositiondecrementoncurrentpositiondecrementoncurrentposi
tiondecrementoncurrentpositiondecrementoncurrentpositiond
ecrementoncurrentpositiondecrementoncurrentpositiondecrem
entoncurrentpositiondecrementoncurrentpositiondecrementon
currentpositionoutputbytetoconsoleincrementoncurrentposit
ionincrementoncurrentpositionincrementoncurrentpositionin
crementoncurrentpositionincrementoncurrentpositionincreme
ntoncurrentpositionincrementoncurrentpositionoutputbyteto
consoleincrementoncurrentpositionincrementoncurrentpositi
onincrementoncurrentpositionincrementoncurrentpositioninc
rementoncurrentpositionincrementoncurrentpositionincremen
toncurrentpositionincrementoncurrentpositionoutputbytetoc
onsolemovepointerrightmovepointerrightoutputbytetoconsole
6) Referenz:
°°°°°°°°°
Zahlensysteme:
System | Basis
~~~~~~~~+~~~~~~~
Q | 1
JJ | 2
JK | 8
KJ | 10
KK | 16
Negativ-Präfix: Q
Ziffern:
zero one
two three
four five
six seven
eight nine
letterA letterB
letterC letterD
letterE letterF
Befehle:
movePointerRight movePointerLeft
movePointerDown movePointerUp
incrementOnCurrentPosition decrementOnCurrentPosition
start[Zahl]Loop exit[Zahl]Loop
outputByteToConsole inputByteFromConsole
startComment exitComment |