นกแก้ว - คู่มือฉบับย่อ

เมื่อเราป้อนโปรแกรมของเราลงใน Perl แบบเดิมก่อนอื่นจะถูกรวบรวมเป็นการแสดงภายในหรือ bytecode; จากนั้น bytecode นี้จะถูกป้อนเข้าสู่ระบบย่อยที่แยกจากกันภายใน Perl เพื่อตีความ ดังนั้นจึงมีสองขั้นตอนที่แตกต่างกันของการดำเนินการของ Perl:

  • การรวบรวมเป็น bytecode และ

  • การตีความ bytecode

สิ่งนี้ไม่ซ้ำกับ Perl ภาษาอื่น ๆ ตามการออกแบบนี้ ได้แก่ Python, Ruby, Tcl และแม้แต่ Java

นอกจากนี้เรายังทราบว่ามี Java Virtual Machine (JVM) ซึ่งเป็นสภาพแวดล้อมการดำเนินการที่ไม่ขึ้นกับแพลตฟอร์มที่แปลง Java bytecode เป็นภาษาเครื่องและเรียกใช้งาน ถ้าคุณเข้าใจแนวคิดนี้แล้วคุณจะเข้าใจ Parrot

Parrotเป็นเครื่องเสมือนที่ออกแบบมาเพื่อรวบรวมและรัน bytecode สำหรับภาษาที่ตีความได้อย่างมีประสิทธิภาพ Parrot เป็นเป้าหมายของคอมไพเลอร์ Perl 6 สุดท้ายและใช้เป็นแบ็กเอนด์สำหรับ Pugs รวมถึงภาษาอื่น ๆ เช่น Tcl, Ruby, Python เป็นต้น

นกแก้วได้รับการเขียนโดยใช้ภาษา "C" ที่เป็นที่นิยมมากที่สุด

ก่อนที่เราจะเริ่มให้ดาวน์โหลด Parrot ล่าสุดหนึ่งชุดและติดตั้งลงในเครื่องของเรา

นกแก้วลิงค์ดาวน์โหลดที่มีอยู่ในนกแก้ว CVS Snapshot ดาวน์โหลด Parrot เวอร์ชันล่าสุดและทำการติดตั้งตามขั้นตอนต่อไปนี้:

  • คลายซิปและคลายไฟล์ที่ดาวน์โหลด

  • ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้ง Perl 5 ไว้ในเครื่องแล้ว

  • ตอนนี้ทำสิ่งต่อไปนี้:

% cd parrot
% perl Configure.pl
Parrot Configure
Copyright (C) 2001 Yet Another Society
Since you're running this script, you obviously have
Perl 5 -- I'll be pulling some defaults from its configuration.
...
  • จากนั้นคุณจะถูกถามชุดคำถามเกี่ยวกับการกำหนดค่าภายในเครื่องของคุณ คุณสามารถกด return / enter สำหรับแต่ละอันได้เกือบตลอดเวลา

  • สุดท้ายคุณจะได้รับคำสั่งให้พิมพ์ - make test_progและ Parrot จะสร้างล่ามทดสอบได้สำเร็จ

  • ตอนนี้คุณควรทำการทดสอบบางอย่าง ดังนั้นพิมพ์ 'make test' และคุณจะเห็นการอ่านดังต่อไปนี้:

perl t/harness
t/op/basic.....ok,1/2 skipped:label constants unimplemented in
assembler
t/op/string....ok, 1/4 skipped:  I'm unable to write it!
All tests successful, 2 subtests skipped.
Files=2, Tests=6,......

เมื่อคุณอ่านสิ่งนี้อาจมีการทดสอบเพิ่มเติมและบางส่วนที่ข้ามไปอาจไม่ข้ามไป แต่อย่าลืมว่าไม่มีข้อใดที่จะล้มเหลว!

เมื่อคุณติดตั้งไฟล์ปฏิบัติการนกแก้วแล้วคุณสามารถดูตัวอย่างประเภทต่างๆที่ระบุไว้ในส่วน'ตัวอย่าง' ของนกแก้ว นอกจากนี้คุณสามารถตรวจสอบไดเร็กทอรีตัวอย่างในที่เก็บนกแก้ว

