Y combinator: Difference between revisions
Content deleted Content added
m →{{header|Tailspin}}: syntax update |
add task to ARM64 assembly Raspberry Pi |
||
Line 16: | Line 16: | ||
* [http://vimeo.com/45140590 Jim Weirich: Adventures in Functional Programming] |
* [http://vimeo.com/45140590 Jim Weirich: Adventures in Functional Programming] |
||
<br><br> |
<br><br> |
||
=={{header|AArch64 Assembly}}== |
|||
{{works with|as|Raspberry Pi 3B version Buster 64 bits}} |
|||
<lang AArch64 Assembly> |
|||
/* ARM assembly AARCH64 Raspberry PI 3B */ |
|||
/* program Ycombi64.s */ |
|||
/*******************************************/ |
|||
/* Constantes file */ |
|||
/*******************************************/ |
|||
/* for this file see task include a file in language AArch64 assembly*/ |
|||
.include "../includeConstantesARM64.inc" |
|||
/*******************************************/ |
|||
/* Structures */ |
|||
/********************************************/ |
|||
/* structure function*/ |
|||
.struct 0 |
|||
func_fn: // next element |
|||
.struct func_fn + 8 |
|||
func_f_: // next element |
|||
.struct func_f_ + 8 |
|||
func_num: |
|||
.struct func_num + 8 |
|||
func_fin: |
|||
/* Initialized data */ |
|||
.data |
|||
szMessStartPgm: .asciz "Program start \n" |
|||
szMessEndPgm: .asciz "Program normal end.\n" |
|||
szMessError: .asciz "\033[31mError Allocation !!!\n" |
|||
szFactorielle: .asciz "Function factorielle : \n" |
|||
szFibonacci: .asciz "Function Fibonacci : \n" |
|||
szCarriageReturn: .asciz "\n" |
|||
/* datas message display */ |
|||
szMessResult: .ascii "Result value : @ \n" |
|||
/* UnInitialized data */ |
|||
.bss |
|||
sZoneConv: .skip 100 |
|||
/* code section */ |
|||
.text |
|||
.global main |
|||
main: // program start |
|||
ldr x0,qAdrszMessStartPgm // display start message |
|||
bl affichageMess |
|||
adr x0,facFunc // function factorielle address |
|||
bl YFunc // create Ycombinator |
|||
mov x19,x0 // save Ycombinator |
|||
ldr x0,qAdrszFactorielle // display message |
|||
bl affichageMess |
|||
mov x20,#1 // loop counter |
|||
1: // start loop |
|||
mov x0,x20 |
|||
bl numFunc // create number structure |
|||
cmp x0,#-1 // allocation error ? |
|||
beq 99f |
|||
mov x1,x0 // structure number address |
|||
mov x0,x19 // Ycombinator address |
|||
bl callFunc // call |
|||
ldr x0,[x0,#func_num] // load result |
|||
ldr x1,qAdrsZoneConv // and convert ascii string |
|||
bl conversion10S // decimal conversion |
|||
ldr x0,qAdrszMessResult |
|||
ldr x1,qAdrsZoneConv |
|||
bl strInsertAtCharInc // insert result at @ character |
|||
bl affichageMess // display message final |
|||
add x20,x20,#1 // increment loop counter |
|||
cmp x20,#10 // end ? |
|||
ble 1b // no -> loop |
|||
/*********Fibonacci *************/ |
|||
adr x0,fibFunc // function fibonacci address |
|||
bl YFunc // create Ycombinator |
|||
mov x19,x0 // save Ycombinator |
|||
ldr x0,qAdrszFibonacci // display message |
|||
bl affichageMess |
|||
mov x20,#1 // loop counter |
|||
2: // start loop |
|||
mov x0,x20 |
|||
bl numFunc // create number structure |
|||
cmp x0,#-1 // allocation error ? |
|||
beq 99f |
|||
mov x1,x0 // structure number address |
|||
mov x0,x19 // Ycombinator address |
|||
bl callFunc // call |
|||
ldr x0,[x0,#func_num] // load result |
|||
ldr x1,qAdrsZoneConv // and convert ascii string |
|||
bl conversion10S |
|||
ldr x0,qAdrszMessResult |
|||
ldr x1,qAdrsZoneConv |
|||
bl strInsertAtCharInc // insert result at @ character |
|||
bl affichageMess |
|||
add x20,x20,#1 // increment loop counter |
|||
cmp x20,#10 // end ? |
|||
ble 2b // no -> loop |
|||
ldr x0,qAdrszMessEndPgm // display end message |
|||
bl affichageMess |
|||
b 100f |
|||
99: // display error message |
|||
ldr x0,qAdrszMessError |
|||
bl affichageMess |
|||
100: // standard end of the program |
|||
mov x0,0 // return code |
|||
mov x8,EXIT // request to exit program |
|||
svc 0 // perform system call |
|||
qAdrszMessStartPgm: .quad szMessStartPgm |
|||
qAdrszMessEndPgm: .quad szMessEndPgm |
|||
qAdrszFactorielle: .quad szFactorielle |
|||
qAdrszFibonacci: .quad szFibonacci |
|||
qAdrszMessError: .quad szMessError |
|||
qAdrszCarriageReturn: .quad szCarriageReturn |
|||
qAdrszMessResult: .quad szMessResult |
|||
qAdrsZoneConv: .quad sZoneConv |
|||
/******************************************************************/ |
|||
/* factorielle function */ |
|||
/******************************************************************/ |
|||
/* x0 contains the Y combinator address */ |
|||
/* x1 contains the number structure */ |
|||
facFunc: |
|||
stp x1,lr,[sp,-16]! // save registers |
|||
stp x2,x3,[sp,-16]! // save registers |
|||
mov x2,x0 // save Y combinator address |
|||
ldr x0,[x1,#func_num] // load number |
|||
cmp x0,#1 // > 1 ? |
|||
bgt 1f // yes |
|||
mov x0,#1 // create structure number value 1 |
|||
bl numFunc |
|||
b 100f |
|||
1: |
|||
mov x3,x0 // save number |
|||
sub x0,x0,#1 // decrement number |
|||
bl numFunc // and create new structure number |
|||
cmp x0,#-1 // allocation error ? |
|||
beq 100f |
|||
mov x1,x0 // new structure number -> param 1 |
|||
ldr x0,[x2,#func_f_] // load function address to execute |
|||
bl callFunc // call |
|||
ldr x1,[x0,#func_num] // load new result |
|||
mul x0,x1,x3 // and multiply by precedent |
|||
bl numFunc // and create new structure number |
|||
// and return her address in x0 |
|||
100: |
|||
ldp x2,x3,[sp],16 // restaur 2 registers |
|||
ldp x1,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
/******************************************************************/ |
|||
/* fibonacci function */ |
|||
/******************************************************************/ |
|||
/* x0 contains the Y combinator address */ |
|||
/* x1 contains the number structure */ |
|||
fibFunc: |
|||
stp x1,lr,[sp,-16]! // save registers |
|||
stp x2,x3,[sp,-16]! // save registers |
|||
stp x4,x5,[sp,-16]! // save registers |
|||
mov x2,x0 // save Y combinator address |
|||
ldr x0,[x1,#func_num] // load number |
|||
cmp x0,#1 // > 1 ? |
|||
bgt 1f // yes |
|||
mov x0,#1 // create structure number value 1 |
|||
bl numFunc |
|||
b 100f |
|||
1: |
|||
mov x3,x0 // save number |
|||
sub x0,x0,#1 // decrement number |
|||
bl numFunc // and create new structure number |
|||
cmp x0,#-1 // allocation error ? |
|||
beq 100f |
|||
mov x1,x0 // new structure number -> param 1 |
|||
ldr x0,[x2,#func_f_] // load function address to execute |
|||
bl callFunc // call |
|||
ldr x4,[x0,#func_num] // load new result |
|||
sub x0,x3,#2 // new number - 2 |
|||
bl numFunc // and create new structure number |
|||
cmp x0,#-1 // allocation error ? |
|||
beq 100f |
|||
mov x1,x0 // new structure number -> param 1 |
|||
ldr x0,[x2,#func_f_] // load function address to execute |
|||
bl callFunc // call |
|||
ldr x1,[x0,#func_num] // load new result |
|||
add x0,x1,x4 // add two results |
|||
bl numFunc // and create new structure number |
|||
// and return her address in x0 |
|||
100: |
|||
ldp x4,x5,[sp],16 // restaur 2 registers |
|||
ldp x2,x3,[sp],16 // restaur 2 registers |
|||
ldp x1,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
/******************************************************************/ |
|||
/* call function */ |
|||
/******************************************************************/ |
|||
/* x0 contains the address of the function */ |
|||
/* x1 contains the address of the function 1 */ |
|||
callFunc: |
|||
stp x2,lr,[sp,-16]! // save registers |
|||
ldr x2,[x0,#func_fn] // load function address to execute |
|||
blr x2 // and call it |
|||
ldp x2,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
/******************************************************************/ |
|||
/* create Y combinator function */ |
|||
/******************************************************************/ |
|||
/* x0 contains the address of the function */ |
|||
YFunc: |
|||
stp x1,lr,[sp,-16]! // save registers |
|||
mov x1,#0 |
|||
bl newFunc |
|||
cmp x0,#-1 // allocation error ? |
|||
beq 100f |
|||
str x0,[x0,#func_f_] // store function and return in x0 |
|||
100: |
|||
ldp x1,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
/******************************************************************/ |
|||
/* create structure number function */ |
|||
/******************************************************************/ |
|||
/* x0 contains the number */ |
|||
numFunc: |
|||
stp x1,lr,[sp,-16]! // save registers |
|||
stp x2,x3,[sp,-16]! // save registers |
|||
mov x2,x0 // save number |
|||
mov x0,#0 // function null |
|||
mov x1,#0 // function null |
|||
bl newFunc |
|||
cmp x0,#-1 // allocation error ? |
|||
beq 100f |
|||
str x2,[x0,#func_num] // store number in new structure |
|||
100: |
|||
ldp x2,x3,[sp],16 // restaur 2 registers |
|||
ldp x1,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
/******************************************************************/ |
|||
/* new function */ |
|||
/******************************************************************/ |
|||
/* x0 contains the function address */ |
|||
/* x1 contains the function address 1 */ |
|||
newFunc: |
|||
stp x1,lr,[sp,-16]! // save registers |
|||
stp x3,x4,[sp,-16]! // save registers |
|||
stp x5,x8,[sp,-16]! // save registers |
|||
mov x4,x0 // save address |
|||
mov x5,x1 // save adresse 1 |
|||
// allocation place on the heap |
|||
mov x0,#0 // allocation place heap |
|||
mov x8,BRK // call system 'brk' |
|||
svc #0 |
|||
mov x6,x0 // save address heap for output string |
|||
add x0,x0,#func_fin // reservation place one element |
|||
mov x8,BRK // call system 'brk' |
|||
svc #0 |
|||
cmp x0,#-1 // allocation error |
|||
beq 100f |
|||
mov x0,x6 |
|||
str x4,[x0,#func_fn] // store address |
|||
str x5,[x0,#func_f_] |
|||
str xzr,[x0,#func_num] // store zero to number |
|||
100: |
|||
ldp x5,x8,[sp],16 // restaur 2 registers |
|||
ldp x3,x4,[sp],16 // restaur 2 registers |
|||
ldp x1,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
/********************************************************/ |
|||
/* File Include fonctions */ |
|||
/********************************************************/ |
|||
/* for this file see task include a file in language AArch64 assembly */ |
|||
.include "../includeARM64.inc" |
|||
</lang> |
|||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |