Changes between Version 2 and Version 3 of PIR Tutorial

Show
Ignore:
Timestamp:
03/22/09 15:29:43 (13 years ago)
Author:
gaurav
Comment:

Added the rest of the content

Legend:

Unmodified
Added
Removed
Modified
  • PIR Tutorial

    v2 v3  
    7777Now we know how to store numbers and strings, let's do some operations on those values. 
    7878 
    79 == Calculating things == 
     79=== Calculating things === 
    8080 
    8181Calculating things is as trivial as you might expect. We'll give some full examples below, so you can copy+paste the code and run it yourself: 
    8282 
    83 === ABC formula === 
     83==== ABC formula ==== 
    8484 
    8585{{{ 
     
    133133}}} 
    134134 
    135 The dot is short in PIR for the concat operation. It takes 2 strings and concatenates them. Just as the assignment operations in the ABC formula example (x2 /= $N3), this can also be done with strings using the .= operator. 
     135The dot is short in PIR for the concat operation. It takes 2 strings and concatenates them. Just as the assignment operations in the ABC formula example `(x2 /= $N3)`, this can also be done with strings using the `.=` operator. 
    136136 
    137137As mentioned, Parrot has many instructions. This tutorial will not list all of them, but instead you could take a look at [http://docs.parrot.org/parrot/latest/html/ops.html the list of ops by category]. 
     138 
     139=== More on subroutines === 
     140 
     141This section will discuss a little bit more on subroutines so you can do some useful stuff. Although there's much more to subroutines, we'll postpone that to a later section. 
     142Passing parameters 
     143 
     144In order to pass parameters to a sub, you'll need to define these parameters. This is easy: 
     145{{{ 
     146  .sub foo 
     147    .param int n 
     148    .param string message 
     149    # do something useful 
     150  .end 
     151}}} 
     152 
     153Sometimes you want a subroutine that might take a parameter, depending on the situation. In that case you'd want to use optional parameters. 
     154Returning values 
     155 
     156If you remember the example in which we implemented the ABC formula, you could see that we calculated them, but only printed them. Usually, you'd like to have some subroutine calculate something and then return the answers. Instead of printing them, you could return the answers, as shown in this code snippet: 
     157{{{ 
     158  .sub abc 
     159    .local num x1, x2 
     160    # do some calculations 
     161    .return (x1, x2) 
     162  .end 
     163}}} 
     164 
     165=== Invoking subroutines === 
     166 
     167Now you know how to define parameters and return values, it's time to explore how to invoke your subroutine. Some examples: 
     168{{{ 
     169  .sub main 
     170    # invoke 'foo' without parameters, no return values 
     171    foo() 
     172     
     173    # invoke 'bar' with parameters $I0, 42, and "hi", no return values 
     174    $N0 = 3.14 
     175    bar($I0, 42, "hi") 
     176 
     177    # invoke 'baz' with parameters $N2, "hello yourself", and return values 
     178    .local int a 
     179    .local num b 
     180    .local string c 
     181    $N2 = 2.7 
     182    (a, b, c) = baz($N2, "hello yourself") 
     183 
     184  .end 
     185 
     186  .sub foo 
     187    print "Foo!\n" 
     188  .end 
     189 
     190  .sub bar 
     191    .param num i 
     192    .param int answer 
     193    .param string message 
     194    print "Bar!\n" 
     195    print i 
     196    print "\n" 
     197    print answer 
     198    print "\n" 
     199    print message 
     200  .end 
     201 
     202  .sub baz 
     203    .param num e 
     204    .param string msg 
     205    print "Baz!\n" 
     206    print e 
     207    print "\n" 
     208    print msg 
     209    .return (1000, 1.23, "hi from baz")  
     210  .end 
     211}}} 
     212 
     213=== Controlling the flow of your program === 
     214 
     215PIR as a few instructions to control the flow of your program. This section describes them. 
     216 
     217==== Goto statements ==== 
     218 
     219The most basic one is of course the goto instruction. It's very simple: 
     220{{{ 
     221    ... 
     222    goto L1 
     223  L1: 
     224    print "hi!\n" 
     225    ... 
     226}}} 
     227 
     228Although the use of goto is not adviced in high-level languages (HLLs), in PIR you are hardly able to write useful programs without it. Besides, PIR is assembly language after all, so that's ok. 
     229 
     230==== If statements ==== 
     231 
     232PIR has a built-in if statement. It can take three forms: 
     233 
     234Evaluate an atomic expression: 
     235{{{ 
     236    ... 
     237    .local int x 
     238    x = 1 
     239 
     240    if x goto L1 
     241    ... 
     242  L1: 
     243}}} 
     244 
     245Evaluate a binary expression: 
     246{{{ 
     247  ... 
     248  .local int x 
     249  x = 1 
     250   
     251  if x == 2 goto L2 
     252  ... 
     253}}} 
     254 
     255Evaluate an object expression: 
     256{{{ 
     257  ... 
     258  .local pmc obj 
     259   
     260  if null obj goto L3 
     261  ... 
     262}}} 
     263 
     264If obj is null, then the execution engine will continue at label L3. More on PMCs soon. 
     265 
     266==== Unless statements ==== 
     267 
     268While an if statement is useful, it is sometimes more efficient to use the unless instruction. It's the opposite of the if statement, and jumps to the specified label unless its argument is true. Its format is exactly the same as the if statement, except the word if is replaced by unless. So you should be able to figure out how to write the unless instruction. 
     269Loop constructions 
     270 
     271PIR has no built-in while or for statement, but implementing a loop can be easily done using the if statement, some *goto*s and a couple of labels, like this: 
     272{{{ 
     273    ... 
     274    .local int i 
     275    i = 0 
     276  loop_begin: 
     277    if i >= 10 goto loop_end 
     278    print i 
     279    print "\n" 
     280    i += 1 
     281    goto loop_begin 
     282  loop_end: 
     283    ... 
     284}}} 
     285 
     286this loop will print the numbers 0 to (but not including) 10 to the screen. 
     287 
     288==== Splitting your program into several files ==== 
     289 
     290Sometimes it's easier to split up your program into multiple files. There are two ways to do this: 
     291 * use the .include directive 
     292 * compile the PIR files separately and load them using load_bytecode 
     293 
     294The first way is the simplest. Use the .include directive at a point in your main file where you'd like to pull in the contents of another file. The contents of the specified file is read and replaces the .include directive, just as the #include directive does in the C preprocessor. 
     295 
     296An example will show what happens: 
     297 
     298contents of the main file: 
     299{{{ 
     300  .sub main 
     301    foo() 
     302  .end 
     303 
     304  .include "foolib.pir" 
     305}}} 
     306 
     307And the file foolib.pir contains: 
     308{{{ 
     309  .sub foo 
     310    print "foo!\n" 
     311  .end 
     312}}} 
     313 
     314After processing the .include directive, the input to the PIR compiler looks like this: 
     315{{{ 
     316  .sub main 
     317    foo() 
     318  .end 
     319 
     320  .sub foo 
     321    print "foo!\n" 
     322  .end 
     323}}} 
    138324 
    139325== Where to read further? == #further-reading