ปัจจุบัน Parrot สามารถยอมรับคำสั่งในการดำเนินการได้สี่รูปแบบ PIR (Parrot Intermediate Representation) ถูกออกแบบมาให้เขียนโดยคนและสร้างโดยคอมไพเลอร์ มันซ่อนรายละเอียดระดับต่ำบางอย่างเช่นวิธีการส่งผ่านพารามิเตอร์ไปยังฟังก์ชัน

PASM (Parrot Assembly) อยู่ในระดับที่ต่ำกว่า PIR ซึ่งยังคงเป็นข้อมูลที่มนุษย์สามารถอ่าน / เขียนได้และสามารถสร้างได้โดยคอมไพเลอร์ แต่ผู้เขียนต้องดูแลรายละเอียดเช่นการเรียกประชุมและการจัดสรรการลงทะเบียน PAST (Parrot Abstract Syntax Tree) ช่วยให้ Parrot ยอมรับการป้อนข้อมูลรูปแบบต้นไม้ไวยากรณ์ที่เป็นนามธรรมซึ่งมีประโยชน์สำหรับการเขียนคอมไพเลอร์เหล่านั้น

รูปแบบอินพุตทั้งหมดข้างต้นจะถูกแปลงโดยอัตโนมัติภายใน Parrot เป็น PBC (Parrot Bytecode) นี่เป็นเหมือนรหัสเครื่องจักร แต่เข้าใจโดยล่ามนกแก้ว

ไม่ได้มีจุดมุ่งหมายให้มนุษย์อ่านได้หรือมนุษย์เขียนได้ แต่ต่างจากการดำเนินการในรูปแบบอื่น ๆ ที่สามารถเริ่มต้นได้ทันทีโดยไม่ต้องใช้ขั้นตอนการประกอบ Parrot bytecode เป็นแพลตฟอร์มที่เป็นอิสระ

ชุดคำสั่ง

ชุดคำสั่ง Parrot ประกอบด้วยตัวดำเนินการทางคณิตศาสตร์และตรรกะการเปรียบเทียบและการแยกสาขา / การกระโดด (สำหรับการใช้ลูป if ... จากนั้นสร้าง ฯลฯ ) การค้นหาและจัดเก็บตัวแปรส่วนกลางและคำศัพท์การทำงานกับคลาสและอ็อบเจ็กต์การเรียกรูทีนย่อยและวิธีการพร้อม ด้วยพารามิเตอร์ I / O เธรดและอื่น ๆ

เช่นเดียวกับ Java Virtual Machine Parrot ยังช่วยให้คุณไม่ต้องกังวลเกี่ยวกับการยกเลิกการจัดสรรหน่วยความจำ

  • นกแก้วให้บริการเก็บขยะ

  • โปรแกรม Parrot ไม่จำเป็นต้องทำให้หน่วยความจำว่างอย่างชัดเจน

  • หน่วยความจำที่จัดสรรจะถูกปลดปล่อยเมื่อไม่มีการใช้งานอีกต่อไปกล่าวคือไม่มีการอ้างอิงอีกต่อไป

  • Parrot Garbage Collector ทำงานเป็นระยะเพื่อดูแลหน่วยความจำที่ไม่ต้องการ

Parrot CPU มีข้อมูลพื้นฐานสี่ประเภท:

  • IV

    ประเภทจำนวนเต็ม รับประกันว่ากว้างพอที่จะถือตัวชี้ได้

  • NV

    ประเภทจุดลอยตัวที่ไม่ขึ้นกับสถาปัตยกรรม

  • STRING

    ประเภทสตริงที่เป็นนามธรรมและไม่ขึ้นกับการเข้ารหัส

  • PMC

    สเกลาร์

สามประเภทแรกค่อนข้างอธิบายตัวเองได้ดี ประเภทสุดท้าย - คุกกี้ Parrot Magic นั้นเข้าใจยากกว่าเล็กน้อย

PMC คืออะไร?

