Ich habe eine Sprache entworfen, in der Zeigerarithmetik das Hauptwerkzeug der Programmierung ist.
Hier sind einige Beispiele.
(print 0 to 8)
=9[>1=9-*-1.>-1-1]
(print 1 to 10 with spaces in between, character literal extension used)
=1[.>1=10-*-1[>1=' '!>-2+1;-2];1]='\n'!
(compute the factorial of 10)
=10>1=*-1-1[>-1**1>1-1]>-1.
(print "hi")
=104!=105!
(print "hi" with extension for arrays)
={104,105,0}[!>1]
(print "Hello, world!" with extension for C-style string literals)
="Hello, world!"[!>1]
Sprachspezifikation
Die Sprachdefinition ist sehr einfach. Sie werden es sehr leicht verstehen, wenn Sie Erfahrung mit C haben, aber ich werde es nicht annehmen.
Jedes Programm in PointerLang hat den Zeiger , kurz gesagt P
. Sie können es sich als eine versteckte einzelne globale Variable vorstellen, die Sie mithilfe von Befehlen steuern können . P
zeigt zunächst auf den Anfang des Arrays . Jedes Element im Array hat den Typ int
einer 32-Bit-Ganzzahl mit Vorzeichen.
Für C-Programmierer
int32_t *P = malloc(1000);
In PointerLang gibt es Befehle und Argumente . Ein Argument ist ein Argument, int
das nach einem Befehl kommen muss. Alle Befehle werden von links nach rechts ausgeführt, sofern nicht anders angegeben. Das Folgende ist die Liste der Befehle. A
steht für Argument. Ein Befehl ohne A
bedeutet, dass er kein Argument benötigt. Ein Befehl mit A
muss ein Argument enthalten. In den Klammern steht der äquivalente C-Ausdruck.
=A
: A bei P zuweisen (*P = A
)+A
: füge A bei P hinzu (*P += A
)-A
: subtrahiere A bei P (*P -= A
)*A
: multipliziere mit A bei P (*P *= A
)/A
: dividiere durch A bei P (*P /= A
)>A
: bewege dichP
umA
(P += A
).
: drucke die ganze Zahl bei P (printf("%d", *P)
)!
: drucke die ganze Zahl bei P als ASCII (printf("%c", (char)*P)
)[
: Wenn der Wert bei P 0 ist, gehe zum Befehl nach dem nächsten]
(while (*P) {
)]
: gehe zum vorherigen[
, das das passende Paar ist (}
);A
: WennA
positiv ist, auf den Befehl gehen nach demA
th]
nächsten kommt; WennA
es negativ ist, gehe zumA
vorhergehenden[
. Wenn A 0 ist, nichts tun.
Ein ganzzahliges Literal ist ein Argument.
Die folgenden zwei sind spezielle Argumente, die ein Argument annehmen.
-A
: bewertet als Argument mit dem gleichen absoluten Wert wieA
und dem entgegengesetzten Vorzeichen vonA
; unäres Minus*A
: bewegeP
dich vorbeiA
, bewerte den Wert beiP
, bewege dichP
durch-A
(P[A]
)
Alle Kommentare in PointerLang stehen in Klammern (comment)
.
Beispielprogramm
Dieses Programm, das von 1 bis 10 zählt, ist ein gutes Beispiel, um Ihr Verständnis zu vervollständigen.
(print 1 to 10 with spaces in between)
=1[.>1=10-*-1[>1=32!>-2+1;-2];1]=10!
Seien Sie vorsichtig, wenn Sie interpretieren -*-1
. -
ist der Befehl und *-1
ist das Argument. Ein ganzzahliges Literal zeigt effektiv das Ende eines Befehl-Argument-Paares an.
Es kann mit 1-zu-1-Entsprechung als nach C übersetzt werden
int main(void) {
int32_t *P = malloc(1000);
*P = 1; // =1
l:
while (*P) { // [
printf("%d", *P); // .
P += 1; // > 1
*P = 10; // =10
*P -= P[-1]; // -*-1
while (*P) { // [
P += 1; // >1
*P = 32; // =32
printf("%c", (char)*P); // !
P += -2; // >-2
*P += 1; // +1
goto l; // ;-2
} // ]
break; // ;1
} // ]
*P = 10; // =10
printf("%c", (char)*P); // !
return 0;
}
Auf diese Sprache können Erweiterungen angewendet werden, z. B. Zeichenliterale, Arrays, Zeichenfolgenliterale usw., die Sie jedoch der Einfachheit halber nicht implementieren müssen.
Die Herausforderung
Sie haben die Kernfunktionen im Detail zu implementieren Language Specification Abschnitt und die nachfolgenden Ausführungen . Probieren Sie es mit Ihrer bevorzugten Programmiersprache aus und schreiben Sie das kürzestmögliche Programm.
HINWEIS 1: Die Größe des Arrays ist undefiniert. Aber es sollte groß genug sein, um die meisten Probleme zu lösen.
HINWEIS 2: Der Integer-Überlauf ist undefiniert.
HINWEIS 3: Die Spezifikation definiert nur das Ergebnis oder den Effekt bestimmter Sprachkonstrukte. Beispielsweise müssen Sie die Schritte in der Definition des Arguments nicht genau befolgen *
.
HINWEIS 4: Alle Zeichen, die keine Befehle, Argumente oder Kommentare sind, werden ignoriert. =104!=105!
ist wie = 1 0 4! = 1 05 !
zum Beispiel.
HINWEIS 5: Kommentare sind nicht verschachtelt. ((comment))
ist ein Syntaxfehler.
HINWEIS 6: Ich habe eine wichtige Änderung vorgenommen, um eine Lücke in meiner Sprache zu schließen. Der ~
Befehl wird jetzt nicht verwendet und ;
nimmt immer ein Argument an.
HINWEIS 7: Jedes ganzzahlige Literal ist dezimal.
quelle
=9[>1=9-*-1.>-1-1]
0 bis 9 druckt? Nachdem es 8 Punkte gegeben hat, weil P [0] = 1 ist, subtrahiert es 1 kurz vor dem Ende der Schleife, wodurch P [0] = 0 wird, und wenn es die Schleife erneut startet, sollte es beendet werden, weil P [0] = 0, also die Beispiel sollte nur 0 bis 8 drucken. Oder bin ich nur wirklich verwirrt?Antworten:
C 413
Vielen Dank an @ceilingcat für einige sehr schöne Golfstücke - jetzt noch kürzer
Probieren Sie es online aus!
und die etwas weniger Golfversion meiner ursprünglichen Antwort:
quelle
switch(...){case'(':...case'.':...
mitj=='('?...:j=='.'?...
und Funktionsaufrufe innerhalb des ternären Operator passen herausgerechnet .