September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -19,4 +19,6 @@ Specifically, this task also shows how to [[Loop/Break|break]] out of nested loo
*   [[Loops/N plus one half]]
*   [[Loops/Nested]]
*   [[Loops/While]]
*   [[Loops/with multiple ranges]]
*   [[Loops/Wrong ranges]]
<br><br>

View file

@ -0,0 +1,228 @@
/* ARM assembly Raspberry PI */
/* program loopnested.s */
/************************************/
/* Constantes */
/************************************/
.equ STDOUT, 1 @ Linux output console
.equ EXIT, 1 @ Linux syscall
.equ WRITE, 4 @ Linux syscall
.equ NBVALUECOL, 10
.equ NBLIGNES, 10
.equ MAXVALUE, 20
/*********************************/
/* Initialized data */
/*********************************/
.data
sMessResult: .ascii " "
sMessValeur: .fill 11, 1, ' ' @ size => 11
szCarriageReturn: .asciz "\n"
.align 4
iGraine: .int 314159
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
tiValues: .skip 4 * NBVALUECOL * NBLIGNES
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
ldr r3,iAdrtiValues
mov r4,#0 @ loop indice
mov r5,#0
mov r7,#4 * NBVALUECOL
1: @ begin loop 1
mov r0,#MAXVALUE + 1
bl genereraleas @ result 0 to MAXVALUE
mul r6,r5,r7
add r6,r4,lsl #2
str r0,[r3,r6]
add r4,#1
cmp r4,#NBVALUECOL
blt 1b
mov r4,#0
add r5,#1
cmp r5,#NBLIGNES
blt 1b
mov r4,#0 @ loop indice
mov r5,#0 @ total
ldr r3,iAdrtiValues @ table values address
2:
mul r6,r5,r7
add r6,r4,lsl #2
ldr r0,[r3,r6]
ldr r1,iAdrsMessValeur @ display value
bl conversion10 @ call conversion decimal
mov r1,#0
ldr r0,iAdrsMessResult
strb r1,[r0,#4]
ldr r0,iAdrsMessResult
bl affichageMess @ display message
ldr r0,[r3,r6]
cmp r0,#MAXVALUE
beq 3f
add r4,#1
cmp r4,#NBVALUECOL
blt 2b
ldr r0,iAdrszCarriageReturn
bl affichageMess @ display message
mov r4,#0
add r5,#1
cmp r5,#NBLIGNES
blt 2b
b 100f
3:
ldr r0,iAdrszCarriageReturn
bl affichageMess @ display message
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc #0 @ perform the system call
iAdrsMessValeur: .int sMessValeur
iAdrszCarriageReturn: .int szCarriageReturn
iAdrsMessResult: .int sMessResult
iAdrtiValues: .int tiValues
/******************************************************************/
/* display text with size calculation */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
push {r0,r1,r2,r7,lr} @ save registres
mov r2,#0 @ counter length
1: @ loop length calculation
ldrb r1,[r0,r2] @ read octet start position + index
cmp r1,#0 @ if 0 its over
addne r2,r2,#1 @ else add 1 in the length
bne 1b @ and loop
@ so here r2 contains the length of the message
mov r1,r0 @ address message in r1
mov r0,#STDOUT @ code to write to the standard output Linux
mov r7, #WRITE @ code call system "write"
svc #0 @ call systeme
pop {r0,r1,r2,r7,lr} @ restaur des 2 registres */
bx lr @ return
/******************************************************************/
/* Converting a register to a decimal unsigned */
/******************************************************************/
/* r0 contains value and r1 address area */
/* r0 return size of result (no zero final in area) */
/* area size => 11 bytes */
.equ LGZONECAL, 10
conversion10:
push {r1-r4,lr} @ save registers
mov r3,r1
mov r2,#LGZONECAL
1: @ start loop
bl divisionpar10U @ unsigned r0 <- dividende. quotient ->r0 reste -> r1
add r1,#48 @ digit
strb r1,[r3,r2] @ store digit on area
cmp r0,#0 @ stop if quotient = 0
subne r2,#1 @ else previous position
bne 1b @ and loop
@ and move digit from left of area
mov r4,#0
2:
ldrb r1,[r3,r2]
strb r1,[r3,r4]
add r2,#1
add r4,#1
cmp r2,#LGZONECAL
ble 2b
@ and move spaces in end on area
mov r0,r4 @ result length
mov r1,#' ' @ space
3:
strb r1,[r3,r4] @ store space in area
add r4,#1 @ next position
cmp r4,#LGZONECAL
ble 3b @ loop if r4 <= area size
100:
pop {r1-r4,lr} @ restaur registres
bx lr @return
/***************************************************/
/* division par 10 unsigned */
/***************************************************/
/* r0 dividende */
/* r0 quotient */
/* r1 remainder */
divisionpar10U:
push {r2,r3,r4, lr}
mov r4,r0 @ save value
//mov r3,#0xCCCD @ r3 <- magic_number lower raspberry 3
//movt r3,#0xCCCC @ r3 <- magic_number higter raspberry 3
ldr r3,iMagicNumber @ r3 <- magic_number raspberry 1 2
umull r1, r2, r3, r0 @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0)
mov r0, r2, LSR #3 @ r2 <- r2 >> shift 3
add r2,r0,r0, lsl #2 @ r2 <- r0 * 5
sub r1,r4,r2, lsl #1 @ r1 <- r4 - (r2 * 2) = r4 - (r0 * 10)
pop {r2,r3,r4,lr}
bx lr @ leave function
iMagicNumber: .int 0xCCCCCCCD
/***************************************************/
/* Generation random number */
/***************************************************/
/* r0 contains limit */
genereraleas:
push {r1-r4,lr} @ save registers
ldr r4,iAdriGraine
ldr r2,[r4]
ldr r3,iNbDep1
mul r2,r3,r2
ldr r3,iNbDep1
add r2,r2,r3
str r2,[r4] @ maj de la graine pour l appel suivant
cmp r0,#0
beq 100f
mov r1,r0 @ divisor
mov r0,r2 @ dividende
bl division
mov r0,r3 @ résult = remainder
100: @ end function
pop {r1-r4,lr} @ restaur registers
bx lr @ return
/*****************************************************/
iAdriGraine: .int iGraine
iNbDep1: .int 0x343FD
iNbDep2: .int 0x269EC3
/***************************************************/
/* integer division unsigned */
/***************************************************/
division:
/* r0 contains dividend */
/* r1 contains divisor */
/* r2 returns quotient */
/* r3 returns remainder */
push {r4, lr}
mov r2, #0 @ init quotient
mov r3, #0 @ init remainder
mov r4, #32 @ init counter bits
b 2f
1: @ loop
movs r0, r0, LSL #1 @ r0 <- r0 << 1 updating cpsr (sets C if 31st bit of r0 was 1)
adc r3, r3, r3 @ r3 <- r3 + r3 + C. This is equivalent to r3 ? (r3 << 1) + C
cmp r3, r1 @ compute r3 - r1 and update cpsr
subhs r3, r3, r1 @ if r3 >= r1 (C=1) then r3 <- r3 - r1
adc r2, r2, r2 @ r2 <- r2 + r2 + C. This is equivalent to r2 <- (r2 << 1) + C
2:
subs r4, r4, #1 @ r4 <- r4 - 1
bpl 1b @ if r4 >= 0 (N=0) then loop
pop {r4, lr}
bx lr