PMC ย่อมาจาก Parrot Magic Cookie PMC แสดงโครงสร้างหรือประเภทข้อมูลที่ซับซ้อนรวมถึงประเภทข้อมูลรวม (อาร์เรย์ตารางแฮช ฯลฯ ) PMC สามารถใช้พฤติกรรมของตัวเองสำหรับการดำเนินการทางคณิตศาสตร์ตรรกะและสตริงที่ดำเนินการโดยอนุญาตให้นำพฤติกรรมเฉพาะภาษามาใช้ได้ PMC สามารถสร้างขึ้นใน Parrot ปฏิบัติการหรือโหลดแบบไดนามิกเมื่อจำเป็น

เครื่องเสมือน Perl 5 ในปัจจุบันเป็นเครื่องสแต็ก มันสื่อสารค่าระหว่างการดำเนินการโดยเก็บไว้ในสแตก การดำเนินการโหลดค่าลงในสแต็กทำทุกอย่างที่ต้องการแล้วนำผลลัพธ์กลับไปที่สแต็ก ทำงานได้ง่าย แต่ทำงานช้า

ในการบวกตัวเลขสองตัวเข้าด้วยกันคุณต้องทำการกดสามสแต็กและสองสแต็กป๊อป ที่แย่กว่านั้นสแต็กจะต้องเติบโตขึ้นในขณะรันไทม์และนั่นหมายถึงการจัดสรรหน่วยความจำเมื่อคุณไม่ต้องการจัดสรร

ดังนั้น Parrot กำลังจะทำลายประเพณีที่กำหนดไว้สำหรับเครื่องเสมือนและใช้สถาปัตยกรรมการลงทะเบียนซึ่งคล้ายกับสถาปัตยกรรมของ CPU ฮาร์ดแวร์จริง นี่มีข้อดีอีกอย่าง เราสามารถใช้เอกสารที่มีอยู่ทั้งหมดเกี่ยวกับวิธีการเขียนคอมไพเลอร์และเครื่องมือเพิ่มประสิทธิภาพสำหรับซีพียูแบบลงทะเบียนสำหรับซีพียูซอฟต์แวร์ของเรา!

Parrot มีการลงทะเบียนผู้เชี่ยวชาญสำหรับแต่ละประเภท: 32 IV register, 32 NV register, 32 string register และ 32 PMC register ใน Parrot แอสเซมเบลอร์จะมีชื่อว่า I1 ... I32, N1 ... N32, S1 ... S32, P1 ... P32 ตามลำดับ

ตอนนี้เรามาดูแอสเซมเบลอร์บางส่วน เราสามารถตั้งค่าการลงทะเบียนเหล่านี้ด้วย set operator:

set I1, 10
	set N1, 3.1415
	set S1, "Hello, Parrot"

ตัวดำเนินการของ Parrot ทั้งหมดมีรูปแบบเดียวกัน: ชื่อของตัวดำเนินการรีจิสเตอร์ปลายทางและตัวถูกดำเนินการ

มีการดำเนินการที่หลากหลายที่คุณสามารถทำได้ ตัวอย่างเช่นเราสามารถพิมพ์เนื้อหาของรีจิสเตอร์หรือค่าคงที่:

set I1, 10
print "The contents of register I1 is: "
print I1
print "\n"

คำแนะนำข้างต้นจะส่งผลให้เนื้อหาของ register I1 คือ: 10

เราสามารถดำเนินการทางคณิตศาสตร์กับรีจิสเตอร์:

# Add the contents of I2 to the contents of I1
add I1, I1, I2
# Multiply I2 by I4 and store in I3
mul I3, I2, I4
# Increment I1 by one
inc I1
# Decrement N3 by 1.5
dec N3, 1.5

เรายังสามารถดำเนินการจัดการสตริงง่ายๆ:

set S1, "fish"
set S2, "bone"
concat S1, S2       # S1 is now "fishbone"
set S3, "w"
substr S4, S1, 1, 7
concat S3, S4       # S3 is now "wishbone"
length I1, S3       # I1 is now 8

