GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/extensions/set_extensions.c
Date: 2024-08-06 17:32:21
Exec Total Coverage
Lines: 0 55 0.0%
Functions: 0 5 0.0%
Branches: 0 46 0.0%

Line Branch Exec Source
1 /*
2 Copyright 2024 Joel Svensson svenssonjoel@yahoo.se
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "extensions/set_extensions.h"
19
20 #include "extensions.h"
21 #include "fundamental.h"
22
23 #define ABORT_ON_MERROR(X) if ((X) == ENC_SYM_MERROR) return ENC_SYM_MERROR;
24
25 static lbm_value ext_member(lbm_value *args, lbm_uint argn);
26 static lbm_value ext_set_insert(lbm_value *args, lbm_uint argn);
27 static lbm_value ext_set_union(lbm_value *args, lbm_uint argn);
28
29 bool lbm_set_extensions_init(void) {
30 bool res = true;
31 res = res && lbm_add_extension("member", ext_member);
32 res = res && lbm_add_extension("set-insert", ext_set_insert);
33 res = res && lbm_add_extension("set-union", ext_set_union);
34 return res;
35 }
36
37 static lbm_value ext_member(lbm_value *args, lbm_uint argn) {
38 lbm_value res = ENC_SYM_TERROR;
39 if (argn == 2 && lbm_is_list(args[0])) {
40 res = ENC_SYM_NIL;
41 lbm_value curr = args[0];
42
43 while (lbm_is_cons(curr)) {
44 if (struct_eq(lbm_car(curr), args[1])) {
45 res = args[0];
46 break;
47 }
48 curr = lbm_cdr(curr);
49 }
50 }
51 return res;
52 }
53
54 static lbm_value set_insert(lbm_value set, lbm_value val) {
55
56 lbm_value end = ENC_SYM_NIL;
57 lbm_value start = ENC_SYM_NIL;
58
59 lbm_value curr = set;
60 while (lbm_is_cons(curr)) {
61 lbm_value h = lbm_car(curr);
62 if (struct_eq(lbm_car(curr), val)) {
63 return set;
64 }
65 lbm_value cell = lbm_cons(h, ENC_SYM_NIL);
66 ABORT_ON_MERROR(cell);
67 if (end == ENC_SYM_NIL) {
68 end = cell;
69 start = cell;
70 } else {
71 lbm_set_cdr(end, cell);
72 end = cell;
73 }
74 curr = lbm_cdr(curr);
75 }
76 lbm_value v = lbm_cons(val, ENC_SYM_NIL);
77 ABORT_ON_MERROR(v);
78 if (end == ENC_SYM_NIL) {
79 start = v;
80 } else {
81 lbm_set_cdr(end, v);
82 }
83 return start;
84 }
85
86 /* extends a copy of the input set with the new element. */
87 static lbm_value ext_set_insert(lbm_value *args, lbm_uint argn) {
88 lbm_value res = ENC_SYM_TERROR;
89 if (argn == 2 && lbm_is_list(args[0])) {
90 res = set_insert(args[0], args[1]);
91 }
92 return res;
93 }
94
95
96 static lbm_value ext_set_union(lbm_value *args, lbm_uint argn) {
97 lbm_value res = ENC_SYM_TERROR;
98 if (argn == 2 && lbm_is_list(args[0]) && lbm_is_list(args[1])) {
99 lbm_value curr = args[0];
100 lbm_value set = args[1];
101
102 while (lbm_is_cons(curr)) {
103 set = set_insert(set, lbm_car(curr));
104 ABORT_ON_MERROR(set);
105 curr = lbm_cdr(curr);
106 }
107 return set;
108 }
109 return res;
110 }
111