Parrot - Programmierbeispiele
Parrot Programmierung ist ähnlich wie Assembler-Programmierung und Ihnen eine Chance, auf einer niedrigeren Ebene zu arbeiten. Hier ist die Liste der Programmierbeispiele Sie Kenntnis von den verschiedenen Aspekten der Parrot Programmierung zu machen.
Klassische Hallo Welt!
Erstellen Sie eine Datei namens hello.pir, die den folgenden Code enthält:
.sub _main print "Hello world!\n" end .end
Dann führen Sie es, indem Typisierung:
parrot hello.pir
Wie erwartet, wird dies den Text anzuzeigen 'Hallo Welt!' auf der Konsole, gefolgt von einer neuen Zeile (aufgrund der \ n).
In diesem Beispiel oben '.sub _main' besagt, dass die Anweisungen, die machen ein Unterprogramm mit dem Namen '_main' bis ein '.end' wird angetroffen. Die zweite Zeile enthält den Druckbefehl. In diesem Fall rufen wir die Variante des Befehls, der einen konstanten String annimmt. Der Assembler kümmert entscheiden, welche Variante der Anweisung, um für uns zu nutzen. Die dritte Zeile enthält die 'end' Befehl, der bewirkt, dass der Interpreter zu beenden.
verwendung Registern
Wir können hello.pir ändern, zu erst die Zeichenfolge speichern Hallo Welt! \ n in einem Register und verwenden Sie dann, dass mit dem Druckanweisung registrieren..
.sub _main set S1, "Hello world!\n" print S1 end .end
Hier wir haben genannt genau welche zu verwendende registrieren angegeben. Jedoch durch Ersetzen S1 mit $ S1 können wir die Wahl, welche Registrierung zur Nutzung zu Parrot delegieren. Es ist auch möglich, eine = Schreibweise anstelle des Schreibens des Satzes Anweisung verwenden.
.sub _main $S0 = "Hello world!\n" print $S0 end .end
Um PIR noch lesbar zu machen, können benannt Register verwendet werden. Diese werden später zu Echt nummerierten Register abgebildet.
.sub _main .local string hello hello = "Hello world!\n" print hello end .end
Die ".local" Richtlinie gibt an dass der benannte Register wird nur brauchte innerhalb der aktuellen Zusammenstellung erforderlich (dh zwischen .sub und .end). folgende ".local" ist eine Art. Dies kann int (für I-Register), float (für N-Register), string (für S-Register), pmc (für P-Register) oder der Name einer PMC-Typ sein..
Summiereinrichtung Quadrate
Dieses Beispiel führt einige weitere Anweisungen und PIR-Syntax. Zeilen, start-die mit einem # sind Kommentare.
.sub _main # State the number of squares to sum. .local int maxnum maxnum = 10 # Some named registers we'll use. # Note how we can declare many # registers of the same type on one line. .local int i, total, temp total = 0 # Loop to do the sum. i = 1 loop: temp = i * i total += temp inc i if i <= maxnum goto loop # Output result. print "The sum of the first " print maxnum print " squares is " print total print ".\n" end .end
PIR bietet ein bisschen syntaktischer Zucker, die es mehr hohe ebene als Montage aussehen lässt. beispielsweise:
temp = i * i
Ist nur eine andere Art des Schreibens der weitere Montage-ish:
mul temp, i, i
Und:
if i <= maxnum goto loop
Ist die gleiche wie:
le i, maxnum, loop
Und:
total += temp
Ist die gleiche wie:
add total, temp
In der Regel, wenn ein Papagei Anweisungen ändert den Inhalt eines Registers, das wird das erste Register beim Schreiben der Unterricht in Montageform sein. .
Wie üblich in Assemblersprachen, Loops und Selektionen werden in Form von bedingten Verzweigungs Aussagen und Labels umgesetzt, wie oben gezeigt. Assembler-Programmierung ist ein Ort, an dem verwendung goto ist keine schlechte Form!
Fibonacci-Zahlen
Die Fibonacci-Reihe ist wie folgt definiert: Nehmen Sie zwei Zahlen, 1 und 1. Dann wiederholt addieren die letzten beiden Zahlen in der Reihe, um die nächste: 1, 1, 2, 3, 5, 8, 13, und so weiter. Die Fibonacci-Zahl fib (n) die n-te Nummer in der Reihe. Hier ist eine einfache Parrot Assembler-Programm, das die ersten 20 Fibonacci-Zahlen findet::
# Some simple code to print some Fibonacci numbers print "The first 20 fibonacci numbers are:\n" set I1, 0 set I2, 20 set I3, 1 set I4, 1 REDO: eq I1, I2, DONE, NEXT NEXT: set I5, I4 add I4, I3, I4 set I3, I5 print I3 print "\n" inc I1 branch REDO DONE: end
Dies ist der entsprechende Code in Perl:
print "The first 20 fibonacci numbers are:\n"; my $i = 0; my $target = 20; my $a = 1; my $b = 1; until ($i == $target) { my $num = $b; $b += $a; $a = $num; print $a,"\n"; $i++; }
Hinweis: als feiner Punkt von Interesse, eine der kürzesten und sicherlich schönsten Möglichkeiten der Drucken eines Fibonacci-Reihe in Perl wird perl -le '$ b = 1; drucke $ a + = $ b, während drucke $ b + = $ a '.
rekursiv Rechen Faktoriellen
In diesem Beispiel definieren wir eine Fakultätsfunktion und rekursiv anruf Es zu berechnen faktorielle.
.sub _fact # Get input parameter. .param int n # return (n > 1 ? n * _fact(n - 1) : 1) .local int result if n > 1 goto recurse result = 1 goto return recurse: $I0 = n - 1 result = _fact($I0) result *= n return: .return (result) .end .sub _main :main .local int f, i # We'll do factorial 0 to 10. i = 0 loop: f = _fact(i) print "Factorial of " print i print " is " print f print ".\n" inc i if i <= 10 goto loop # That's it. end .end
Lassen Sie uns schauen an das _fact Sub ersten. Ein Punkt, der gegenüber früheren beschönigt wurde ist warum die Namen der Unterprogramme, alle beginnen mit einem Unterstrich! Dies wird einfach als eine Möglichkeit zu zeigen, dass die Markierung global und nicht auf eine bestimmte Subroutine scoped geführt. Dies ist von Bedeutung, wenn das Etikett wird dann auf andere Unterprogramme sichtbar. .
Die erste Zeile, .param int n, gibt an, dass dieses Unterprogramm nimmt einen Integer-Parameter und wir möchten,zu verweisen dass auf das zu registrieren wurde es weitergegeben in durch Namen n für den Rest des sub ..
Vieles von dem, was folgt, in den vorherigen Beispielen gesehen hat, abgesehen von der Zeile Lesen::
result = _fact($I0)
Das Single Zeile von PIR eigentlich stellt ganz wenigen Zeilen von PASM . Zuerst wird der Wert ist registrieren zu $ I0 ist in das entsprechende Register verschoben um es als ein ganzzahliger Parameter durch _fact Funktion empfangen werden. Andere Aufruf verbundenen Register werden dann aufgestellt, gefolgt von _fact aufgerufen wird. Dann, wenn _fact kehrt der Wert kehrte von _fact ist stellt in das Register angesichts der Name Ergebnis ..
Rechts vor dem .end der _fact sub, ein .return Direktive wird benutzt, um den Wert in dem Register gehalten zu gewährleisten; benannt Ergebnis wird in das richtige register abgelegt, um es als einen Rückgabewert durch den Code Aufruf des Unter gesehen werden..
Der Aufruf zu _fact in Hauptwerk in genau der gleichen Weise wie der rekursive Aufruf zu die _fact innerhalb der Unter _fact selbst . Die einzige verbleibende wenig neue Syntax ist: Haupt, nach .sub _main geschrieben. Standardmäßig PIR wird davon ausgegangen, dass Ausführung beginnt mit dem ersten Unter in der Datei. Dieses Verhalten kann geändert durch Kennzeichnung der sub zu start in mit :. Haupt-.
Zusammenstellung zu PBC
Zu kompilieren PIR zu Bytecode , verwenden Sie die Flagge -o, und geben Sie eine Ausgabedatei mit der Erweiterung .pbc..
parrot -o factorial.pbc factorial.pir
PIR vs. PASM
PIR können ,indem Sie in zu PASM gedreht werden durch Laufen:
parrot -o hello.pasm hello.pir
Das PASM für die endgültige Beispiel sieht wie folgt aus:
_main: set S30, "Hello world!\n" print S30 end
PASM tut nicht verarbeitet Register zuweisung oder bietet keine Unterstützung für die genannten Register. Es hat auch nicht die .sub und .end Richtlinien, anstatt sie zu ersetzen mit einem Etikett zu Beginn der Anleitung.