โค้ดน่าเบื่อเล็กน้อยโดยไม่มีการควบคุมการไหล สำหรับผู้เริ่มต้นนกแก้วรู้เกี่ยวกับการแตกกิ่งก้านและฉลาก สาขา op เทียบเท่ากับ goto ของ Perl:

branch TERRY
JOHN:    print "fjords\n"
         branch END
MICHAEL: print " pining"
         branch GRAHAM
TERRY:   print "It's"
         branch MICHAEL
GRAHAM:  print " for the "
         branch JOHN
END:     end

นอกจากนี้ยังสามารถทำการทดสอบอย่างง่ายเพื่อดูว่ารีจิสเตอร์มีค่าจริงหรือไม่:

set I1, 12
         set I2, 5
         mod I3, I2, I2
         if I3, REMAIND, DIVISOR
REMAIND: print "5 divides 12 with remainder "
         print I3
         branch DONE
DIVISOR: print "5 is an integer divisor of 12"
DONE:    print "\n"
         end

นี่คือสิ่งที่จะดูเหมือนใน Perl สำหรับการเปรียบเทียบ:

$i1 = 12;
    $i2 = 5;
    $i3 = $i1 % $i2;
    if ($i3) {
      print "5 divides 12 with remainder ";
      print $i3;
    } else {
      print "5 is an integer divisor of 12";
    }
    print "\n";
    exit;

นกแก้วโอเปอเรเตอร์

เรามีตัวเปรียบเทียบตัวเลขครบวงจร: eq, ne, lt, gt, le และ ge โปรดทราบว่าคุณไม่สามารถใช้ตัวดำเนินการเหล่านี้กับอาร์กิวเมนต์ประเภทที่แตกต่างกันได้ คุณอาจต้องเพิ่มคำต่อท้าย _i หรือ _n ลงใน op เพื่อบอกว่าคุณใช้อาร์กิวเมนต์ประเภทใดแม้ว่าแอสเซมเบลอร์ควรจะกำหนดสิ่งนี้ให้คุณเมื่อคุณอ่านสิ่งนี้

การเขียนโปรแกรม Parrot นั้นคล้ายกับการเขียนโปรแกรมภาษาแอสเซมบลีและคุณมีโอกาสทำงานในระดับต่ำกว่า นี่คือรายการตัวอย่างการเขียนโปรแกรมเพื่อให้คุณทราบถึงแง่มุมต่างๆของ Parrot Programming

  • คลาสสิกสวัสดีชาวโลก - - '
  • ใช้รีจิสเตอร์
  • กำลังสองรวม
  • Fibonacci Numbers
  • การคำนวณแฟกทอเรียล
  • รวบรวมไปยัง PBC
  • PIR กับ PASM

คลาสสิกสวัสดีชาวโลก - - '

สร้างไฟล์ชื่อ hello.pir ที่มีรหัสต่อไปนี้:

.sub _main
      print "Hello world!\n"
      end
  .end

จากนั้นเรียกใช้โดยพิมพ์:

parrot hello.pir

ตามที่คาดไว้สิ่งนี้จะแสดงข้อความ "Hello world!" บนคอนโซลตามด้วยบรรทัดใหม่ (เนื่องจาก \ n)

ในตัวอย่างข้างต้นนี้ ".sub _main" ระบุว่าคำสั่งที่ตามมาประกอบเป็นรูทีนย่อยชื่อ '_main' จนกว่าจะพบ ".end" บรรทัดที่สองประกอบด้วยคำแนะนำในการพิมพ์ ในกรณีนี้เรากำลังเรียกตัวแปรของคำสั่งที่ยอมรับสตริงคงที่ แอสเซมเบลอร์จะดูแลในการตัดสินใจว่าจะใช้ชุดคำสั่งใดสำหรับเรา บรรทัดที่สามมีคำสั่ง 'end' ซึ่งทำให้ล่ามยุติการทำงาน

การใช้รีจิสเตอร์

เราสามารถแก้ไข hello.pir เพื่อจัดเก็บสตริง Hello world! \ n ในรีจิสเตอร์ก่อนแล้วใช้รีจิสเตอร์นั้นกับคำสั่งการพิมพ์

