Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,5 @@
---
category:
- Data Structures
from: http://rosettacode.org/wiki/Associative_array/Creation
note: Basic language learning

View file

@ -0,0 +1,12 @@
;Task:
The goal is to create an [[associative array]] (also known as a dictionary, map, or hash).
Related tasks:
* [[Associative arrays/Iteration]]
* [[Hash from two arrays]]
{{Template:See also lists}}
<br><br>

View file

@ -0,0 +1,2 @@
V dict = [key1 = 1, key2 = 2]
V value2 = dict[key2]

View file

@ -0,0 +1 @@
{ "one" : 1, "two" : "bad" }

View file

@ -0,0 +1 @@
m:new "one" 1 m:! "two" "bad" m:!

View file

@ -0,0 +1,395 @@
/* ARM assembly AARCH64 Raspberry PI 3B or android 64 bits */
/* program hashmap64.s */
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ MAXI, 10
.equ HEAPSIZE,20000
.equ LIMIT, 10 // key characters number for compute hash
.equ COEFF, 80 // filling rate 80 = 80%
/*******************************************/
/* Structures */
/********************************************/
/* structure hashMap */
.struct 0
hash_count: // stored values counter
.struct hash_count + 8
hash_key: // key
.struct hash_key + (8 * MAXI)
hash_data: // data
.struct hash_data + (8 * MAXI)
hash_fin:
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessFin: .asciz "End program.\n"
szCarriageReturn: .asciz "\n"
szMessNoP: .asciz "Key not found !!!\n"
szKey1: .asciz "one"
szData1: .asciz "Ceret"
szKey2: .asciz "two"
szData2: .asciz "Maureillas"
szKey3: .asciz "three"
szData3: .asciz "Le Perthus"
szKey4: .asciz "four"
szData4: .asciz "Le Boulou"
.align 4
iptZoneHeap: .quad sZoneHeap // start heap address
iptZoneHeapEnd: .quad sZoneHeap + HEAPSIZE // end heap address
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
tbHashMap1: .skip hash_fin // hashmap
sZoneHeap: .skip HEAPSIZE // heap
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrtbHashMap1
bl hashInit // init hashmap
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey1 // store key one
ldr x2,qAdrszData1
bl hashInsert
cmp x0,#0 // error ?
bne 100f
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey2 // store key two
ldr x2,qAdrszData2
bl hashInsert
cmp x0,#0
bne 100f
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey3 // store key three
ldr x2,qAdrszData3
bl hashInsert
cmp x0,#0
bne 100f
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey4 // store key four
ldr x2,qAdrszData4
bl hashInsert
cmp x0,#0
bne 100f
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey2 // remove key two
bl hashRemoveKey
cmp x0,#0
bne 100f
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey1 // search key one
bl searchKey
cmp x0,#-1
beq 1f
bl affichageMess
ldr x0,qAdrszCarriageReturn
bl affichageMess
b 2f
1:
ldr x0,qAdrszMessNoP
bl affichageMess
2:
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey2 // search key two
bl searchKey
cmp x0,#-1
beq 3f
bl affichageMess
ldr x0,qAdrszCarriageReturn
bl affichageMess
b 4f
3:
ldr x0,qAdrszMessNoP
bl affichageMess
4:
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey4 // search key four
bl searchKey
cmp x0,#-1
beq 5f
bl affichageMess
ldr x0,qAdrszCarriageReturn
bl affichageMess
b 6f
5:
ldr x0,qAdrszMessNoP
bl affichageMess
6:
ldr x0,qAdrszMessFin
bl affichageMess
100: // standard end of the program
mov x0, #0 // return code
mov x8, #EXIT // request to exit program
svc #0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrszMessFin: .quad szMessFin
qAdrtbHashMap1: .quad tbHashMap1
qAdrszKey1: .quad szKey1
qAdrszData1: .quad szData1
qAdrszKey2: .quad szKey2
qAdrszData2: .quad szData2
qAdrszKey3: .quad szKey3
qAdrszData3: .quad szData3
qAdrszKey4: .quad szKey4
qAdrszData4: .quad szData4
qAdrszMessNoP: .quad szMessNoP
/***************************************************/
/* init hashMap */
/***************************************************/
// x0 contains address to hashMap
hashInit:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
mov x1,#0
mov x2,#0
str x2,[x0,#hash_count] // init counter
add x0,x0,#hash_key // start zone key/value
1:
lsl x3,x1,#3
add x3,x3,x0
str x2,[x3,#hash_key]
str x2,[x3,#hash_data]
add x1,x1,#1
cmp x1,#MAXI
blt 1b
100:
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/***************************************************/
/* insert key/datas */
/***************************************************/
// x0 contains address to hashMap
// x1 contains address to key
// x2 contains address to datas
hashInsert:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
mov x6,x0 // save address
bl hashIndex // search void key or identical key
cmp x0,#0 // error ?
blt 100f
ldr x3,qAdriptZoneHeap
ldr x3,[x3]
ldr x7,qAdriptZoneHeapEnd
ldr x7,[x7]
sub x7,x7,#50
lsl x0,x0,#3 // 8 bytes
add x5,x6,#hash_key // start zone key/value
ldr x4,[x5,x0]
cmp x4,#0 // key already stored ?
bne 1f
ldr x4,[x6,#hash_count] // no -> increment counter
add x4,x4,#1
cmp x4,#(MAXI * COEFF / 100)
bge 98f
str x4,[x6,#hash_count]
1:
str x3,[x5,x0] // store heap key address in hashmap
mov x4,#0
2: // copy key loop in heap
ldrb w5,[x1,x4]
strb w5,[x3,x4]
cmp w5,#0
add x4,x4,#1
bne 2b
add x3,x3,x4
cmp x3,x7
bge 99f
add x1,x6,#hash_data
str x3,[x1,x0] // store heap data address in hashmap
mov x4,#0
3: // copy data loop in heap
ldrb w5,[x2,x4]
strb w5,[x3,x4]
cmp w5,#0
add x4,x4,#1
bne 3b
add x3,x3,x4
cmp x3,x7
bge 99f
ldr x0,qAdriptZoneHeap
str x3,[x0] // new heap address
mov x0,#0 // insertion OK
b 100f
98: // error hashmap
adr x0,szMessErrInd
bl affichageMess
mov x0,#-1
b 100f
99: // error heap
adr x0,szMessErrHeap
bl affichageMess
mov x0,#-1
100:
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
szMessErrInd: .asciz "Error : HashMap size Filling rate Maxi !!\n"
szMessErrHeap: .asciz "Error : Heap size Maxi !!\n"
.align 4
qAdriptZoneHeap: .quad iptZoneHeap
qAdriptZoneHeapEnd: .quad iptZoneHeapEnd
/***************************************************/
/* search void index in hashmap */
/***************************************************/
// x0 contains hashMap address
// x1 contains key address
hashIndex:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
add x4,x0,#hash_key
mov x2,#0 // index
mov x3,#0 // characters sum
1: // loop to compute characters sum
ldrb w0,[x1,x2]
cmp w0,#0 // string end ?
beq 2f
add x3,x3,x0 // add to sum
add x2,x2,#1
cmp x2,#LIMIT
blt 1b
2:
mov x5,x1 // save key address
mov x0,x3
mov x1,#MAXI
udiv x2,x0,x1
msub x3,x2,x1,x0 // compute remainder -> x3
mov x1,x5 // key address
3:
ldr x0,[x4,x3,lsl #3] // loak key for computed index
cmp x0,#0 // void key ?
beq 4f
bl comparStrings // identical key ?
cmp x0,#0
beq 4f // yes
add x3,x3,#1 // no search next void key
cmp x3,#MAXI // maxi ?
csel x3,xzr,x3,ge // restart to index 0
b 3b
4:
mov x0,x3 // return index void array or key equal
100:
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/***************************************************/
/* search key in hashmap */
/***************************************************/
// x0 contains hash map address
// x1 contains key address
searchKey:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
mov x2,x0
bl hashIndex
lsl x0,x0,#3
add x1,x0,#hash_key
ldr x1,[x2,x1]
cmp x1,#0
beq 2f
add x1,x0,#hash_data
ldr x0,[x2,x1]
b 100f
2:
mov x0,#-1
100:
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/***************************************************/
/* remove key in hashmap */
/***************************************************/
// x0 contains hash map address
// x1 contains key address
hashRemoveKey:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
mov x2,x0
bl hashIndex
lsl x0,x0,#3
add x1,x0,#hash_key
ldr x3,[x2,x1]
cmp x3,#0
beq 2f
str xzr,[x2,x1] // raz key address
add x1,x0,#hash_data
str xzr,[x2,x1] // raz datas address
mov x0,0
b 100f
2:
adr x0,szMessErrRemove
bl affichageMess
mov x0,#-1
100:
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
szMessErrRemove: .asciz "\033[31mError remove key !!\033[0m\n"
.align 4
/************************************/
/* Strings case sensitive comparisons */
/************************************/
/* x0 et x1 contains the address of strings */
/* return 0 in x0 if equals */
/* return -1 if string x0 < string x1 */
/* return 1 if string x0 > string x1 */
comparStrings:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
mov x2,#0 // characters counter
1:
ldrb w3,[x0,x2] // byte string 1
ldrb w4,[x1,x2] // byte string 2
cmp w3,w4
blt 2f
bgt 3f
cmp w3,#0 // 0 end string ?
beq 4f
add x2,x2,#1 // else add 1 in counter
b 1b // and loop
2:
mov x0,#-1 // smaller
b 100f
3:
mov x0,#1 // greather
b 100f
4:
mov x0,#0 // equals
100:
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"

View file

@ -0,0 +1,70 @@
main:(
MODE COLOR = BITS;
FORMAT color repr = $"16r"16r6d$;
# This is an associative array which maps strings to ints #
MODE ITEM = STRUCT(STRING key, COLOR value);
REF[]ITEM color map items := LOC[0]ITEM;
PROC color map find = (STRING color)REF COLOR:(
REF COLOR out;
# linear search! #
FOR index FROM LWB key OF color map items TO UPB key OF color map items DO
IF color = key OF color map items[index] THEN
out := value OF color map items[index]; GO TO found
FI
OD;
NIL EXIT
found:
out
);
PROC color map = (STRING color)REF COLOR:(
REF COLOR out = color map find(color);
IF out :=: REF COLOR(NIL) THEN # extend color map array #
HEAP[UPB key OF color map items + 1]ITEM color map append;
color map append[:UPB key OF color map items] := color map items;
color map items := color map append;
value OF (color map items[UPB value OF color map items] := (color, 16r000000)) # black #
ELSE
out
FI
);
# First, populate it with some values #
color map("red") := 16rff0000;
color map("green") := 16r00ff00;
color map("blue") := 16r0000ff;
color map("my favourite color") := 16r00ffff;
# then, get some values out #
COLOR color := color map("green"); # color gets 16r00ff00 #
color := color map("black"); # accessing unassigned values assigns them to 16r0 #
# get some value out without accidentally inserting new ones #
REF COLOR value = color map find("green");
IF value :=: REF COLOR(NIL) THEN
put(stand error, ("color not found!", new line))
ELSE
printf(($"green: "f(color repr)l$, value))
FI;
# Now I changed my mind about my favourite color, so change it #
color map("my favourite color") := 16r337733;
# print out all defined colors #
FOR index FROM LWB color map items TO UPB color map items DO
ITEM item = color map items[index];
putf(stand error, ($"color map("""g""") = "f(color repr)l$, item))
OD;
FORMAT fmt;
FORMAT comma sep = $"("n(UPB color map items-1)(f(fmt)", ")f(fmt)")"$;
fmt := $""""g""""$;
printf(($g$,"keys: ", comma sep, key OF color map items, $l$));
fmt := color repr;
printf(($g$,"values: ", comma sep, value OF color map items, $l$))
)

View file

@ -0,0 +1,21 @@
⍝ Create a namespace ("hash")
X⎕NS
⍝ Assign some names
X.this'that'
X.foo88
⍝ Access the names
X.this
that
⍝ Or do it the array way
X.(foo this)
88 that
⍝ Namespaces are first class objects
sales ⎕NS
sales.(prices quantities) (100 98.4 103.4 110.16) (10 12 8 10)
sales.(revenue prices +.× quantities)
sales.revenue
4109.6

View file

@ -0,0 +1,26 @@
⍝ Assign some names
X.this'that'
X.foo88
⍝ Access the names
X.this
that
⍝ ..or access via 'array index' syntax
X['this']
that
⍝ Or do it the array way
X.(foo)
88
⍝ GNU APL does not support multiple assoc. array indices however
X.(foo this)
VALUE ERROR
X.(foo this)
^
(sales.prices sales.quantities) (100 98.4 103.4 110.16) (10 12 8 10)
sales.revenue sales.prices +.× sales.quantities
sales.revenue
4109.6

View file

@ -0,0 +1,371 @@
/* ARM assembly Raspberry PI or android 32 bits */
/* program hashmap.s */
/* */
/* REMARK 1 : this program use routines in a include file
see task Include a file language arm assembly
for the routine affichageMess conversion10
see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes */
/************************************/
.include "../constantes.inc"
.equ MAXI, 10 @ size hashmap
.equ HEAPSIZE,20000
.equ LIMIT, 10 @ key characters number for compute index
.equ COEFF, 80 @ filling rate 80 = 80%
/*******************************************/
/* Structures */
/********************************************/
/* structure hashMap */
.struct 0
hash_count: // stored values counter
.struct hash_count + 4
hash_key: // key
.struct hash_key + (4 * MAXI)
hash_data: // data
.struct hash_data + (4 * MAXI)
hash_fin:
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessFin: .asciz "End program.\n"
szCarriageReturn: .asciz "\n"
szMessNoP: .asciz "Key not found !!!\n"
szKey1: .asciz "one"
szData1: .asciz "Ceret"
szKey2: .asciz "two"
szData2: .asciz "Maureillas"
szKey3: .asciz "three"
szData3: .asciz "Le Perthus"
szKey4: .asciz "four"
szData4: .asciz "Le Boulou"
.align 4
iptZoneHeap: .int sZoneHeap // start heap address
iptZoneHeapEnd: .int sZoneHeap + HEAPSIZE // end heap address
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
//sZoneConv: .skip 24
tbHashMap1: .skip hash_fin @ hashmap
sZoneHeap: .skip HEAPSIZE @ heap
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
ldr r0,iAdrtbHashMap1
bl hashInit @ init hashmap
ldr r0,iAdrtbHashMap1
ldr r1,iAdrszKey1 @ store key one
ldr r2,iAdrszData1
bl hashInsert
cmp r0,#0 @ error ?
bne 100f
ldr r0,iAdrtbHashMap1
ldr r1,iAdrszKey2 @ store key two
ldr r2,iAdrszData2
bl hashInsert
cmp r0,#0
bne 100f
ldr r0,iAdrtbHashMap1
ldr r1,iAdrszKey3 @ store key three
ldr r2,iAdrszData3
bl hashInsert
cmp r0,#0
bne 100f
ldr r0,iAdrtbHashMap1
ldr r1,iAdrszKey4 @ store key four
ldr r2,iAdrszData4
bl hashInsert
cmp r0,#0
bne 100f
ldr r0,iAdrtbHashMap1
ldr r1,iAdrszKey2 @ remove key two
bl hashRemoveKey
cmp r0,#0
bne 100f
ldr r0,iAdrtbHashMap1
ldr r1,iAdrszKey1 @ search key
bl searchKey
cmp r0,#-1
beq 1f
bl affichageMess
ldr r0,iAdrszCarriageReturn
bl affichageMess
b 2f
1:
ldr r0,iAdrszMessNoP
bl affichageMess
2:
ldr r0,iAdrtbHashMap1
ldr r1,iAdrszKey2
bl searchKey
cmp r0,#-1
beq 3f
bl affichageMess
ldr r0,iAdrszCarriageReturn
bl affichageMess
b 4f
3:
ldr r0,iAdrszMessNoP
bl affichageMess
4:
ldr r0,iAdrtbHashMap1
ldr r1,iAdrszKey4
bl searchKey
cmp r0,#-1
beq 5f
bl affichageMess
ldr r0,iAdrszCarriageReturn
bl affichageMess
b 6f
5:
ldr r0,iAdrszMessNoP
bl affichageMess
6:
ldr r0,iAdrszMessFin
bl affichageMess
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc #0 @ perform the system call
iAdrszCarriageReturn: .int szCarriageReturn
iAdrszMessFin: .int szMessFin
iAdrtbHashMap1: .int tbHashMap1
iAdrszKey1: .int szKey1
iAdrszData1: .int szData1
iAdrszKey2: .int szKey2
iAdrszData2: .int szData2
iAdrszKey3: .int szKey3
iAdrszData3: .int szData3
iAdrszKey4: .int szKey4
iAdrszData4: .int szData4
iAdrszMessNoP: .int szMessNoP
/***************************************************/
/* init hashMap */
/***************************************************/
// r0 contains address to hashMap
hashInit:
push {r1-r3,lr} @ save registers
mov r1,#0
mov r2,#0
str r2,[r0,#hash_count] @ init counter
add r0,r0,#hash_key @ start zone key/value
1:
lsl r3,r1,#3
add r3,r3,r0
str r2,[r3,#hash_key]
str r2,[r3,#hash_data]
add r1,r1,#1
cmp r1,#MAXI
blt 1b
100:
pop {r1-r3,pc} @ restaur registers
/***************************************************/
/* insert key/datas */
/***************************************************/
// r0 contains address to hashMap
// r1 contains address to key
// r2 contains address to datas
hashInsert:
push {r1-r8,lr} @ save registers
mov r6,r0 @ save address
bl hashIndex @ search void key or identical key
cmp r0,#0 @ error ?
blt 100f
ldr r3,iAdriptZoneHeap
ldr r3,[r3]
ldr r8,iAdriptZoneHeapEnd
ldr r8,[r8]
sub r8,r8,#50
lsl r0,r0,#2 @ 4 bytes
add r7,r6,#hash_key @ start zone key/value
ldr r4,[r7,r0]
cmp r4,#0 @ key already stored ?
bne 1f
ldr r4,[r6,#hash_count] @ no -> increment counter
add r4,r4,#1
cmp r4,#(MAXI * COEFF / 100)
bge 98f
str r4,[r6,#hash_count]
1:
str r3,[r7,r0]
mov r4,#0
2: @ copy key loop in heap
ldrb r5,[r1,r4]
strb r5,[r3,r4]
cmp r5,#0
add r4,r4,#1
bne 2b
add r3,r3,r4
cmp r3,r8
bge 99f
add r7,r6,#hash_data
str r3,[r7,r0]
mov r4,#0
3: @ copy data loop in heap
ldrb r5,[r2,r4]
strb r5,[r3,r4]
cmp r5,#0
add r4,r4,#1
bne 3b
add r3,r3,r4
cmp r3,r8
bge 99f
ldr r0,iAdriptZoneHeap
str r3,[r0] @ new heap address
mov r0,#0 @ insertion OK
b 100f
98: @ error hashmap
adr r0,szMessErrInd
bl affichageMess
mov r0,#-1
b 100f
99: @ error heap
adr r0,szMessErrHeap
bl affichageMess
mov r0,#-1
100:
pop {r1-r8,lr} @ restaur registers
bx lr @ return
szMessErrInd: .asciz "Error : HashMap size Filling rate Maxi !!\n"
szMessErrHeap: .asciz "Error : Heap size Maxi !!\n"
.align 4
iAdriptZoneHeap: .int iptZoneHeap
iAdriptZoneHeapEnd: .int iptZoneHeapEnd
/***************************************************/
/* search void index in hashmap */
/***************************************************/
// r0 contains hashMap address
// r1 contains key address
hashIndex:
push {r1-r4,lr} @ save registers
add r4,r0,#hash_key
mov r2,#0 @ index
mov r3,#0 @ characters sum
1: @ loop to compute characters sum
ldrb r0,[r1,r2]
cmp r0,#0 @ string end ?
beq 2f
add r3,r3,r0 @ add to sum
add r2,r2,#1
cmp r2,#LIMIT
blt 1b
2:
mov r5,r1 @ save key address
mov r0,r3
mov r1,#MAXI
bl division @ compute remainder -> r3
mov r1,r5 @ key address
3:
ldr r0,[r4,r3,lsl #2] @ loak key for computed index
cmp r0,#0 @ void key ?
beq 4f
bl comparStrings @ identical key ?
cmp r0,#0
beq 4f @ yes
add r3,r3,#1 @ no search next void key
cmp r3,#MAXI @ maxi ?
movge r3,#0 @ restart to index 0
b 3b
4:
mov r0,r3 @ return index void array or key equal
100:
pop {r1-r4,pc} @ restaur registers
/***************************************************/
/* search key in hashmap */
/***************************************************/
// r0 contains hash map address
// r1 contains key address
searchKey:
push {r1-r2,lr} @ save registers
mov r2,r0
bl hashIndex
lsl r0,r0,#2
add r1,r0,#hash_key
ldr r1,[r2,r1]
cmp r1,#0
moveq r0,#-1
beq 100f
add r1,r0,#hash_data
ldr r0,[r2,r1]
100:
pop {r1-r2,pc} @ restaur registers
/***************************************************/
/* remove key in hashmap */
/***************************************************/
// r0 contains hash map address
// r1 contains key address
hashRemoveKey: @ INFO: hashRemoveKey
push {r1-r3,lr} @ save registers
mov r2,r0
bl hashIndex
lsl r0,r0,#2
add r1,r0,#hash_key
ldr r3,[r2,r1]
cmp r3,#0
beq 2f
add r3,r2,r1
mov r1,#0 @ raz key address
str r1,[r3]
add r1,r0,#hash_data
add r3,r2,r1
mov r1,#0
str r1,[r3] @ raz datas address
mov r0,#0
b 100f
2:
adr r0,szMessErrRemove
bl affichageMess
mov r0,#-1
100:
pop {r1-r3,pc} @ restaur registers
szMessErrRemove: .asciz "\033[31mError remove key !!\033[0m\n"
.align 4
/************************************/
/* Strings case sensitive comparisons */
/************************************/
/* r0 et r1 contains the address of strings */
/* return 0 in r0 if equals */
/* return -1 if string r0 < string r1 */
/* return 1 if string r0 > string r1 */
comparStrings:
push {r1-r4} @ save des registres
mov r2,#0 @ characters counter
1:
ldrb r3,[r0,r2] @ byte string 1
ldrb r4,[r1,r2] @ byte string 2
cmp r3,r4
movlt r0,#-1 @ smaller
movgt r0,#1 @ greather
bne 100f @ not equals
cmp r3,#0 @ 0 end string ?
moveq r0,#0 @ equals
beq 100f @ end string
add r2,r2,#1 @ else add 1 in counter
b 1b @ and loop
100:
pop {r1-r4}
bx lr
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"

View file

@ -0,0 +1,226 @@
(*------------------------------------------------------------------*)
#define ATS_DYNLOADFLAG 0
#include "share/atspre_staload.hats"
(*------------------------------------------------------------------*)
(* Interface *)
(* You can put the interface in a .sats file. You will have to remove
the word "extern". *)
typedef alist_t (key_t : t@ype+,
data_t : t@ype+,
size : int) =
list (@(key_t, data_t), size)
typedef alist_t (key_t : t@ype+,
data_t : t@ype+) =
[size : int]
alist_t (key_t, data_t, size)
extern prfun
lemma_alist_t_param :
{size : int} {key_t : t@ype} {data_t : t@ype}
alist_t (key_t, data_t, size) -<prf> [0 <= size] void
extern fun {key_t : t@ype} (* Implement key equality with this. *)
alist_t$key_eq : (key_t, key_t) -<> bool
(* alist_t_nil: create an empty association list. *)
extern fun
alist_t_nil :
{key_t : t@ype} {data_t : t@ype}
() -<> alist_t (key_t, data_t, 0)
(* alist_t_set: add an association, deleting old associations with an
equal key. *)
extern fun {key_t : t@ype}
{data_t : t@ype}
alist_t_set {size : int}
(alst : alist_t (key_t, data_t, size),
key : key_t,
data : data_t) :<>
[sz : int | 1 <= sz]
alist_t (key_t, data_t, sz)
(* alist_t_get: find an association and return its data, if
present. *)
extern fun {key_t : t@ype}
{data_t : t@ype}
alist_t_get {size : int}
(alst : alist_t (key_t, data_t, size),
key : key_t) :<>
Option data_t
(* alist_t_delete: delete all associations with key. *)
extern fun {key_t : t@ype}
{data_t : t@ype}
alist_t_delete {size : int}
(alst : alist_t (key_t, data_t, size),
key : key_t ) :<>
[sz : int | 0 <= sz]
alist_t (key_t, data_t, sz)
(* alist_t_make_pairs_generator: make a closure that returns
the association pairs, one by one. This is a form of iterator.
Analogous generators can be made for the keys or data values
alone. *)
extern fun {key_t : t@ype}
{data_t : t@ype}
alist_t_make_pairs_generator
{size : int}
(alst : alist_t (key_t, data_t, size)) :<!wrt>
() -<cloref,!refwrt> Option @(key_t, data_t)
(*------------------------------------------------------------------*)
(* Implementation *)
#define NIL list_nil ()
#define :: list_cons
primplement
lemma_alist_t_param alst =
lemma_list_param alst
implement
alist_t_nil () =
NIL
implement {key_t} {data_t}
alist_t_set (alst, key, data) =
@(key, data) :: alist_t_delete (alst, key)
implement {key_t} {data_t}
alist_t_get (alst, key) =
let
fun
loop {n : nat}
.<n>. (* <-- proof of termination *)
(lst : alist_t (key_t, data_t, n)) :<>
Option data_t =
case+ lst of
| NIL => None ()
| head :: tail =>
if alist_t$key_eq (key, head.0) then
Some (head.1)
else
loop tail
prval _ = lemma_alist_t_param alst
in
loop alst
end
implement {key_t} {data_t}
alist_t_delete (alst, key) =
let
fun
delete {n : nat}
.<n>. (* <-- proof of termination *)
(lst : alist_t (key_t, data_t, n)) :<>
[m : nat] alist_t (key_t, data_t, m) =
(* This implementation is *not* tail recursive, but has the
minor advantage of preserving the order of entries without
doing a lot of work. *)
case+ lst of
| NIL => lst
| head :: tail =>
if alist_t$key_eq (key, head.0) then
delete tail
else
head :: delete tail
prval _ = lemma_alist_t_param alst
in
delete alst
end
implement {key_t} {data_t}
alist_t_make_pairs_generator alst =
let
typedef alist_t = [sz : int] alist_t (key_t, data_t, sz)
val alst_ref = ref alst
(* Cast the ref to a pointer so it can be enclosed in the
closure. *)
val alst_ptr = $UNSAFE.castvwtp0{ptr} alst_ref
in
lam () =>
let
val alst_ref = $UNSAFE.castvwtp0{ref alist_t} alst_ptr
in
case+ !alst_ref of
| NIL => None ()
| head :: tail =>
begin
!alst_ref := tail;
(* For a keys generator, change the following line to
"Some (head.0)"; for a data values generator, change
it to "Some (head.1)". *)
Some head
end
end
end
(*------------------------------------------------------------------*)
(* Demonstration program *)
implement
alist_t$key_eq<string> (s, t) =
s = t
typedef s2i_alist_t = alist_t (string, int)
fn
s2i_alist_t_set (map : s2i_alist_t,
key : string,
data : int) :<> s2i_alist_t =
alist_t_set<string><int> (map, key, data)
fn
s2i_alist_t_set_ref (map : &s2i_alist_t >> _,
key : string,
data : int) :<!wrt> void =
(* Update a reference to a persistent alist. *)
map := s2i_alist_t_set (map, key, data)
fn
s2i_alist_t_get (map : s2i_alist_t,
key : string) :<> Option int =
alist_t_get<string><int> (map, key)
extern fun {} (* {} = a template without template parameters *)
s2i_alist_t_get_dflt$dflt :<> () -> int
fn {} (* {} = a template without template parameters *)
s2i_alist_t_get_dflt (map : s2i_alist_t,
key : string) : int =
case+ s2i_alist_t_get (map, key) of
| Some x => x
| None () => s2i_alist_t_get_dflt$dflt<> ()
overload [] with s2i_alist_t_set_ref
overload [] with s2i_alist_t_get_dflt
implement
main0 () =
let
implement s2i_alist_t_get_dflt$dflt<> () = 0
var map = alist_t_nil ()
var gen : () -<cloref1> @(string, int)
var pair : Option @(string, int)
in
map["one"] := 1;
map["two"] := 2;
map["three"] := 3;
println! ("map[\"one\"] = ", map["one"]);
println! ("map[\"two\"] = ", map["two"]);
println! ("map[\"three\"] = ", map["three"]);
println! ("map[\"four\"] = ", map["four"]);
gen := alist_t_make_pairs_generator<string><int> map;
for (pair := gen (); option_is_some pair; pair := gen ())
println! (pair)
end
(*------------------------------------------------------------------*)

View file

@ -0,0 +1,579 @@
(*------------------------------------------------------------------*)
#define ATS_DYNLOADFLAG 0
#include "share/atspre_staload.hats"
(*------------------------------------------------------------------*)
(* String hashing using XXH3_64bits from the xxHash suite. *)
#define ATS_EXTERN_PREFIX "hashmaps_postiats_"
%{^ /* Embedded C code. */
#include <xxhash.h>
ATSinline() atstype_uint64
hashmaps_postiats_mem_hash (atstype_ptr data, atstype_size len)
{
return (atstype_uint64) XXH3_64bits (data, len);
}
%}
extern fn mem_hash : (ptr, size_t) -<> uint64 = "mac#%"
fn
string_hash (s : string) :<> uint64 =
let
val len = string_length s
in
mem_hash ($UNSAFE.cast{ptr} s, len)
end
(*------------------------------------------------------------------*)
(* A trimmed down version of the AVL trees from the AVL Tree task. *)
datatype bal_t =
| bal_minus1
| bal_zero
| bal_plus1
datatype avl_t (key_t : t@ype+,
data_t : t@ype+,
size : int) =
| avl_t_nil (key_t, data_t, 0)
| {size_L, size_R : nat}
avl_t_cons (key_t, data_t, size_L + size_R + 1) of
(key_t, data_t, bal_t,
avl_t (key_t, data_t, size_L),
avl_t (key_t, data_t, size_R))
typedef avl_t (key_t : t@ype+,
data_t : t@ype+) =
[size : int] avl_t (key_t, data_t, size)
extern fun {key_t : t@ype}
avl_t$compare (u : key_t, v : key_t) :<> int
#define NIL avl_t_nil ()
#define CONS avl_t_cons
#define LNIL list_nil ()
#define :: list_cons
#define F false
#define T true
typedef fixbal_t = bool
prfn
lemma_avl_t_param {key_t : t@ype} {data_t : t@ype} {size : int}
(avl : avl_t (key_t, data_t, size)) :<prf>
[0 <= size] void =
case+ avl of NIL => () | CONS _ => ()
fn {}
minus_neg_bal (bal : bal_t) :<> bal_t =
case+ bal of
| bal_minus1 () => bal_plus1
| _ => bal_zero ()
fn {}
minus_pos_bal (bal : bal_t) :<> bal_t =
case+ bal of
| bal_plus1 () => bal_minus1
| _ => bal_zero ()
fn
avl_t_is_empty {key_t : t@ype} {data_t : t@ype} {size : int}
(avl : avl_t (key_t, data_t, size)) :<>
[b : bool | b == (size == 0)] bool b =
case+ avl of
| NIL => T
| CONS _ => F
fn
avl_t_isnot_empty {key_t : t@ype} {data_t : t@ype} {size : int}
(avl : avl_t (key_t, data_t, size)) :<>
[b : bool | b == (size <> 0)] bool b =
~avl_t_is_empty avl
fn {key_t : t@ype} {data_t : t@ype}
avl_t_search_ref {size : int}
(avl : avl_t (key_t, data_t, size),
key : key_t,
data : &data_t? >> opt (data_t, found),
found : &bool? >> bool found) :<!wrt>
#[found : bool] void =
let
fun
search (p : avl_t (key_t, data_t),
data : &data_t? >> opt (data_t, found),
found : &bool? >> bool found) :<!wrt,!ntm>
#[found : bool] void =
case+ p of
| NIL =>
{
prval _ = opt_none {data_t} data
val _ = found := F
}
| CONS (k, d, _, left, right) =>
begin
case+ avl_t$compare<key_t> (key, k) of
| cmp when cmp < 0 => search (left, data, found)
| cmp when cmp > 0 => search (right, data, found)
| _ =>
{
val _ = data := d
prval _ = opt_some {data_t} data
val _ = found := T
}
end
in
$effmask_ntm search (avl, data, found)
end
fn {key_t : t@ype} {data_t : t@ype}
avl_t_search_opt {size : int}
(avl : avl_t (key_t, data_t, size),
key : key_t) :<>
Option (data_t) =
let
var data : data_t?
var found : bool?
val _ = $effmask_wrt avl_t_search_ref (avl, key, data, found)
in
if found then
let
prval _ = opt_unsome data
in
Some {data_t} data
end
else
let
prval _ = opt_unnone data
in
None {data_t} ()
end
end
fn {key_t : t@ype} {data_t : t@ype}
avl_t_insert_or_replace {size : int}
(avl : avl_t (key_t, data_t, size),
key : key_t,
data : data_t) :<>
[sz : pos] (avl_t (key_t, data_t, sz), bool) =
let
fun
search {size : nat}
(p : avl_t (key_t, data_t, size),
fixbal : fixbal_t,
found : bool) :<!ntm>
[sz : pos]
(avl_t (key_t, data_t, sz), fixbal_t, bool) =
case+ p of
| NIL => (CONS (key, data, bal_zero, NIL, NIL), T, F)
| CONS (k, d, bal, left, right) =>
case+ avl_t$compare<key_t> (key, k) of
| cmp when cmp < 0 =>
let
val (p1, fixbal, found) = search (left, fixbal, found)
in
case+ (fixbal, bal) of
| (F, _) => (CONS (k, d, bal, p1, right), F, found)
| (T, bal_plus1 ()) =>
(CONS (k, d, bal_zero (), p1, right), F, found)
| (T, bal_zero ()) =>
(CONS (k, d, bal_minus1 (), p1, right), fixbal, found)
| (T, bal_minus1 ()) =>
let
val+ CONS (k1, d1, bal1, left1, right1) = p1
in
case+ bal1 of
| bal_minus1 () =>
let
val q = CONS (k, d, bal_zero (), right1, right)
val q1 = CONS (k1, d1, bal_zero (), left1, q)
in
(q1, F, found)
end
| _ =>
let
val p2 = right1
val- CONS (k2, d2, bal2, left2, right2) = p2
val q = CONS (k, d, minus_neg_bal bal2,
right2, right)
val q1 = CONS (k1, d1, minus_pos_bal bal2,
left1, left2)
val q2 = CONS (k2, d2, bal_zero (), q1, q)
in
(q2, F, found)
end
end
end
| cmp when cmp > 0 =>
let
val (p1, fixbal, found) = search (right, fixbal, found)
in
case+ (fixbal, bal) of
| (F, _) => (CONS (k, d, bal, left, p1), F, found)
| (T, bal_minus1 ()) =>
(CONS (k, d, bal_zero (), left, p1), F, found)
| (T, bal_zero ()) =>
(CONS (k, d, bal_plus1 (), left, p1), fixbal, found)
| (T, bal_plus1 ()) =>
let
val+ CONS (k1, d1, bal1, left1, right1) = p1
in
case+ bal1 of
| bal_plus1 () =>
let
val q = CONS (k, d, bal_zero (), left, left1)
val q1 = CONS (k1, d1, bal_zero (), q, right1)
in
(q1, F, found)
end
| _ =>
let
val p2 = left1
val- CONS (k2, d2, bal2, left2, right2) = p2
val q = CONS (k, d, minus_pos_bal bal2,
left, left2)
val q1 = CONS (k1, d1, minus_neg_bal bal2,
right2, right1)
val q2 = CONS (k2, d2, bal_zero (), q, q1)
in
(q2, F, found)
end
end
end
| _ => (CONS (key, data, bal, left, right), F, T)
in
if avl_t_is_empty avl then
(CONS (key, data, bal_zero, NIL, NIL), F)
else
let
prval _ = lemma_avl_t_param avl
val (avl, _, found) = $effmask_ntm search (avl, F, F)
in
(avl, found)
end
end
fn {key_t : t@ype} {data_t : t@ype}
avl_t_insert {size : int}
(avl : avl_t (key_t, data_t, size),
key : key_t,
data : data_t) :<>
[sz : pos] avl_t (key_t, data_t, sz) =
(avl_t_insert_or_replace<key_t><data_t> (avl, key, data)).0
fun {key_t : t@ype} {data_t : t@ype}
push_all_the_way_left (stack : List (avl_t (key_t, data_t)),
p : avl_t (key_t, data_t)) :
List0 (avl_t (key_t, data_t)) =
let
prval _ = lemma_list_param stack
in
case+ p of
| NIL => stack
| CONS (_, _, _, left, _) =>
push_all_the_way_left (p :: stack, left)
end
fun {key_t : t@ype} {data_t : t@ype}
update_generator_stack (stack : List (avl_t (key_t, data_t)),
right : avl_t (key_t, data_t)) :
List0 (avl_t (key_t, data_t)) =
let
prval _ = lemma_list_param stack
in
if avl_t_is_empty right then
stack
else
push_all_the_way_left<key_t><data_t> (stack, right)
end
fn {key_t : t@ype} {data_t : t@ype}
avl_t_make_data_generator {size : int}
(avl : avl_t (key_t, data_t, size)) :
() -<cloref1> Option data_t =
let
typedef avl_t = avl_t (key_t, data_t)
val stack = push_all_the_way_left<key_t><data_t> (LNIL, avl)
val stack_ref = ref stack
(* Cast stack_ref to its (otherwise untyped) pointer, so it can be
enclosed within generate. *)
val p_stack_ref = $UNSAFE.castvwtp0{ptr} stack_ref
fun
generate () :<cloref1> Option data_t =
let
(* Restore the type information for stack_ref. *)
val stack_ref =
$UNSAFE.castvwtp0{ref (List avl_t)} p_stack_ref
var stack : List0 avl_t = !stack_ref
var retval : Option data_t
in
begin
case+ stack of
| LNIL => retval := None ()
| p :: tail =>
let
val- CONS (_, d, _, left, right) = p
in
retval := Some d;
stack :=
update_generator_stack<key_t><data_t> (tail, right)
end
end;
!stack_ref := stack;
retval
end
in
generate
end
(*------------------------------------------------------------------*)
(* Hashmaps implemented with AVL trees and association lists. *)
(* The interface - - - - - - - - - - - - - - - - - - - - - - - - - *)
typedef hashmap_t (key_t : t@ype+,
data_t : t@ype+) =
avl_t (uint64, List1 @(key_t, data_t))
(* For simplicity, let us support only 64-bit hashes. *)
extern fun {key_t : t@ype} (* Implement a hash function with this. *)
hashmap_t$hashfunc : key_t -<> uint64
extern fun {key_t : t@ype} (* Implement key equality with this. *)
hashmap_t$key_eq : (key_t, key_t) -<> bool
extern fun
hashmap_t_nil :
{key_t : t@ype} {data_t : t@ype}
() -<> hashmap_t (key_t, data_t)
extern fun {key_t : t@ype}
{data_t : t@ype}
hashmap_t_set (map : hashmap_t (key_t, data_t),
key : key_t,
data : data_t) :<>
hashmap_t (key_t, data_t)
extern fun {key_t : t@ype}
{data_t : t@ype}
hashmap_t_get (map : hashmap_t (key_t, data_t),
key : key_t) :<>
Option data_t
(*
Notes:
* Generators for hashmap_t produce their output in unspecified
order.
* Generators for keys and data values can be made by analogy to
the following generator for pairs, or can be written in terms
of the generator for pairs. (The former approach seems better;
it might copy less data.)
*)
extern fun {key_t : t@ype}
{data_t : t@ype}
hashmap_t_make_pairs_generator (map : hashmap_t (key_t, data_t)) :
() -<cloref1> Option @(key_t, data_t)
(* The implementation - - - - - - - - - - - - - - - - - - - - - - - *)
implement
avl_t$compare<uint64> (u, v) =
if u < v then
~1
else if v < u then
1
else
0
implement
hashmap_t_nil () =
avl_t_nil ()
fun {key_t : t@ype}
{data_t : t@ype}
remove_association {n : nat} .<n>.
(lst : list (@(key_t, data_t), n),
key : key_t) :<>
List0 @(key_t, data_t) =
(* This implementation uses linear stack space, and so presumes the
list is not extremely long. It preserves the order of the list,
although doing so is not necessary for persistence. (You might
wish to think about that, taking into account that the
order of traversal through a hashmap usually is considered
"unspecified".) *)
case+ lst of
| list_nil () => lst
| list_cons (head, tail) =>
if hashmap_t$key_eq<key_t> (key, head.0) then
tail (* Assume there is only one match. *)
else
list_cons (head, remove_association (tail, key))
fun {key_t : t@ype}
{data_t : t@ype}
find_association {n : nat} .<n>.
(lst : list (@(key_t, data_t), n),
key : key_t) :<>
List0 @(key_t, data_t) =
(* This implementation is tail recursive. It will not build up the
stack. *)
case+ lst of
| list_nil () => lst
| list_cons (head, tail) =>
if hashmap_t$key_eq<key_t> (key, head.0) then
lst
else
find_association (tail, key)
implement {key_t} {data_t}
hashmap_t_set (map, key, data) =
let
typedef lst_t = List1 @(key_t, data_t) (* Association list. *)
val hash = hashmap_t$hashfunc<key_t> key
val lst_opt = avl_t_search_opt<uint64><lst_t> (map, hash)
val lst =
begin
case+ lst_opt of
| Some lst =>
(* There is already an association list for this hash value.
Remove any association already in it. *)
remove_association<key_t><data_t> (lst, key)
| None () =>
(* Start a new association list. *)
list_nil ()
end : List0 @(key_t, data_t)
val lst = list_cons (@(key, data), lst)
in
avl_t_insert<uint64><lst_t> (map, hash, lst)
end
implement {key_t} {data_t}
hashmap_t_get (map, key) =
let
typedef lst_t = List1 @(key_t, data_t) (* Association list. *)
val hash = hashmap_t$hashfunc<key_t> key
val lst_opt = avl_t_search_opt<uint64><lst_t> (map, hash)
in
case+ lst_opt of
| None () => None{data_t} ()
| Some lst =>
begin
case+ find_association<key_t><data_t> (lst, key) of
| list_nil () => None{data_t} ()
| list_cons (@(_, data), _) => Some{data_t} data
end
end
implement {key_t} {data_t}
hashmap_t_make_pairs_generator (map) =
let
typedef pair_t = @(key_t, data_t)
typedef lst_t = List1 pair_t
typedef lst_t_0 = List0 pair_t
val avl_gen = avl_t_make_data_generator<uint64><lst_t> (map)
val current_alist_ref : ref lst_t_0 = ref (list_nil ())
val current_alist_ptr =
$UNSAFE.castvwtp0{ptr} current_alist_ref
in
lam () =>
let
val current_alist_ref =
$UNSAFE.castvwtp0{ref lst_t_0} current_alist_ptr
in
case+ !current_alist_ref of
| list_nil () =>
begin
case+ avl_gen () of
| None () => None ()
| Some lst =>
begin
case+ lst of
| list_cons (head, tail) =>
begin
!current_alist_ref := tail;
Some head
end
end
end
| list_cons (head, tail) =>
begin
!current_alist_ref := tail;
Some head
end
end
end
(*------------------------------------------------------------------*)
implement
hashmap_t$hashfunc<string> (s) =
string_hash s
implement
hashmap_t$key_eq<string> (s, t) =
s = t
typedef s2i_hashmap_t = hashmap_t (string, int)
fn
s2i_hashmap_t_set (map : s2i_hashmap_t,
key : string,
data : int) :<> s2i_hashmap_t =
hashmap_t_set<string><int> (map, key, data)
fn
s2i_hashmap_t_set_ref (map : &s2i_hashmap_t >> _,
key : string,
data : int) :<!wrt> void =
(* Update a reference to a persistent hashmap. *)
map := s2i_hashmap_t_set (map, key, data)
fn
s2i_hashmap_t_get (map : s2i_hashmap_t,
key : string) :<> Option int =
hashmap_t_get<string><int> (map, key)
extern fun {} (* {} = a template without template parameters *)
s2i_hashmap_t_get_dflt$dflt :<> () -> int
fn {} (* {} = a template without template parameters *)
s2i_hashmap_t_get_dflt (map : s2i_hashmap_t,
key : string) : int =
case+ s2i_hashmap_t_get (map, key) of
| Some x => x
| None () => s2i_hashmap_t_get_dflt$dflt<> ()
overload [] with s2i_hashmap_t_set_ref
overload [] with s2i_hashmap_t_get_dflt
implement
main0 () =
let
implement s2i_hashmap_t_get_dflt$dflt<> () = 0
var map = hashmap_t_nil ()
var gen : () -<cloref1> @(string, int)
var pair : Option @(string, int)
in
map["one"] := 1;
map["two"] := 2;
map["three"] := 3;
println! ("map[\"one\"] = ", map["one"]);
println! ("map[\"two\"] = ", map["two"]);
println! ("map[\"three\"] = ", map["three"]);
println! ("map[\"four\"] = ", map["four"]);
gen := hashmap_t_make_pairs_generator<string><int> map;
for (pair := gen (); option_is_some pair; pair := gen ())
println! (pair)
end
(*------------------------------------------------------------------*)

View file

@ -0,0 +1,16 @@
BEGIN {
a["red"] = 0xff0000
a["green"] = 0x00ff00
a["blue"] = 0x0000ff
for (i in a) {
printf "%8s %06x\n", i, a[i]
}
# deleting a key/value
delete a["red"]
for (i in a) {
print i
}
# check if a key exists
print ( "red" in a ) # print 0
print ( "blue" in a ) # print 1
}

View file

@ -0,0 +1,9 @@
var map:Object = {key1: "value1", key2: "value2"};
trace(map['key1']); // outputs "value1"
// Dot notation can also be used
trace(map.key2); // outputs "value2"
// More keys and values can then be added
map['key3'] = "value3";
trace(map['key3']); // outputs "value3"

View file

@ -0,0 +1,33 @@
with Ada.Containers.Ordered_Maps;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO;
procedure Associative_Array is
-- Instantiate the generic package Ada.Containers.Ordered_Maps
package Associative_Int is new Ada.Containers.Ordered_Maps(Unbounded_String, Integer);
use Associative_Int;
Color_Map : Map;
Color_Cursor : Cursor;
Success : Boolean;
Value : Integer;
begin
-- Add values to the ordered map
Color_Map.Insert(To_Unbounded_String("Red"), 10, Color_Cursor, Success);
Color_Map.Insert(To_Unbounded_String("Blue"), 20, Color_Cursor, Success);
Color_Map.Insert(To_Unbounded_String("Yellow"), 5, Color_Cursor, Success);
-- retrieve values from the ordered map and print the value and key
-- to the screen
Value := Color_Map.Element(To_Unbounded_String("Red"));
Ada.Text_Io.Put_Line("Red:" & Integer'Image(Value));
Value := Color_Map.Element(To_Unbounded_String("Blue"));
Ada.Text_IO.Put_Line("Blue:" & Integer'Image(Value));
Value := Color_Map.Element(To_Unbounded_String("Yellow"));
Ada.Text_IO.Put_Line("Yellow:" & Integer'Image(Value));
end Associative_Array;

View file

@ -0,0 +1,17 @@
var names = {} // empty map
names["foo"] = "bar"
names[3] = 4
// initialized map
var names2 = {"foo": bar, 3:4}
// lookup map
var name = names["foo"]
if (typeof(name) == "none") {
println ("not found")
} else {
println (name)
}
// remove from map
delete names["foo"]

View file

@ -0,0 +1 @@
record r;

View file

@ -0,0 +1,3 @@
r_put(r, "A", 33); # an integer value
r_put(r, "C", 2.5); # a real value
r_put(r, "B", "associative"); # a string value

View file

@ -0,0 +1,9 @@
// Cannot / Do not need to instantiate the algorithm implementation (e.g, HashMap).
Map<String, String> strMap = new Map<String, String>();
strMap.put('a', 'aval');
strMap.put('b', 'bval');
System.assert( strMap.containsKey('a') );
System.assertEquals( 'bval', strMap.get('b') );
// String keys are case-sensitive
System.assert( !strMap.containsKey('A') );

View file

@ -0,0 +1,7 @@
Map<String, String> strMap = new Map<String, String>{
'a' => 'aval',
'b' => 'bval'
};
System.assert( strMap.containsKey('a') );
System.assertEquals( 'bval', strMap.get('b') );

View file

@ -0,0 +1,8 @@
; create a dictionary
d: #[
name: "john"
surname: "doe"
age: 34
]
print d

View file

@ -0,0 +1,3 @@
associative_array := {key1: "value 1", "Key with spaces and non-alphanumeric characters !*+": 23}
MsgBox % associative_array.key1
. "`n" associative_array["Key with spaces and non-alphanumeric characters !*+"]

View file

@ -0,0 +1,6 @@
arrayX1 = first
arrayX2 = second
arrayX3 = foo
arrayX4 = bar
Loop, 4
Msgbox % arrayX%A_Index%

View file

@ -0,0 +1,127 @@
; Associative arrays in AutoIt.
; All the required functions are below the examples.
; Initialize an error handler to deal with any COM errors..
global $oMyError = ObjEvent("AutoIt.Error", "AAError")
; first example, simple.
global $simple
; Initialize your array ...
AAInit($simple)
AAAdd($simple, "Appple", "fruit")
AAAdd($simple, "Dog", "animal")
AAAdd($simple, "Silicon", "tetravalent metalloid semiconductor")
ConsoleWrite("It is well-known that Silicon is a " & AAGetItem($simple, "Silicon") & "." & @CRLF)
ConsoleWrite(@CRLF)
; A more interesting example..
$ini_path = "AA_Test.ini"
; Put this prefs section in your ini file..
; [test]
; foo=foo value
; foo2=foo2 value
; bar=bar value
; bar2=bar2 value
global $associative_array
AAInit($associative_array)
; We are going to convert this 2D array into a cute associative array where we
; can access the values by simply using their respective key names..
$test_array = IniReadSection($ini_path, "test")
for $z = 1 to 2 ; do it twice, to show that the items are *really* there!
for $i = 1 to $test_array[0][0]
$key_name = $test_array[$i][0]
ConsoleWrite("Adding '" & $key_name & "'.." & @CRLF)
; key already exists in "$associative_array", use the pre-determined value..
if AAExists($associative_array, $key_name) then
$this_value = AAGetItem($associative_array, $key_name)
ConsoleWrite("key_name ALREADY EXISTS! : =>" & $key_name & "<=" & @CRLF)
else
$this_value = $test_array[$i][1]
; store left=right value pair in AA
if $this_value then
AAAdd($associative_array, $key_name, $this_value)
endif
endif
next
next
ConsoleWrite(@CRLF & "Array Count: =>" & AACount($associative_array) & "<=" & @CRLF)
AAList($associative_array)
ConsoleWrite(@CRLF & "Removing 'foo'..")
AARemove($associative_array, "foo")
ConsoleWrite(@CRLF & "Array Count: =>" & AACount($associative_array) & "<=" & @CRLF)
AAList($associative_array)
AAWipe($associative_array)
; end
func AAInit(ByRef $dict_obj)
$dict_obj = ObjCreate("Scripting.Dictionary")
endfunc
; Adds a key and item pair to a Dictionary object..
func AAAdd(ByRef $dict_obj, $key, $val)
$dict_obj.Add($key, $val)
If @error Then return SetError(1, 1, -1)
endfunc
; Removes a key and item pair from a Dictionary object..
func AARemove(ByRef $dict_obj, $key)
$dict_obj.Remove($key)
If @error Then return SetError(1, 1, -1)
endfunc
; Returns true if a specified key exists in the associative array, false if not..
func AAExists(ByRef $dict_obj, $key)
return $dict_obj.Exists($key)
endfunc
; Returns a value for a specified key name in the associative array..
func AAGetItem(ByRef $dict_obj, $key)
return $dict_obj.Item($key)
endfunc
; Returns the total number of keys in the array..
func AACount(ByRef $dict_obj)
return $dict_obj.Count
endfunc
; List all the "Key" > "Item" pairs in the array..
func AAList(ByRef $dict_obj)
ConsoleWrite("AAList: =>" & @CRLF)
local $k = $dict_obj.Keys ; Get the keys
; local $a = $dict_obj.Items ; Get the items (for reference)
for $i = 0 to AACount($dict_obj) -1 ; Iterate the array
ConsoleWrite($k[$i] & " ==> " & AAGetItem($dict_obj, $k[$i]) & @CRLF)
next
endfunc
; Wipe the array, obviously.
func AAWipe(ByRef $dict_obj)
$dict_obj.RemoveAll()
endfunc
; Oh oh!
func AAError()
Local $err = $oMyError.number
If $err = 0 Then $err = -1
SetError($err) ; to check for after this function returns
endfunc
;; End AA Functions.

View file

@ -0,0 +1,106 @@
global values$, keys$
dim values$[1]
dim keys$[1]
call updateKey("a","apple")
call updateKey("b","banana")
call updateKey("c","cucumber")
gosub show
print "I like to eat a " + getValue$("c") + " on my salad."
call deleteKey("b")
call updateKey("c","carrot")
call updateKey("e","endive")
gosub show
end
show:
for t = 0 to countKeys()-1
print getKeyByIndex$(t) + " " + getValueByIndex$(t)
next t
print
return
subroutine updateKey(key$, value$)
# update or add an item
i=findKey(key$)
if i=-1 then
i = freeKey()
keys$[i] = key$
end if
values$[i] = value$
end subroutine
subroutine deleteKey(key$)
# delete by clearing the key
i=findKey(key$)
if i<>-1 then
keys$[i] = ""
end if
end subroutine
function freeKey()
# find index of a free element in the array
for n = 0 to keys$[?]-1
if keys$[n]="" then return n
next n
redim keys$[n+1]
redim values$[n+1]
return n
end function
function findKey(key$)
# return index or -1 if not found
for n = 0 to keys$[?]-1
if key$=keys$[n] then return n
next n
return -1
end function
function getValue$(key$)
# return a value by the key or "" if not existing
i=findKey(key$)
if i=-1 then
return ""
end if
return values$[i]
end function
function countKeys()
# return number of items
# remember to skip the empty keys (deleted ones)
k = 0
for n = 0 to keys$[?] -1
if keys$[n]<>"" then k++
next n
return k
end function
function getValueByIndex$(i)
# get a value by the index
# remember to skip the empty keys (deleted ones)
k = 0
for n = 0 to keys$[?] -1
if keys$[n]<>"" then
if k=i then return values$[k]
k++
endif
next n
return ""
end function
function getKeyByIndex$(i)
# get a key by the index
# remember to skip the empty keys (deleted ones)
k = 0
for n = 0 to keys$[?] -1
if keys$[n]<>"" then
if k=i then return keys$[k]
k++
endif
next n
return ""
end function

View file

@ -0,0 +1,21 @@
REM Store some values with their keys:
PROCputdict(mydict$, "FF0000", "red")
PROCputdict(mydict$, "00FF00", "green")
PROCputdict(mydict$, "0000FF", "blue")
REM Retrieve some values using their keys:
PRINT FNgetdict(mydict$, "green")
PRINT FNgetdict(mydict$, "red")
END
DEF PROCputdict(RETURN dict$, value$, key$)
IF dict$ = "" dict$ = CHR$(0)
dict$ += key$ + CHR$(1) + value$ + CHR$(0)
ENDPROC
DEF FNgetdict(dict$, key$)
LOCAL I%, J%
I% = INSTR(dict$, CHR$(0) + key$ + CHR$(1))
IF I% = 0 THEN = "" ELSE I% += LEN(key$) + 2
J% = INSTR(dict$, CHR$(0), I%)
= MID$(dict$, I%, J% - I%)

View file

@ -0,0 +1,6 @@
DECLARE associative ASSOC STRING
associative("abc") = "first three"
associative("xyz") = "last three"
PRINT associative("xyz")

View file

@ -0,0 +1,3 @@
(("foo" 13)
("bar" 42)
("baz" 77)) ls2map !

View file

@ -0,0 +1,24 @@
::assocarrays.cmd
@echo off
setlocal ENABLEDELAYEDEXPANSION
set array.dog=1
set array.cat=2
set array.wolf=3
set array.cow=4
for %%i in (dog cat wolf cow) do call :showit array.%%i !array.%%i!
set c=-27
call :mkarray sicko flu 5 measles 6 mumps 7 bromodrosis 8
for %%i in (flu measles mumps bromodrosis) do call :showit "sicko^&%%i" !sicko^&%%i!
endlocal
goto :eof
:mkarray
set %1^&%2=%3
shift /2
shift /2
if "%2" neq "" goto :mkarray
goto :eof
:showit
echo %1 = %2
goto :eof

View file

@ -0,0 +1,10 @@
new$hash:?myhash
& (myhash..insert)$(title."Some title")
& (myhash..insert)$(formula.a+b+x^7)
& (myhash..insert)$(fruit.apples oranges kiwis)
& (myhash..insert)$(meat.)
& (myhash..insert)$(fruit.melons bananas)
& out$(myhash..find)$fruit
& (myhash..remove)$formula
& (myhash..insert)$(formula.x^2+y^2)
& out$(myhash..find)$formula;

View file

@ -0,0 +1,8 @@
h = [:] #Empty hash
h[:a] = 1 #Assign value
h[:b] = [1 2 3] #Assign another value
h2 = [a: 1, b: [1 2 3], 10 : "ten"] #Initialized hash
h2[:b][2] #Returns 3

View file

@ -0,0 +1 @@
#include <map>

View file

@ -0,0 +1,26 @@
#include <map>
#include <iostreams>
int main()
{
// Create the map.
std::map<int, double> exampleMap;
// Choose our key
int myKey = 7;
// Choose our value
double myValue = 3.14;
// Assign a value to the map with the specified key.
exampleMap[myKey] = myValue;
// Retrieve the value
double myRetrievedValue = exampleMap[myKey];
// Display our retrieved value.
std::cout << myRetrievedValue << std::endl;
// main() must return 0 on success.
return 0;
}

View file

@ -0,0 +1 @@
std::map<A, B> exampleMap

View file

@ -0,0 +1 @@
std::map<int, double> exampleMap

View file

@ -0,0 +1 @@
exampleMap[7] = 3.14

View file

@ -0,0 +1,3 @@
int myKey = 7;
double myValue = 3.14;
exampleMap[myKey] = myValue;

View file

@ -0,0 +1 @@
exampleMap.insert(std::pair<int, double>(7,3.14));

View file

@ -0,0 +1 @@
exampleMap.insert(std::make_pair(7,3.14));

View file

@ -0,0 +1 @@
myValue = exampleMap[myKey]

View file

@ -0,0 +1,7 @@
double myValue = 0.0;
std::map<int, double>::iterator myIterator = exampleMap.find(myKey);
if(exampleMap.end() != myIterator)
{
// Return the value for that key.
myValue = myIterator->second;
}

View file

@ -0,0 +1,2 @@
System.Collections.HashTable map = new System.Collections.HashTable();
map["key1"] = "foo";

View file

@ -0,0 +1,2 @@
Dictionary<string, string> map = new Dictionary<string,string>();
map[ "key1" ] = "foo";

View file

@ -0,0 +1 @@
var map = new Dictionary<string, string> {{"key1", "foo"}};

View file

@ -0,0 +1,36 @@
import ceylon.collection {
ArrayList,
HashMap,
naturalOrderTreeMap
}
shared void run() {
// the easiest way is to use the map function to create
// an immutable map
value myMap = map {
"foo" -> 5,
"bar" -> 10,
"baz" -> 15,
"foo" -> 6 // by default the first "foo" will remain
};
// or you can use the HashMap constructor to create
// a mutable one
value myOtherMap = HashMap {
"foo"->"bar"
};
myOtherMap.put("baz", "baxx");
// there's also a sorted red/black tree map
value myTreeMap = naturalOrderTreeMap {
1 -> "won",
2 -> "too",
4 -> "fore"
};
for(num->homophone in myTreeMap) {
print("``num`` is ``homophone``");
}
}

View file

@ -0,0 +1,29 @@
// arr is an array of string to int. any type can be used in both places.
var keys: domain(string);
var arr: [keys] int;
// keys can be added to a domain using +, new values will be initialized to the default value (0 for int)
keys += "foo";
keys += "bar";
keys += "baz";
// array access via [] or ()
arr["foo"] = 1;
arr["bar"] = 4;
arr("baz") = 6;
// write auto-formats domains and arrays
writeln("Keys: ", keys);
writeln("Values: ", arr);
// keys can be deleted using -
keys -= "bar";
writeln("Keys: ", keys);
writeln("Values: ", arr);
// chapel also supports array literals
var arr2 = [ "John" => 3, "Pete" => 14 ];
writeln("arr2 keys: ", arr2.domain);
writeln("arr2 values: ", arr2);

View file

@ -0,0 +1,3 @@
{:key "value"
:key2 "value2"
:key3 "value3"}

View file

@ -0,0 +1,4 @@
<cfset myHash = structNew()>
<cfset myHash.key1 = "foo">
<cfset myHash["key2"] = "bar">
<cfset myHash.put("key3","java-style")>

View file

@ -0,0 +1,13 @@
;; default :test is #'eql, which is suitable for numbers only,
;; or for implementation identity for other types!
;; Use #'equalp if you want case-insensitive keying on strings.
(setf my-hash (make-hash-table :test #'equal))
(setf (gethash "H2O" my-hash) "Water")
(setf (gethash "HCl" my-hash) "Hydrochloric Acid")
(setf (gethash "CO" my-hash) "Carbon Monoxide")
;; That was actually a hash table, an associative array or
;; alist is written like this:
(defparameter *legs* '((cow . 4) (flamingo . 2) (centipede . 100)))
;; you can use assoc to do lookups and cons new elements onto it to make it longer.

View file

@ -0,0 +1,67 @@
DEFINITION Collections;
IMPORT Boxes;
CONST
notFound = -1;
TYPE
Hash = POINTER TO RECORD
cap-, size-: INTEGER;
(h: Hash) ContainsKey (k: Boxes.Object): BOOLEAN, NEW;
(h: Hash) Get (k: Boxes.Object): Boxes.Object, NEW;
(h: Hash) IsEmpty (): BOOLEAN, NEW;
(h: Hash) Put (k, v: Boxes.Object): Boxes.Object, NEW;
(h: Hash) Remove (k: Boxes.Object): Boxes.Object, NEW;
(h: Hash) Reset, NEW
END;
HashMap = POINTER TO RECORD
cap-, size-: INTEGER;
(hm: HashMap) ContainsKey (k: Boxes.Object): BOOLEAN, NEW;
(hm: HashMap) ContainsValue (v: Boxes.Object): BOOLEAN, NEW;
(hm: HashMap) Get (k: Boxes.Object): Boxes.Object, NEW;
(hm: HashMap) IsEmpty (): BOOLEAN, NEW;
(hm: HashMap) Keys (): POINTER TO ARRAY OF Boxes.Object, NEW;
(hm: HashMap) Put (k, v: Boxes.Object): Boxes.Object, NEW;
(hm: HashMap) Remove (k: Boxes.Object): Boxes.Object, NEW;
(hm: HashMap) Reset, NEW;
(hm: HashMap) Values (): POINTER TO ARRAY OF Boxes.Object, NEW
END;
LinkedList = POINTER TO RECORD
first-, last-: Node;
size-: INTEGER;
(ll: LinkedList) Add (item: Boxes.Object), NEW;
(ll: LinkedList) Append (item: Boxes.Object), NEW;
(ll: LinkedList) AsString (): POINTER TO ARRAY OF CHAR, NEW;
(ll: LinkedList) Contains (item: Boxes.Object): BOOLEAN, NEW;
(ll: LinkedList) Get (at: INTEGER): Boxes.Object, NEW;
(ll: LinkedList) IndexOf (item: Boxes.Object): INTEGER, NEW;
(ll: LinkedList) Insert (at: INTEGER; item: Boxes.Object), NEW;
(ll: LinkedList) IsEmpty (): BOOLEAN, NEW;
(ll: LinkedList) Remove (item: Boxes.Object), NEW;
(ll: LinkedList) RemoveAt (at: INTEGER), NEW;
(ll: LinkedList) Reset, NEW;
(ll: LinkedList) Set (at: INTEGER; item: Boxes.Object), NEW
END;
Vector = POINTER TO RECORD
size-, cap-: LONGINT;
(v: Vector) Add (item: Boxes.Object), NEW;
(v: Vector) AddAt (item: Boxes.Object; i: INTEGER), NEW;
(v: Vector) Contains (o: Boxes.Object): BOOLEAN, NEW;
(v: Vector) Get (i: LONGINT): Boxes.Object, NEW;
(v: Vector) IndexOf (o: Boxes.Object): LONGINT, NEW;
(v: Vector) Remove (o: Boxes.Object), NEW;
(v: Vector) RemoveIndex (i: LONGINT): Boxes.Object, NEW;
(v: Vector) Set (i: LONGINT; o: Boxes.Object): Boxes.Object, NEW;
(v: Vector) Trim, NEW
END;
PROCEDURE NewHash (cap: INTEGER): Hash;
PROCEDURE NewHashMap (cap: INTEGER): HashMap;
PROCEDURE NewLinkedList (): LinkedList;
PROCEDURE NewVector (cap: INTEGER): Vector;
END Collections.

View file

@ -0,0 +1,22 @@
MODULE BbtAssociativeArrays;
IMPORT StdLog, Collections, Boxes;
PROCEDURE Do*;
VAR
hm : Collections.HashMap;
o : Boxes.Object;
keys, values: POINTER TO ARRAY OF Boxes.Object;
i: INTEGER;
BEGIN
hm := Collections.NewHashMap(1009);
o := hm.Put(Boxes.NewString("first"),Boxes.NewInteger(1));
o := hm.Put(Boxes.NewString("second"),Boxes.NewInteger(2));
o := hm.Put(Boxes.NewString("third"),Boxes.NewInteger(3));
o := hm.Put(Boxes.NewString("one"),Boxes.NewInteger(1));
StdLog.String("size: ");StdLog.Int(hm.size);StdLog.Ln;
END Do;
END BbtAssociativeArrays.

View file

@ -0,0 +1,5 @@
hash1 = {"foo" => "bar"}
# hash literals that don't perfectly match the intended hash type must be given an explicit type specification
# the following would fail without `of String => String|Int32`
hash2 : Hash(String, String|Int32) = {"foo" => "bar"} of String => String|Int32

View file

@ -0,0 +1,4 @@
void main() {
auto hash = ["foo":42, "bar":100];
assert("foo" in hash);
}

View file

@ -0,0 +1,5 @@
m = { => } # empty ordered map, future inserted keys will be ordered
h = { -> } # empty hash map, future inserted keys will not be ordered
m = { 'foo' => 42, 'bar' => 100 } # with ordered keys
h = { 'foo' -> 42, 'bar' -> 100 } # with unordered keys

View file

@ -0,0 +1,34 @@
main() {
var rosettaCode = { // Type is inferred to be Map<String, String>
'task': 'Associative Array Creation'
};
rosettaCode['language'] = 'Dart';
// The update function can be used to update a key using a callback
rosettaCode.update( 'is fun', // Key to update
(value) => "i don't know", // New value to use if key is present
ifAbsent: () => 'yes!' // Value to use if key is absent
);
assert( rosettaCode.toString() == '{task: Associative Array Creation, language: Dart, is fun: yes!}');
// If we type the Map with dynamic keys and values, it is like a JavaScript object
Map<dynamic, dynamic> jsObject = {
'key': 'value',
1: 2,
1.5: [ 'more', 'stuff' ],
#doStuff: () => print('doing stuff!') // #doStuff is a symbol, only one instance of this exists in the program. Would be :doStuff in Ruby
};
print( jsObject['key'] );
print( jsObject[1] );
for ( var value in jsObject[1.5] )
print('item: $value');
jsObject[ #doStuff ](); // Calling the function
print('\nKey types:');
jsObject.keys.forEach( (key) => print( key.runtimeType ) );
}

View file

@ -0,0 +1,19 @@
program AssociativeArrayCreation;
{$APPTYPE CONSOLE}
uses Generics.Collections;
var
lDictionary: TDictionary<string, Integer>;
begin
lDictionary := TDictionary<string, Integer>.Create;
try
lDictionary.Add('foo', 5);
lDictionary.Add('bar', 10);
lDictionary.Add('baz', 15);
lDictionary.AddOrSetValue('foo', 6); // replaces value if it exists
finally
lDictionary.Free;
end;
end.

View file

@ -0,0 +1,5 @@
use_namespace(rosettacode)_me();
add_dict(tanzanianBanknoteObverseDipiction)_keys(500,1000,2000,5000,10000)_values(Karume,Nyerere,lion,black rhinoceros,elephant);
reset_ns[];

View file

@ -0,0 +1,11 @@
use_namespace(rosettacode)_me();
add_hash(tanzanianBanknoteReverseDipiction)_values(
University of Dar es Salaam\, Central Hall Building,
Ikulu\, Dar es Salaam,
Ngome Kongwe\, Zanzibar,
Geita Cyanid Leaching Plant,
Bank of Tanzania Headquarters\, Dar es Salaam
);
reset_ns[];

View file

@ -0,0 +1,2 @@
var t = (x: 1, y: 2, z: 3)
print(t.Keys().ToArray())

View file

@ -0,0 +1,5 @@
[].asMap() # immutable, empty
["one" => 1, "two" => 2] # immutable, 2 mappings
[].asMap().diverge() # mutable, empty
["one" => 2].diverge(String, float64) # mutable, initial contents,
# typed (coerces to float)

View file

@ -0,0 +1,11 @@
Map empty = Map(int, text) # creates an empty map
writeLine(empty)
var longFruit = Map(int, text).of(1, "banana") # creates a map with the pair 1 => "banana"
longFruit[2] = "melon" # associates a key of 2 with "melon"
longFruit.insert(3, "avocado")
writeLine(longFruit) # prints the map
var shortFruit = int%text[4 => "kiwi", 5 => "apple"] # map creation using arrow notation
writeLine(shortFruit[5]) # retrieves the value with a key of 5 and prints it out
writeLine(shortFruit.length) # prints the number of entries
writeLine(shortFruit) # prints the map
writeLine(text%text["Italy" => "Rome", "France" => "Paris", "Germany" => "Berlin", "Spain" => "Madrid"])

View file

@ -0,0 +1 @@
associative$[][] = [ [ 1 "associative" ] [ 2 "arrays" ] ]

View file

@ -0,0 +1,18 @@
proc indexAssoc index . array[][] item .
for i = 1 to len array[][]
if array[i][1] = index
item = array[i][2]
break 2
.
.
item = number "nan"
.
proc indexStrAssoc index$ . array$[][] item$ .
for i = 1 to len array$[][]
if array$[i][1] = index$
item$ = array$[i][2]
break 2
.
.
item$ = ""
.

View file

@ -0,0 +1,18 @@
(lib 'hash) ;; needs hash.lib
(define H (make-hash)) ;; new hash table
;; keys may be symbols, numbers, strings ..
;; values may be any lisp object
(hash-set H 'simon 'antoniette)
→ antoniette
(hash-set H 'antoinette 'albert)
→ albert
(hash-set H "Elvis" 42)
→ 42
(hash-ref H 'Elvis)
→ #f ;; not found. Elvis is not "Elvis"
(hash-ref H "Elvis")
→ 42
(hash-ref H 'simon)
→ antoniette
(hash-count H)
→ 3

View file

@ -0,0 +1,5 @@
Map<String, Int> map = new HashMap();
map["foo"] = 5; // or: map.put("foo", 5)
map["bar"] = 10;
map["baz"] = 15;
map["foo"] = 6; // replaces previous value of 5

View file

@ -0,0 +1 @@
Map<String, Int> map = ["foo"=6, "bar"=10, "baz"=15];

View file

@ -0,0 +1,7 @@
Int? mightBeNull = map["foo"];
Int neverNull = map.getOrDefault("foo", 0);
if (Int n := map.get("foo")) {
// if "foo" is in the map, then the variable "n" is set to its value
} else {
// if "foo" is not in the map, then the variable "n" is not defined
}

View file

@ -0,0 +1,3 @@
for (String key : map) {
// the variable "key" is defined here
}

View file

@ -0,0 +1,3 @@
for (Int value : map.values) {
// the variable "value" is defined here
}

View file

@ -0,0 +1,3 @@
for ((String key, Int value) : map) {
// the variables "key" and "value" are defined here
}

View file

@ -0,0 +1,12 @@
import system'collections;
public program()
{
// 1. Create
var map := Dictionary.new();
map["key"] := "foox";
map["key"] := "foo";
map["key2"]:= "foo2";
map["key3"]:= "foo3";
map["key4"]:= "foo4";
}

View file

@ -0,0 +1,12 @@
import system'collections;
public program()
{
// 1. Create
auto map := new Map<string,string>();
map["key"] := "foox";
map["key"] := "foo";
map["key2"]:= "foo2";
map["key3"]:= "foo3";
map["key4"]:= "foo4";
}

View file

@ -0,0 +1 @@
%{"one" => :two, 3 => "four"}

View file

@ -0,0 +1,3 @@
%{a: 1, b: 2}
# equivalent to
%{:a => 1, :b => 2}

View file

@ -0,0 +1,17 @@
defmodule RC do
def test_create do
IO.puts "< create Map.new >"
m = Map.new #=> creates an empty Map
m1 = Map.put(m,:foo,1)
m2 = Map.put(m1,:bar,2)
print_vals(m2)
print_vals(%{m2 | foo: 3})
end
defp print_vals(m) do
IO.inspect m
Enum.each(m, fn {k,v} -> IO.puts "#{inspect k} => #{v}" end)
end
end
RC.test_create

View file

@ -0,0 +1,2 @@
(setq my-table (make-hash-table))
(puthash 'key 'value my-table)

View file

@ -0,0 +1,2 @@
(setq my-table (make-hash-table :test 'equal))
(puthash "key" 123 my-table)

View file

@ -0,0 +1,14 @@
-module(assoc).
-compile([export_all]).
test_create() ->
D = dict:new(),
D1 = dict:store(foo,1,D),
D2 = dict:store(bar,2,D1),
print_vals(D2),
print_vals(dict:store(foo,3,D2)).
print_vals(D) ->
lists:foreach(fun (K) ->
io:format("~p: ~b~n",[K,dict:fetch(K,D)])
end, dict:fetch_keys(D)).

View file

@ -0,0 +1,3 @@
let dic = System.Collections.Generic.Dictionary<string,string>() ;;
dic.Add("key","val") ;
dic.["key"] <- "new val" ;

View file

@ -0,0 +1,7 @@
let d = [("key","val");("other key","other val")] |> Map.ofList
let newd = d.Add("new key","new val")
let takeVal (d:Map<string,string>) =
match d.TryFind("key") with
| Some(v) -> printfn "%s" v
| None -> printfn "not found"

View file

@ -0,0 +1,6 @@
H{ { "one" 1 } { "two" 2 } }
{ [ "one" swap at . ]
[ 2 swap value-at . ]
[ "three" swap at . ]
[ [ 3 "three" ] dip set-at ]
[ "three" swap at . ] } cleave

View file

@ -0,0 +1,17 @@
class Main
{
public static Void main ()
{
// create a map which maps Ints to Strs, with given key-value pairs
Int:Str map := [1:"alpha", 2:"beta", 3:"gamma"]
// create an empty map
Map map2 := [:]
// now add some numbers mapped to their doubles
10.times |Int i|
{
map2[i] = 2*i
}
}
}

View file

@ -0,0 +1,21 @@
: get ( key len table -- data ) \ 0 if not present
search-wordlist if
>body @
else 0 then ;
: put ( data key len table -- )
>r 2dup r@ search-wordlist if
r> drop nip nip
>body !
else
r> get-current >r set-current \ switch definition word lists
nextname create ,
r> set-current
then ;
wordlist constant bar
5 s" alpha" bar put
9 s" beta" bar put
2 s" gamma" bar put
s" alpha" bar get . \ 5
8 s" Alpha" bar put \ Forth dictionaries are normally case-insensitive
s" alpha" bar get . \ 8

View file

@ -0,0 +1,19 @@
include ffl/hct.fs
\ Create a hash table 'table' in the dictionary with a starting size of 10
10 hct-create htable
\ Insert entries
5 s" foo" htable hct-insert
10 s" bar" htable hct-insert
15 s" baz" htable hct-insert
\ Get entry from the table
s" bar" htable hct-get [IF]
.( Value:) . cr
[ELSE]
.( Entry not present.) cr
[THEN]

View file

@ -0,0 +1,23 @@
include lib/hash.4th
include lib/hashkey.4th
\ Create a hash table 'table' with a starting size of 10
['] fnv1a is hash \ set hash method
10 constant /htable \ determine the size
/htable array htable \ allocate the table
latest /htable hashtable \ turn it into a hashtable
\ Insert entries
5 s" foo" htable put
10 s" bar" htable put
15 s" baz" htable put
\ Get entry from the table
s" bar" htable get error? if
.( Entry not present.) cr drop
else
.( Value: ) . cr
then

View file

@ -0,0 +1,17 @@
program AssociativeArrayCreation;
{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
{$IFDEF WINDOWS}{$APPTYPE CONSOLE}{$ENDIF}
uses Generics.Collections;
var
lDictionary: TDictionary<string, Integer>;
begin
lDictionary := TDictionary<string, Integer>.Create;
try
lDictionary.Add('foo', 5);
lDictionary.Add('bar', 10);
lDictionary.Add('baz', 15);
lDictionary.AddOrSetValue('foo', 6); // replaces value if it exists
finally
lDictionary.Free;
end;
end.

View file

@ -0,0 +1,17 @@
program AssociativeArrayCreation;
{$IFDEF WINDOWS}{$APPTYPE CONSOLE}{$ENDIF}
{$MODE DELPHI}
uses fgl;
var
lDictionary: TFPGMap<string, Integer>;
begin
lDictionary := TFPGMap<string, Integer>.Create;
try
lDictionary.Add('foo', 5);
lDictionary.Add('bar', 10);
lDictionary.Add('baz', 15);
finally
lDictionary.Free;
end;
end.

View file

@ -0,0 +1,69 @@
#define max(a, b) Iif(a>b,a,b)
enum datatype
'for this demonstration we'll allow these five data types
BOOL
STRNG
BYYTE
INTEG
FLOAT
end enum
union value
bool as boolean
strng as string*32
byyte as byte
integ as integer
float as double
end union
type dicitem
'one part of the dictionary entry, either the key or the value
datatype as datatype 'need to keep track of what kind of data it is
value as value
end type
type dicentry
'a dic entry has two things, a key and a value
key as dicitem
value as dicitem
end type
sub add_dicentry( Dic() as dicentry, entry as dicentry )
redim preserve Dic(0 to max(ubound(Dic)+1,0))
Dic(ubound(Dic)) = entry
return
end sub
redim as dicentry Dictionary(-1) 'initialise a dictionary with no entries as yet
dim as dicentry thing1, thing2
'generate some test dictionary entries
with thing1
with .key
.datatype = STRNG
.value.strng = "Cat"
end with
with .value
.datatype = STRNG
.value.strng = "Mittens"
end with
end with
with thing2
with .key
.datatype = integ
.value.integ = 32767
end with
with .value
.datatype = float
.value.float = 2.718281828
end with
end with
add_dicentry( Dictionary(), thing1 )
add_dicentry( Dictionary(), thing2 )
print Dictionary(0).value.value.strng
print Dictionary(1).key.value.integ

View file

@ -0,0 +1 @@
let associative_array = {key1=1,key2=2}

View file

@ -0,0 +1,23 @@
void local fn DoIt
CFDictionaryRef dict1 = fn DictionaryWithObjects( @"Alpha", @"A", @"Bravo", @"B", @"Charlie", @"C", @"Delta", @"D", NULL )
CFDictionaryRef dict2 = @{@"A":@"Alpha", @"B":@"Bravo", @"C":@"Charlie", @"D":@"Delta"}
CFMutableDictionaryRef dict3 = fn MutableDictionaryWithCapacity(0)
MutableDictionarySetObjectForKey( dict3, @"Alpha", @"A" )
MutableDictionarySetObjectForKey( dict3, @"Bravo", @"B" )
MutableDictionarySetObjectForKey( dict3, @"Charlie", @"C" )
MutableDictionarySetObjectForKey( dict3, @"Delta", @"D" )
CFMutableDictionaryRef dict4 = fn MutableDictionaryWithDictionary( @{@"A":@"Alpha", @"B":@"Bravo", @"C":@"Charlie", @"D":@"Delta"} )
print fn DictionaryObjectForKey( dict1, @"A" )
print dict1[@"B"]
print dict2[@"C"]
print dict3[@"D"]
print dict4
end fn
fn DoIt
HandleEvents

View file

@ -0,0 +1,23 @@
// declare a nil map variable, for maps from string to int
var x map[string]int
// make an empty map
x = make(map[string]int)
// make an empty map with an initial capacity
x = make(map[string]int, 42)
// set a value
x["foo"] = 3
// getting values
y1 := x["bar"] // zero value returned if no map entry exists for the key
y2, ok := x["bar"] // ok is a boolean, true if key exists in the map
// removing keys
delete(x, "foo")
// make a map with a literal
x = map[string]int{
"foo": 2, "bar": 42, "baz": -1,
}

View file

@ -0,0 +1,35 @@
// empty map
var emptyMap = new HashMap<String, Integer>()
// map initialization
var map = {"Scott"->50, "Carson"->40, "Luca"->30, "Kyle"->38}
// map key/value assignment
map["Scott"] = 51
// get a value
var x = map["Scott"]
// remove an entry
map.remove("Scott")
// loop and maps
for(entry in map.entrySet()) {
print("Key: ${entry.Key}, Value: ${entry.Value}")
}
// functional iteration
map.eachKey(\ k ->print(map[k]))
map.eachValue(\ v ->print(v))
map.eachKeyAndValue(\ k, v -> print("Key: ${v}, Value: ${v}"))
var filtered = map.filterByValues(\ v ->v < 50)
// any object can be treated as an associative array
class Person {
var name: String
var age: int
}
// access properties on Person dynamically via associative array syntax
var scott = new Person()
scott["name"] = "Scott"
scott["age"] = 29

View file

@ -0,0 +1,10 @@
map = [:]
map[7] = 7
map['foo'] = 'foovalue'
map.put('bar', 'barvalue')
map.moo = 'moovalue'
assert 7 == map[7]
assert 'foovalue' == map.foo
assert 'barvalue' == map['bar']
assert 'moovalue' == map.get('moo')

View file

@ -0,0 +1,6 @@
map = [7:7, foo:'foovalue', bar:'barvalue', moo:'moovalue']
assert 7 == map[7]
assert 'foovalue' == map.foo
assert 'barvalue' == map['bar']
assert 'moovalue' == map.get('moo')

View file

@ -0,0 +1,3 @@
arr := { => }
arr[ 10 ] := "Val_10"
arr[ "foo" ] := "foovalue"

View file

@ -0,0 +1,3 @@
arr := hb_Hash( 10, "Val_10", "foo", "foovalue" )
// or
arr := { 10 => "Val_10", "foo" => "foovalue" }

View file

@ -0,0 +1,5 @@
import Data.Map
dict = fromList [("key1","val1"), ("key2","val2")]
ans = Data.Map.lookup "key2" dict -- evaluates to Just "val2"

View file

@ -0,0 +1,3 @@
dict = [("key1","val1"), ("key2","val2")]
ans = lookup "key2" dict -- evaluates to Just "val2"

View file

@ -0,0 +1,6 @@
let d dict 2 # Initial estimated size
let d["test"] "test" # Strings can be used as index
let d[123] 123 # Integers can also be used as index
println d["test"]
println d[123]

Some files were not shown because too many files have changed in this diff Show more