Parrot programación es similar al lenguaje ensamblador programación y tienes la oportunidad de trabajar en un nivel inferior. Aquí está la lista de ejemplos de programación para que tenga en cuenta los diversos aspectos de programación Loro.
Cree un archivo llamado hello.pir que contiene el siguiente código:
.sub _main print "Hello world!\n" end .end
A continuación, ejecutar tecleando:
parrot hello.pir
Como era de esperar, se mostrará el texto 'Hello world!' en la consola, seguido de un carácter de nueva línea (debido a la \n).
En el ejemplo anterior, '.sub _main' de los estados que las instrucciones que se detallan a continuación constituyen una subrutina llamada '_main', hasta que un '.end' han encontrado. La segunda línea contiene la instrucción de impresión. En este caso, nos están pidiendo la variante de la instrucción que acepta una constante de cadena. El ensamblador se encarga de decidir qué variante de las instrucciones de uso para nosotros. La tercera línea, el 'end' instrucciones, lo que provoca que el intérprete para terminar.
Podemos modificar hola.pir a primera tienda la cadena Hello world!\n en un registro y, a continuación, utilice el registro con la instrucción de impresión.
.sub _main set S1, "Hello world!\n" print S1 end .end
Aquí hemos dicho exactamente que registrarse para usar. Sin embargo, por S1 a $S1 podemos delegar la elección de que registrarse para usar de Parrot. También es posible utilizar un = notación en lugar de escribir las instrucciones.
.sub _main $S0 = "Hello world!\n" print $S0 end .end
PIR para que sea aún más legible, llamado registros pueden ser utilizados. Estos son más tarde asignado a real registros numerados.
.sub _main .local string hello hello = "Hello world!\n" print hello end .end
El '.local' directiva indica que el registro sólo es necesario dentro de la misma unidad de compilación (es decir, entre .sub y .final). Después de un '.local' es un tipo. Esto puede ser int (para I registros), flotación (para N registros), cadena (para S registros), pmc (para P registros) o el nombre de un tipo.
Este ejemplo presenta algunas más instrucciones y sintaxis PIR. Las líneas que comienzan con # son comentarios.
.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 proporciona un poco de azúcar sintáctica que lo hacen ver más alto nivel de la asamblea. Por ejemplo:
temp = i * i
Es simplemente otra forma de escribir el más asamblea de ish:
mul temp, i, i
Y:
if i <= maxnum goto loop
Es el mismo:
le i, maxnum, loop
Y:
total += temp
Es el mismo:
add total, temp
Como regla general, cada vez que un loro instrucción modifica el contenido de un registro, que será el primer registro cuando por escrito las instrucciones en conjunto.
Como es habitual en lenguajes ensambladores, los ciclos y las selecciones se implementan en términos de bifurcaciones condicionales las declaraciones y etiquetas, como se ha indicado anteriormente. Aprendizaje Conjunto es uno de los lugares donde uso de goto no es una mala forma!
La serie de Fibonacci es definido como sigue: dos números, 1 y 1. A continuación, varias veces sumar los últimos dos números de la serie para hacer el siguiente: 1, 1, 2, 3, 5, 8, 13, y así sucesivamente. La serie de Fibonacci el fib(n) es el n'th número de la serie. He aquí una simple Parrot programa ensamblador que considera los 20 primeros números de Fibonacci:
# 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
Este es el código equivalente en 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++; }
NOTA: Es un buen punto de interés, uno de los más cortos y, sin duda, la más hermosa manera de imprimir una serie de Fibonacci en Perl es perl -le '$b=1; print $a+=$b, mientras que print $b+=$a'.
En este ejemplo, definimos una función factorial y llamar de forma recursiva para calcular el factorial.
.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
Echemos un vistazo a la _fact sub primero. Un punto en el que se evoca con respecto a las anteriores es por qué los nombres de subrutinas, todos comienzan con un carácter de subrayado. Esto se hace simplemente como una manera de mostrar que la etiqueta es global y no particular ámbito de una subrutina. Esto es importante ya que las etiquetas se hace visible a otras subrutinas.
La primera línea, .param int n, especifica que esta subrutina toma un parámetro de entero y que nos gustaría hacer referencia al registro que fue aprobada por el nombre n para el resto de la sub.
Gran parte de lo que sigue se ha visto en ejemplos anteriores, aparte de la línea siguiente:
result = _fact($I0)
Esta única línea de PIR en realidad representa unas cuantas líneas de modo PASM. En primer lugar, el valor del registro $I0 se mueve en el registro correspondiente para que sea recibido como un parámetro de entero por la _fact función. Otros que están relacionados con registros, a continuación, configurar, seguido por _fact que se invoca. A continuación, una vez _fact devuelve el valor devuelto por _fact se coloca en el registro le da el nombre.
Justo antes de que el .fin de la _fact sub, .directiva de retorno se utiliza para garantizar el valor almacenado en el registro, denominado resultado se coloca en el registro correcto para que se vea como un valor de retorno en el código que llama al sub.
La llamada a _fact en principal funciona de la misma forma como el recursivo llamar a _fact dentro de la _fact sub sí mismo. El único bit restantes de la nueva sintaxis es :principal, escrito después de .sub _main. De forma predeterminada, PIR se supone que la ejecución comienza con la primera sub en el archivo. Este comportamiento se puede modificar mediante el marcado de la subcomisión para iniciar con :principales.
Para compilar PIR a bytecode, utilice el distintivo -o y especificar un archivo de salida con la extensión .pbc.
Parrot -o factorial.cpp factorial.pir
PIR puede transformarse en PASM ejecutando:
parrot -o hello.pasm hello.pir
El modo PASM para el ejemplo final tiene este aspecto:
_main: set S30, "Hello world!\n" print S30 end
PASM no maneja asignación de registros o proporcionar apoyo para registros. También no tiene el .sub y .final las directivas, en lugar de una etiqueta en el inicio de las instrucciones.