.sub _main
      set S1, "Hello world!\n"
      print S1
      end
  .end

ที่นี่เราได้ระบุไว้อย่างชัดเจนว่าจะใช้การลงทะเบียนใด อย่างไรก็ตามการแทนที่ S1 ด้วย $ S1 เราสามารถมอบสิทธิ์ตัวเลือกในการลงทะเบียนเพื่อใช้กับ Parrot ได้ นอกจากนี้ยังสามารถใช้สัญกรณ์ = แทนการเขียนชุดคำสั่งได้

.sub _main
      $S0 = "Hello world!\n"
      print $S0
      end
  .end

เพื่อให้ PIR อ่านได้ง่ายยิ่งขึ้นสามารถใช้ชื่อรีจิสเตอร์ สิ่งเหล่านี้ถูกจับคู่กับการลงทะเบียนที่มีหมายเลขจริงในภายหลัง

.sub _main
      .local string hello
      hello = "Hello world!\n"
      print hello
      end
  .end

คำสั่ง ".local" ระบุว่าจำเป็นต้องมีการลงทะเบียนที่ระบุชื่อภายในหน่วยคอมไพล์ปัจจุบันเท่านั้น (นั่นคือระหว่าง. sub และ. end) การติดตาม ".local" เป็นประเภทหนึ่ง ซึ่งอาจเป็น int (สำหรับ I register), float (สำหรับ N register), string (สำหรับ S register), pmc (สำหรับ P register) หรือชื่อประเภท PMC

กำลังสองรวม

ตัวอย่างนี้แนะนำคำแนะนำเพิ่มเติมและไวยากรณ์ PIR บรรทัดที่ขึ้นต้นด้วย # คือความคิดเห็น

.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 ให้น้ำตาลซินแทติกเล็กน้อยซึ่งทำให้ดูมีระดับมากกว่าการประกอบ ตัวอย่างเช่น:

temp = i * i

เป็นอีกวิธีหนึ่งในการเขียนแอสเซมบลีเพิ่มเติม:

mul temp, i, i

และ:

if i <= maxnum goto loop

เหมือนกับ:

le i, maxnum, loop

และ:

total += temp

เหมือนกับ:

add total, temp

ตามกฎแล้วเมื่อใดก็ตามที่คำสั่ง Parrot แก้ไขเนื้อหาของรีจิสเตอร์นั่นจะเป็นรีจิสเตอร์แรกเมื่อเขียนคำสั่งในรูปแบบแอสเซมบลี

ตามปกติในภาษาแอสเซมบลีการวนซ้ำและการเลือกจะถูกนำไปใช้ในรูปแบบของคำสั่งสาขาตามเงื่อนไขและป้ายกำกับดังที่แสดงไว้ด้านบน การเขียนโปรแกรม Assembly เป็นที่หนึ่งที่การใช้ goto ไม่ใช่รูปแบบที่ไม่ดี!

Fibonacci Numbers

อนุกรมฟีโบนักชีถูกกำหนดไว้เช่นนี้: ใช้ตัวเลขสองตัวคือ 1 และ 1 จากนั้นจึงบวกตัวเลขสองตัวสุดท้ายเข้าด้วยกันซ้ำ ๆ เพื่อสร้างหมายเลขถัดไป: 1, 1, 2, 3, 5, 8, 13 และอื่น ๆ . Fibonacci number fib (n) คือเลขที่ n ในอนุกรม นี่คือโปรแกรมแอสเซมเบลอร์ Parrot ง่ายๆที่ค้นหาหมายเลข Fibonacci 20 ตัวแรก:

# 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

นี่คือรหัสเทียบเท่าใน 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++;
        }

NOTE:ในฐานะที่เป็นจุดสนใจที่ดีหนึ่งในวิธีที่สั้นที่สุดและสวยงามที่สุดในการพิมพ์ชุดฟีโบนักชีใน Perl คือ perl -le '$ b = 1; พิมพ์ $ a + = $ b ในขณะที่พิมพ์ $ b + = $ a '