View file

@ -0,0 +1,43 @@
/**
Loops/Nested in Neko
Tectonics:
nekoc loops-nested.neko
neko loops-nested.neko
*/
var random = $loader.loadprim("std@random_new", 0)();
var random_int = $loader.loadprim("std@random_int", 2);
var values = $amake(10);
var row = 0;
var col = 0;
while row < 10 {
values[row] = $amake(10);
col = 0;
while col < 10 {
values[row][col] = random_int(random, 20) + 1;
col += 1;
}
row += 1;
}
/* Look for a 20 */
/*
To break out of nested loops, (without using labels and $goto),
Neko needs the value of the inner loop(s).
The break statement sets the return value of a loop expression.
Without a break, the value of a loop expression is unspecified.
*/
var inner;
row = 0;
while row < 10 {
col = 0;
inner = while col < 10 {
$print("values[", row, "][", col, "] = ", values[row][col], "\n");
if values[row][col] == 20 break true;
col += 1;
}
if $istrue(inner) break;
row += 1;
}

View file

@ -17,6 +17,6 @@ fn main() {
print!("{:2} ", item);
if item == 20 { break 'outer }
}
println!("");
println!();
}
}

View file

@ -0,0 +1,20 @@
Public Sub LoopsNested()
Dim a(1 To 10, 1 To 10) As Integer
Randomize
For i = 1 To 10
For j = 1 To 10
a(i, j) = Int(20 * Rnd) + 1
Next j
Next i
For i = 1 To 10
For j = 1 To 10
If a(i, j) <> 20 Then
Debug.Print a(i, j),
Else
i = 10 'Upperbound iterator outerloop
Exit For 'Exit For exits only innerloop
End If
Next j
Debug.Print
Next i
End Sub

View file

@ -0,0 +1,20 @@
Module Program
Sub Main()
Const ROWS = 10
Const COLS = 10
' Initialize with seed 0 to get deterministic output (may vary across .NET versions, though).
Dim rand As New Random(0)
' VB uses max index array declarations
Dim nums(ROWS - 1, COLS - 1) As Integer
For r = 0 To ROWS - 1
For c = 0 To COLS - 1
nums(r, c) = rand.Next(0, 21) ' Upper bound is exclusive.
Next
Next
' MISSING IMPLEMENTATION
End Sub
End Module

View file

@ -0,0 +1,8 @@
For r = 0 To ROWS - 1
For c = 0 To COLS - 1
Dim val = nums(r, c)
Console.WriteLine(val)
If val = 20 Then GoTo BREAK
Next
Next
BREAK:

View file

@ -0,0 +1,9 @@
Do
For r = 0 To ROWS - 1
For c = 0 To COLS - 1
Dim val = nums(r, c)
Console.WriteLine(val)
If val = 20 Then Exit Do
Next
Next
Loop While False

View file

@ -0,0 +1,9 @@
For r = 0 To ROWS - 1
Dim c = 0
Do While c <= COLS - 1
Dim val = nums(r, c)
Console.WriteLine(val)
If val = 20 Then Exit For
c += 1
Loop
Next

View file

@ -0,0 +1,10 @@
Sub Find20Impl(arr As Integer(,))
For r = 0 To arr.GetLength(0) - 1
For c = 0 To arr.GetLength(1) - 1
Dim val = arr(r, c)
Console.WriteLine(val)
If val = 20 Then Exit Sub
'If val = 20 Then Return ' Equivalent to above.
Next
Next
End Sub

View file

@ -0,0 +1 @@
Find20Impl(nums)

View file

@ -0,0 +1,10 @@
For r = 0 To ROWS - 1
For c = 0 To COLS - 1
Dim val = nums(r, c)
Console.WriteLine(val)
If val = 20 Then
r = ROWS
Exit For
End If
Next
Next

View file

@ -0,0 +1,12 @@
Dim done = False
For r = 0 To ROWS - 1
For c = 0 To COLS - 1
Dim val = nums(r, c)
Console.WriteLine(val)
If val = 20 Then
done = True
Exit For
End If
Next
If done Then Exit For
Next