Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | Copyright 2019, 2021, 2022, 2024 Joel Svensson svenssonjoel@yahoo.se | ||
3 | 2022 Benjamin Vedder | ||
4 | |||
5 | This program is free software: you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation, either version 3 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <lbm_memory.h> | ||
20 | #include <stdio.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <stdbool.h> | ||
23 | #include <string.h> | ||
24 | #include <eval_cps.h> | ||
25 | |||
26 | #include "extensions.h" | ||
27 | #include "lbm_utils.h" | ||
28 | |||
29 | static lbm_uint ext_max = 0; | ||
30 | static lbm_uint ext_num = 0; | ||
31 | static lbm_uint next_extension_ix = 0; | ||
32 | |||
33 | lbm_extension_t *extension_table = NULL; | ||
34 | |||
35 | ✗ | lbm_value lbm_extensions_default(lbm_value *args, lbm_uint argn) { | |
36 | (void)args; | ||
37 | (void)argn; | ||
38 | ✗ | return ENC_SYM_EERROR; | |
39 | } | ||
40 | |||
41 | 17444 | int lbm_extensions_init(lbm_extension_t *extension_storage, lbm_uint extension_storage_size) { | |
42 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17444 times.
|
17444 | if (extension_storage == NULL || extension_storage_size == 0) return 0; |
43 | |||
44 | 17444 | extension_table = extension_storage; | |
45 | 17444 | memset(extension_table, 0, sizeof(lbm_extension_t) * extension_storage_size); | |
46 | |||
47 |
2/2✓ Branch 0 taken 1744400 times.
✓ Branch 1 taken 17444 times.
|
1761844 | for (lbm_uint i = 0; i < extension_storage_size; i ++) { |
48 | 1744400 | extension_storage[i].fptr = lbm_extensions_default; | |
49 | } | ||
50 | |||
51 | 17444 | ext_num = 0; | |
52 | 17444 | next_extension_ix = 0; | |
53 | 17444 | ext_max = (lbm_uint)extension_storage_size; | |
54 | |||
55 | 17444 | return 1; | |
56 | } | ||
57 | |||
58 | 230875674 | lbm_uint lbm_get_max_extensions(void) { | |
59 | 230875674 | return ext_max; | |
60 | } | ||
61 | |||
62 | ✗ | lbm_uint lbm_get_num_extensions(void) { | |
63 | ✗ | return ext_num; | |
64 | } | ||
65 | |||
66 | 14 | extension_fptr lbm_get_extension(lbm_uint sym) { | |
67 | 14 | lbm_uint ext_next = sym - EXTENSION_SYMBOLS_START; | |
68 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | if (ext_next >= ext_max) { |
69 | ✗ | return NULL; | |
70 | } | ||
71 | 14 | return extension_table[ext_next].fptr; | |
72 | } | ||
73 | |||
74 | ✗ | bool lbm_clr_extension(lbm_uint sym_id) { | |
75 | ✗ | lbm_uint ext_id = SYMBOL_IX(sym_id); | |
76 | ✗ | if (ext_id >= ext_max) { | |
77 | ✗ | return false; | |
78 | } | ||
79 | ✗ | extension_table[ext_id].name = NULL; | |
80 | ✗ | extension_table[ext_id].fptr = lbm_extensions_default; | |
81 | ✗ | return true; | |
82 | } | ||
83 | |||
84 | 14 | bool lbm_lookup_extension_id(char *sym_str, lbm_uint *ix) { | |
85 |
1/2✓ Branch 0 taken 1386 times.
✗ Branch 1 not taken.
|
1386 | for (lbm_uint i = 0; i < ext_max; i ++) { |
86 |
1/2✓ Branch 0 taken 1386 times.
✗ Branch 1 not taken.
|
1386 | if(extension_table[i].name) { |
87 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1372 times.
|
1386 | if (str_eq(extension_table[i].name, sym_str)) { |
88 | 14 | *ix = i + EXTENSION_SYMBOLS_START; | |
89 | 14 | return true; | |
90 | } | ||
91 | } | ||
92 | } | ||
93 | ✗ | return false; | |
94 | } | ||
95 | |||
96 | 1709554 | bool lbm_add_extension(char *sym_str, extension_fptr ext) { | |
97 | lbm_value symbol; | ||
98 | |||
99 | // Check if symbol already exists. | ||
100 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1709540 times.
|
1709554 | if (lbm_get_symbol_by_name(sym_str, &symbol)) { |
101 |
1/2✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
14 | if (lbm_is_extension(lbm_enc_sym(symbol))) { |
102 | // update the extension entry. | ||
103 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | if (str_eq(extension_table[SYMBOL_IX(symbol)].name, sym_str)) { |
104 | // Do not replace name ptr. | ||
105 | 14 | extension_table[SYMBOL_IX(symbol)].fptr = ext; | |
106 | 14 | return true; | |
107 | } | ||
108 | } | ||
109 | ✗ | return false; | |
110 | } | ||
111 | |||
112 |
1/2✓ Branch 0 taken 1709540 times.
✗ Branch 1 not taken.
|
1709540 | if (next_extension_ix < ext_max) { |
113 | 1709540 | lbm_uint sym_ix = next_extension_ix ++; | |
114 | 1709540 | extension_table[sym_ix].name = sym_str; | |
115 | 1709540 | extension_table[sym_ix].fptr = ext; | |
116 | 1709540 | ext_num ++; | |
117 | 1709540 | return true; | |
118 | } | ||
119 | ✗ | return false; | |
120 | } | ||
121 | |||
122 | // Helpers for extension developers: | ||
123 | |||
124 | 2841 | static bool lbm_is_number_all(lbm_value *args, lbm_uint argn) { | |
125 |
2/2✓ Branch 0 taken 8579 times.
✓ Branch 1 taken 2841 times.
|
11420 | for (lbm_uint i = 0;i < argn;i++) { |
126 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8579 times.
|
8579 | if (!lbm_is_number(args[i])) { |
127 | ✗ | return false; | |
128 | } | ||
129 | } | ||
130 | 2841 | return true; | |
131 | } | ||
132 | |||
133 | ✗ | bool lbm_check_true_false(lbm_value v) { | |
134 | ✗ | bool res = lbm_is_symbol_true(v) || lbm_is_symbol_nil(v); | |
135 | ✗ | lbm_set_error_reason((char*)lbm_error_str_not_a_boolean); | |
136 | ✗ | return res; | |
137 | } | ||
138 | |||
139 | 2813 | bool lbm_check_number_all(lbm_value *args, lbm_uint argn) { | |
140 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2813 times.
|
2813 | if (!lbm_is_number_all(args, argn)) { |
141 | ✗ | lbm_set_error_reason((char*)lbm_error_str_no_number); | |
142 | ✗ | return false; | |
143 | } | ||
144 | 2813 | return true; | |
145 | } | ||
146 | |||
147 | ✗ | bool lbm_check_argn(lbm_uint argn, lbm_uint n) { | |
148 | ✗ | if (argn != n) { | |
149 | ✗ | lbm_set_error_reason((char*)lbm_error_str_num_args); | |
150 | ✗ | return false; | |
151 | } else { | ||
152 | ✗ | return true; | |
153 | } | ||
154 | } | ||
155 | |||
156 | 28 | bool lbm_check_argn_number(lbm_value *args, lbm_uint argn, lbm_uint n) { | |
157 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
|
28 | if (!lbm_is_number_all(args, argn)) { |
158 | ✗ | lbm_set_error_reason((char*)lbm_error_str_no_number); | |
159 | ✗ | return false; | |
160 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
|
28 | } else if (argn != n) { |
161 | ✗ | lbm_set_error_reason((char*)lbm_error_str_num_args); | |
162 | ✗ | return false; | |
163 | } else { | ||
164 | 28 | return true; | |
165 | } | ||
166 | } | ||
167 |