Parrot

Eine VM für mehrere Skriptsprachen

Parrot Assembly

Einführung

Parrot Assembly, oder kurz PASM, ist die Assemblersprache der ParrotVM. PASM ist sehr nah an der ParrotVM. Jeder Befehl in PASM entspricht einen Operationscode im Bytecode. Dies bringt die üblichen Nachteile von Assembler-Sprachen mit sich.

In der Dokumentation wird von der Verwendung von PASM abgeraten, da PASM schwer leserlich und fehleranfällig ist. Die Verwendung der Parrot Intermediate Representation sollte bevorzugt werden.

In einer Einführung darf ein "Hallo Welt"-Beispiel nicht fehlen:


$ cat hallo_wedel.pasm
print "Hallo Wedel\n"
end

$ parrot hallo_wedel.pasm
Hallo Wedel

Register

Mit dem Operationscode "set" können Registerinhalte verändert werden. "print" gibt den Inhalt eines Registers aus.


$ cat register.pasm
set     I1, 42
set     N1, 4.2
set     S1, "Hallo Ohlsdorf"
print   I1
print   ", "
print   N1
print   ", "
print   S1
print   "\n"
end

$ parrot register.pasm
42, 4.200000, Hallo Ohlsdorf

Arithmetik

Für mathematischen Operationen sind natürlich auch die entsprechenden Befehle in Parrot vorhanden.


$ cat arithmetik.pasm
set     I1, 2
set     I2, 4
add     I3, I1, I2           # I3 ist nun  6 (2+4)
sub     I3, I1, I2           # I3 ist nun -2 (2-4)
mul     I3, I1, I2           # I3 ist nun  8 (2*4)
div     I3, I2, I1           # I3 ist nun  2 (4/2)
add     I1, I1, 5            # I1 ist nun  7 (2+5)
set     N1, 1
set     N2, 3
div     N3, N1, N2           # N3 ist nun  0.333333
print   I1
print   ", "
print   N3
print   "\n"
end

$ parrot arithmetik.pasm
7, 0.333333

Zeichenketten

Zeichenketten gehören in Parrot zu den grundlegenden Datentypen. Dementsprechend gibt es in Parrot Operationscodes mit denen Zeichenketten direkt verarbeitet werden können.


$ cat strings.pasm
set     S1, "Hallo"
set     S2, " Jena"
length  I1, S2               # I1 ist nun 5
print   I1
print   ", "
concat  S1, S2               # S1 ist nun "Hallo Jena"
concat  S3, S1, S2           # S3 ist nun "Hallo Jena Jena"
substr  S2, S1, 6, 5         # S2 ist nun "Jena"
chopn   S1, I1               # S1 ist nun "Hallo"
print   S1
print   ", "
print   S2
print   ", "
print   S3
print   "\n"
end

$ parrot strings.pasm
5, Hallo, Jena, Hallo Jena Jena

Parrot Magic Cookies

Parrot Magic Cookies sind zusammengesetzte Datentypen und können dynamischen Speicher benötigen. Somit müssen PMCs mit einem Befehl erzeugt werden. Dieser Befehl ist "new".

Desweiteren können Operationscodes wie "set" oder "add" ein PMC als Operand aufnehmen. Parrot greift dann mit bestimmten Methoden auf das PMC zu. Beispielsweise wird set_number() aufgerufen, um einem PMC eine Zahl zuzuweisen.


$ cat pmc.pasm
new P0, .Integer             # Klasse 'Integer' instanziieren
set P0, 123                  # Den Wert 123 zuweisen
new P1, .Integer
set P1, 321
add P1, P1, P0               # Addieren geht auch
print P1
print "\n"
end

$ parrot pmc.pasm
444

Sprünge

Bedingte Sprünge sind weitgehend selbsterklärend.


$ cat spruenge.pasm
    set     I1, 1
NOCHMAL:
    gt      I1, 10, END      # Wenn 'I1' größer '10', springe zu END
    print   I1
    print   " "
    inc     I1
    branch  NOCHMAL          # goto
END:
    print "\n"
    end

$ parrot spruenge.pasm
1 2 3 4 5 6 7 8 9 10

Unterprogramme

Ein Funktionsaufruf ist ein unbedingter Sprung (branch) mit dem Unterschied, dass die aktuelle Position auf einem Call-Stack gespeichert wird

Die Parameterübergabe erfolgt über spezielle Befehle. Dies macht es möglich, mehrere Parameter auf einmal zurückzugeben.


$ cat unterprogramm.pasm
    bsr     HELLO
    end
HELLO:
    print "Hello there!\n"
    ret

$ parrot unterprogramm.pasm
Hello there!
Erstellt von Johannes Barop