Skip to content

Commit 1aaf2a2

Browse files
committed
Functional records
I added a data type for "records." A record behaves like a function that maps string keys to arbitrary values. It is represented internally as a vector of zero or more items, each item a {key val} pair, sorted by key. The expression (empty) returns the empty record. The expression (set key val obj) sets key to val in record obj, returning a record like obj but with key mapped to val. It modifies obj inline if there are no other references to it; otherwise it returns a modified copy of obj. The expression (record_count obj) returns the number of items in the record. The expression (record_item obj pos) returns the item in record obj at offset pos, starting at zero. These functions can be used to define record_pairs, which returns the lazy list of pairs in a record, allowing iteration (see test/record.fxl). I added a "chain" function, defined by type_chain in basic.c. The expression (chain a b x) returns (a x) if that value is defined, otherwise (b x). This is used to establish default values when a key is not defined in a record or other function. EXAMPLES This constructs a simple record value: ( set "a" 1; set "b" 2; set "c" 3; set "d" 4; set "e" 5; empty ) This overrides some of the earlier specified values: ( set "c" 33; # maps "c" to 33 instead of 3 set "b" 22; # maps "b" to 22 instead of 2 set "a" 1; set "b" 2; set "c" 3; set "d" 4; set "e" 5; empty ) See test/record.fxl for more examples.
1 parent 6f7d148 commit 1aaf2a2

File tree

11 files changed

+703
-1
lines changed

11 files changed

+703
-1
lines changed

src/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
26.30.1
1+
26.31.0

src/basic.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,22 @@ value type_is_good(value f) { return op_predicate(f,is_good); }
189189
value type_is_bool(value f) { return op_predicate(f,is_bool); }
190190
value type_is_list(value f) { return op_predicate(f,is_list); }
191191

192+
/* \chain==(\a\b\x \v=(a x) is_defined v v (b x)) */
193+
value type_chain(value f)
194+
{
195+
if (!f->L || !f->L->L || !f->L->L->L) return 0;
196+
{
197+
value x = arg(f->R);
198+
value v = eval(AV(arg(f->L->L->R),x));
199+
200+
if (v->T != type_void)
201+
return v;
202+
203+
drop(v);
204+
return eval(AV(arg(f->L->R),hold(x)));
205+
}
206+
}
207+
192208
/* Expand the list data f->R inline. */
193209
value expand(value f)
194210
{

src/basic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,5 @@ extern value type_is_void(value f);
3030
extern value type_is_good(value f);
3131
extern value type_is_bool(value f);
3232
extern value type_is_list(value f);
33+
extern value type_chain(value f);
3334
extern value expand(value y);

src/build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ make type_num
5252
make type_output
5353
make type_parse
5454
make type_rand
55+
make type_record
5556
make type_run
5657
make type_signal
5758
make type_standard

src/out/record

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
\out=
2+
~
3+
BEG
4+
= test_1
5+
count 1
6+
a = void
7+
!b = 2
8+
c = void
9+
d = void
10+
e = void
11+
12+
= test_2
13+
count 1
14+
a = void
15+
b = 222
16+
c = void
17+
d = void
18+
e = void
19+
20+
= test_3
21+
count 1
22+
a = void
23+
b = 22
24+
c = void
25+
d = void
26+
e = void
27+
28+
= test_4
29+
count 4
30+
a = 1
31+
b = 2
32+
c = 33
33+
d = 44
34+
e = void
35+
36+
= test_5
37+
count 5
38+
a = 1
39+
b = 2
40+
c = 33
41+
d = 44
42+
e = 5
43+
44+
= test_6
45+
count 5
46+
a = 1
47+
b = 2
48+
c = 33
49+
d = 44
50+
e = 5
51+
52+
= test_7
53+
obj_3043:
54+
count 3
55+
a = void
56+
b = 2
57+
c = 3
58+
d = 44
59+
e = void
60+
61+
obj_8237:
62+
count 2
63+
a = void
64+
b = void
65+
c = void
66+
d = 44
67+
e = 5
68+
69+
obj_7892:
70+
count 5
71+
a = 1
72+
b = 2
73+
c = 33
74+
d = 44
75+
e = 5
76+
77+
= test_8
78+
count void
79+
a = 1
80+
b = 2
81+
c = 3
82+
d = void
83+
e = void
84+
85+
steps 476 bytes 4608
86+
= test_9
87+
0
88+
void
89+
count 4
90+
a = 1
91+
b = void
92+
c = 33
93+
d = 44
94+
e = 5
95+
96+
at "x" = void
97+
at void = void
98+
at -1 = {"a" 1}
99+
at 2.6 = {"d" 44}
100+
at 99 = void
101+
at 0 = {"a" 1}
102+
at 1 = {"c" 33}
103+
at 2 = {"d" 44}
104+
at 3 = {"e" 5}
105+
at 4 = void
106+
[
107+
{"a" 1}
108+
{"c" 33}
109+
{"d" 44}
110+
{"e" 5}
111+
]
112+
[
113+
{"a" 1}
114+
{"c" 33}
115+
{"d" 44}
116+
{"e" 5}
117+
]
118+
steps 3729 bytes 8384
119+
END
120+
~
121+
\err=
122+
~
123+
~
124+
\status=0

src/show.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <type_output.h>
1919
#include <type_parse.h>
2020
#include <type_rand.h>
21+
#include <type_record.h>
2122
#include <type_run.h>
2223
#include <type_standard.h>
2324
#include <type_str.h>
@@ -174,6 +175,8 @@ static void put_type(type t)
174175
else if (t == type_split_obj) put("split_obj");
175176
else if (t == type_fetch) put("fetch");
176177

178+
else if (t == type_record) put("record");
179+
177180
else put_ch('?');
178181
}
179182

@@ -219,6 +222,21 @@ static void show_form(struct form *form)
219222
limit_show(form->exp);
220223
}
221224

225+
static void show_record(struct record *x)
226+
{
227+
unsigned long i;
228+
for (i = 0; i < x->count; i++)
229+
{
230+
struct item *item = &x->item[i];
231+
put_ch('[');
232+
limit_show(item->key);
233+
put_ch(' ');
234+
limit_show(item->val);
235+
put_ch(']');
236+
put_ch(' ');
237+
}
238+
}
239+
222240
static void show_atom(value f)
223241
{
224242
if (f->T == type_num)
@@ -233,6 +251,8 @@ static void show_atom(value f)
233251
put_ulong(fileno(get_fh(f)));
234252
else if (f->T == type_form)
235253
show_form((struct form *)f->R);
254+
else if (f->T == type_record)
255+
show_record(get_record(f));
236256
else
237257
put_ch('?');
238258
}

src/test/check.fxl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"lib"
6767
"stream"
6868
"resolve"
69+
"record"
6970
]
7071

7172
# Gather any individually specified tests.

0 commit comments

Comments
 (0)