Skip to content

Commit 24af743

Browse files
committed
vhdl: ignore duplicate map keys
1 parent 11086bf commit 24af743

File tree

3 files changed

+62
-13
lines changed

3 files changed

+62
-13
lines changed

impls/vhdl/core.vhdl

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,11 @@ package body core is
260260
end procedure fn_vector_q;
261261

262262
procedure fn_hash_map(args: inout mal_val_ptr; result: out mal_val_ptr; err: out mal_val_ptr) is
263+
variable new_map: mal_val_ptr;
263264
begin
264-
args.val_type := mal_hashmap;
265-
result := args;
265+
new_empty_hashmap(new_map);
266+
hashmap_extend(new_map, args.seq_val.all);
267+
result := m;
266268
end procedure fn_hash_map;
267269

268270
procedure fn_map_q(args: inout mal_val_ptr; result: out mal_val_ptr; err: out mal_val_ptr) is
@@ -272,14 +274,9 @@ package body core is
272274

273275
procedure fn_assoc(args: inout mal_val_ptr; result: out mal_val_ptr; err: out mal_val_ptr) is
274276
variable new_hashmap: mal_val_ptr;
275-
variable i: integer;
276277
begin
277278
hashmap_copy(args.seq_val(0), new_hashmap);
278-
i := 1;
279-
while i < args.seq_val'length loop
280-
hashmap_put(new_hashmap, args.seq_val(i), args.seq_val(i + 1));
281-
i := i + 2;
282-
end loop;
279+
hashmap_extend(new_hashmap, args.seq_val.all(1 to args.seq_val'last));
283280
result := new_hashmap;
284281
end procedure fn_assoc;
285282

impls/vhdl/reader.vhdl

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ package body reader is
246246
end if;
247247
end procedure read_atom;
248248

249-
procedure read_sequence(list_type: in mal_type_tag; end_ch: in string; r: inout reader_class; result: out mal_val_ptr; err: out mal_val_ptr) is
249+
procedure read_sequence(end_ch: in string; r: inout reader_class; result: out mal_seq_ptr; err: out mal_val_ptr) is
250250
variable token: line;
251251
variable element, sub_err: mal_val_ptr;
252252
variable seq: mal_seq_ptr;
@@ -270,9 +270,50 @@ package body reader is
270270
return;
271271
end if;
272272
reader_next(r, token); -- Consume the close paren
273-
new_seq_obj(list_type, seq, result);
273+
result := seq;
274274
end procedure read_sequence;
275275

276+
procedure read_list(r: inout reader_class; result: out mal_seq_ptr; err: out mal_val_ptr) is
277+
variable seq: mal_seq_ptr;
278+
variable sub_err: mal_val_ptr;
279+
begin
280+
read_sequence(")", r, seq, sub_err);
281+
if sub_err = null then
282+
new_seq_obj(mal_list, seq, result);
283+
else
284+
err := sub_err;
285+
result := null;
286+
end if;
287+
end procedure read_list;
288+
289+
procedure read_vector(r: inout reader_class; result: out mal_seq_ptr; err: out mal_val_ptr) is
290+
variable seq: mal_seq_ptr;
291+
variable sub_err: mal_val_ptr;
292+
begin
293+
read_sequence("]", r, seq, sub_err);
294+
if sub_err = null then
295+
new_seq_obj(mal_vector, seq, result);
296+
else
297+
err := sub_err;
298+
result := null;
299+
end if;
300+
end procedure read_vector;
301+
302+
procedure read_map(r: inout reader_class; result: out mal_val_ptr; err: out mal_val_ptr) is
303+
variable seq: mal_seq_ptr;
304+
variable sub_err, new_map: mal_val_ptr;
305+
begin
306+
read_sequence("}", r, seq, sub_err);
307+
if sub_err = null then
308+
new_empty_hashmap(new_map);
309+
hashmap_extend(new_map, seq.all);
310+
result := new_map;
311+
else
312+
err := sub_err;
313+
result := null;
314+
end if;
315+
end procedure read_map;
316+
276317
procedure reader_macro(r: inout reader_class; result: out mal_val_ptr; err: out mal_val_ptr; sym_name: in string) is
277318
variable token, sym_line: line;
278319
variable seq: mal_seq_ptr;
@@ -339,11 +380,11 @@ package body reader is
339380
end if;
340381
when '^' => with_meta_reader_macro(r, result, err);
341382
when '@' => reader_macro(r, result, err, "deref");
342-
when '(' => read_sequence(mal_list, ")", r, result, err);
383+
when '(' => read_list(r, result, err);
343384
when ')' => new_string("unexcepted ')'", err);
344-
when '[' => read_sequence(mal_vector, "]", r, result, err);
385+
when '[' => read_vector(r, result, err);
345386
when ']' => new_string("unexcepted ']'", err);
346-
when '{' => read_sequence(mal_hashmap, "}", r, result, err);
387+
when '{' => read_map(r, result, err);
347388
when '}' => new_string("unexcepted '}'", err);
348389
when others => read_atom(r, result, err);
349390
end case;

impls/vhdl/types.vhdl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ package types is
6666
procedure new_atom(val: inout mal_val_ptr; obj: out mal_val_ptr);
6767

6868
procedure hashmap_copy(hashmap: inout mal_val_ptr; obj: out mal_val_ptr);
69+
procedure hashmap_extend(hm: inout mal_val_ptr; kvs: in mal_seq);
6970
procedure hashmap_get(hashmap: inout mal_val_ptr; key: inout mal_val_ptr; val: out mal_val_ptr);
7071
procedure hashmap_contains(hashmap: inout mal_val_ptr; key: inout mal_val_ptr; ok: out boolean);
7172
procedure hashmap_put(hashmap: inout mal_val_ptr; key: inout mal_val_ptr; val: inout mal_val_ptr);
@@ -213,6 +214,16 @@ package body types is
213214
new_seq_obj(mal_hashmap, new_seq, obj);
214215
end procedure hashmap_copy;
215216

217+
procedure hashmap_extend(hm: inout mal_val_ptr; kvs: in mal_seq) is
218+
variable i: natural;
219+
begin
220+
i := 0;
221+
while i < kvs'length loop
222+
hashmap_put(hm, kvs(i), kvs(i + 1));
223+
i := i + 2;
224+
end loop;
225+
end hashmap_extend;
226+
216227
procedure hashmap_get(hashmap: inout mal_val_ptr; key: inout mal_val_ptr; val: out mal_val_ptr) is
217228
variable i: natural;
218229
variable curr_key: mal_val_ptr;

0 commit comments

Comments
 (0)