การคำนวณแฟกทอเรียลซ้ำ ๆ

ในตัวอย่างนี้เรากำหนดฟังก์ชันแฟกทอเรียลและเรียกมันซ้ำเพื่อคำนวณแฟกทอเรียล

.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

มาดูย่อย _fact กันก่อน จุดที่ถูกปัดสวะก่อนหน้านี้คือสาเหตุที่ชื่อของรูทีนย่อยทั้งหมดเริ่มต้นด้วยขีดล่าง! สิ่งนี้ทำขึ้นเพื่อแสดงให้เห็นว่าเลเบลเป็นแบบโกลบอลแทนที่จะกำหนดขอบเขตไปยังรูทีนย่อยเฉพาะ สิ่งนี้มีความสำคัญเนื่องจากเลเบลจะปรากฏแก่รูทีนย่อยอื่น ๆ

บรรทัดแรก. param int n ระบุว่ารูทีนย่อยนี้รับพารามิเตอร์จำนวนเต็มหนึ่งพารามิเตอร์และเราต้องการอ้างถึงรีจิสเตอร์ที่ถูกส่งโดยชื่อ n สำหรับส่วนที่เหลือของส่วนย่อย

สิ่งต่อไปนี้มีให้เห็นมากมายในตัวอย่างก่อนหน้านี้นอกเหนือจากการอ่านบรรทัด:

result = _fact($I0)

PIR บรรทัดเดียวนี้แสดงถึง PASM ไม่กี่บรรทัด ขั้นแรกค่าใน register $ I0 จะถูกย้ายไปยังรีจิสเตอร์ที่เหมาะสมเพื่อให้ได้รับเป็นพารามิเตอร์จำนวนเต็มโดยฟังก์ชัน _fact จากนั้นจะมีการตั้งค่าการลงทะเบียนอื่น ๆ ที่เกี่ยวข้องกับการโทรตามด้วย _fact ถูกเรียกใช้ จากนั้นเมื่อ _fact ส่งคืนค่าที่ส่งกลับโดย _fact จะถูกใส่ลงในรีจิสเตอร์ที่ได้รับชื่อผลลัพธ์

ก่อนหน้า. end ของย่อย _fact คำสั่ง. return ถูกใช้เพื่อให้แน่ใจว่าค่าที่เก็บไว้ในรีจิสเตอร์ ผลลัพธ์ที่ตั้งชื่อจะถูกวางลงในรีจิสเตอร์ที่ถูกต้องเพื่อให้เห็นเป็นค่าส่งคืนโดยรหัสที่เรียกซับ

การเรียก _fact ใน main ทำงานในลักษณะเดียวกับการเรียกซ้ำไปยัง _fact ภายใน _fact ย่อยเอง ไวยากรณ์ใหม่ที่เหลือเพียงบิตเดียวคือ: main เขียนตามหลัง. sub _main โดยค่าเริ่มต้น PIR จะถือว่าการเรียกใช้งานเริ่มต้นด้วยส่วนย่อยแรกในไฟล์ พฤติกรรมนี้สามารถเปลี่ยนแปลงได้โดยการทำเครื่องหมายย่อยเพื่อเริ่มต้นด้วย: main

รวบรวมไปยัง PBC

ในการคอมไพล์ PIR เป็น bytecode ให้ใช้แฟล็ก -o และระบุไฟล์เอาต์พุตที่มีนามสกุล. pbc

parrot -o factorial.pbc factorial.pir

PIR กับ PASM

PIR สามารถเปลี่ยนเป็น PASM ได้โดยเรียกใช้:

parrot -o hello.pasm hello.pir

PASM สำหรับตัวอย่างสุดท้ายมีลักษณะดังนี้:

_main:
      set S30, "Hello world!\n"
      print S30
      end

PASM ไม่จัดการการจัดสรรการลงทะเบียนหรือให้การสนับสนุนสำหรับการลงทะเบียนที่ระบุชื่อ นอกจากนี้ยังไม่มีคำสั่ง. sub และ. end ให้แทนที่ด้วยป้ายกำกับที่จุดเริ่มต้นของคำแนะนำ