A small standalone Lisp used as a scripting language in the Z2 game engine
Révision | 43921e54fe35496ec29eb0bf1e74d1d5a906d3b9 (tree) |
---|---|
l'heure | 2019-11-10 05:12:48 |
Auteur | AlaskanEmily <emily@alas...> |
Commiter | AlaskanEmily |
Add bitwise operators as builtins
@@ -19,28 +19,46 @@ | ||
19 | 19 | |
20 | 20 | %-----------------------------------------------------------------------------% |
21 | 21 | |
22 | +:- mode arith_pred == (pred(in, in, uo) is det). | |
23 | +:- inst arith_pred == (pred(in, in, uo) is det). | |
24 | + | |
25 | +%-----------------------------------------------------------------------------% | |
26 | + | |
22 | 27 | :- type math_pred == (pred(number, number, string)). |
23 | -:- mode math_pred == (pred(in, in, uo) is det). | |
24 | -:- inst math_pred == (pred(in, in, uo) is det). | |
28 | + | |
29 | +%-----------------------------------------------------------------------------% | |
30 | + | |
31 | +:- type bit_pred == (pred(int, int, int)). | |
25 | 32 | |
26 | 33 | %-----------------------------------------------------------------------------% |
27 | 34 | % TODO: Variadic + and *? |
28 | -:- pred builtin_plus `with_type` math_pred `with_inst` math_pred. | |
29 | -:- pred builtin_minus `with_type` math_pred `with_inst` math_pred. | |
30 | -:- pred builtin_times `with_type` math_pred `with_inst` math_pred. | |
31 | -:- pred builtin_divide `with_type` math_pred `with_inst` math_pred. | |
35 | +:- pred builtin_plus `with_type` math_pred `with_inst` arith_pred. | |
36 | +:- pred builtin_minus `with_type` math_pred `with_inst` arith_pred. | |
37 | +:- pred builtin_times `with_type` math_pred `with_inst` arith_pred. | |
38 | +:- pred builtin_divide `with_type` math_pred `with_inst` arith_pred. | |
39 | + | |
40 | +%-----------------------------------------------------------------------------% | |
41 | + | |
42 | +:- pred builtin_and `with_type` bit_pred `with_inst` arith_pred. | |
43 | +:- pred builtin_or `with_type` bit_pred `with_inst` arith_pred. | |
44 | +:- pred builtin_xor`with_type` bit_pred `with_inst` arith_pred. | |
45 | + | |
46 | +%-----------------------------------------------------------------------------% | |
47 | + | |
48 | +:- pred builtin_math_bind(math_pred, arithmetic, list(element), result). | |
49 | +:- mode builtin_math_bind(arith_pred, in, in, res_uo) is det. | |
32 | 50 | |
33 | 51 | %-----------------------------------------------------------------------------% |
34 | 52 | |
35 | -:- pred builtin_arithmetic_bind(math_pred, arithmetic, list(element), result). | |
36 | -:- mode builtin_arithmetic_bind(math_pred, in, in, res_uo) is det. | |
53 | +:- pred builtin_bit_bind(bit_pred, logic, list(element), result). | |
54 | +:- mode builtin_bit_bind(arith_pred, in, in, res_uo) is det. | |
37 | 55 | |
38 | 56 | %=============================================================================% |
39 | 57 | % Most of the implementation of the arithmetic submodule is private. |
40 | 58 | :- implementation. |
41 | 59 | %=============================================================================% |
42 | 60 | |
43 | -:- use_module int. | |
61 | +:- import_module int. | |
44 | 62 | :- import_module float. |
45 | 63 | |
46 | 64 | %-----------------------------------------------------------------------------% |
@@ -123,10 +141,16 @@ builtin_times(ANum, BNum, arithmetic(int.times, float_times, ANum, BNum)). | ||
123 | 141 | builtin_divide(ANum, BNum, arithmetic('int__div', float_divide, ANum, BNum)). |
124 | 142 | |
125 | 143 | %-----------------------------------------------------------------------------% |
144 | + | |
145 | +builtin_and(A, B, A /\ B). | |
146 | +builtin_or(A, B, A \/ B). | |
147 | +builtin_xor(A, B, int.xor(A, B)). | |
148 | + | |
149 | +%-----------------------------------------------------------------------------% | |
126 | 150 | % Implementation of arithmetic operators. |
127 | 151 | :- pred arithmetic(math_pred, |
128 | 152 | arithmetic, list.list(element), result). |
129 | -:- mode arithmetic(math_pred, | |
153 | +:- mode arithmetic(arith_pred, | |
130 | 154 | in, in, res_uo) is det. |
131 | 155 | |
132 | 156 | :- pragma inline(arithmetic/4). |
@@ -167,4 +191,62 @@ arithmetic(Pred, Op, Args, Result) :- | ||
167 | 191 | |
168 | 192 | %-----------------------------------------------------------------------------% |
169 | 193 | |
170 | -builtin_arithmetic_bind(Pred, Op, Args, Out) :- arithmetic(Pred, Op, Args, Out). | |
194 | +builtin_math_bind(Pred, Op, Args, Out) :- arithmetic(Pred, Op, Args, Out). | |
195 | + | |
196 | +%-----------------------------------------------------------------------------% | |
197 | + | |
198 | +builtin_bit_bind(Pred, Op, Args, Result) :- | |
199 | + two_atoms(Args, ArgsResult), | |
200 | + ( | |
201 | + ArgsResult = maybe.error(Error), | |
202 | + builtin_op_tag(logic(Op), Tag), | |
203 | + Result = maybe.error(func_error(Tag, 2, Error)) | |
204 | + ; | |
205 | + ArgsResult = maybe.ok({AStr, BStr}), | |
206 | + ( if | |
207 | + number_type(AStr, ANum) | |
208 | + then | |
209 | + ( if | |
210 | + number_type(BStr, BNum) | |
211 | + then | |
212 | + ( | |
213 | + ANum = int(A), | |
214 | + ( | |
215 | + BNum = int(B), | |
216 | + Pred(A, B, Out), | |
217 | + Result = maybe.ok(atom(string.from_int(Out))) | |
218 | + ; | |
219 | + ANum = int(_), BNum = float(_), | |
220 | + builtin_op_tag(logic(Op), Tag), | |
221 | + Result = maybe.error(func_error( | |
222 | + Tag, | |
223 | + 2, | |
224 | + string.append(string.append( | |
225 | + "arg 2 not an integer (", BStr), ")"))) | |
226 | + ) | |
227 | + ; | |
228 | + ANum = float(_), | |
229 | + builtin_op_tag(logic(Op), Tag), | |
230 | + Result = maybe.error(func_error( | |
231 | + Tag, | |
232 | + 2, | |
233 | + string.append(string.append( | |
234 | + "arg 1 not an integer (", BStr), ")"))) | |
235 | + ) | |
236 | + else | |
237 | + builtin_op_tag(logic(Op), Tag), | |
238 | + Result = maybe.error(func_error( | |
239 | + Tag, | |
240 | + 2, | |
241 | + string.append(string.append( | |
242 | + "arg 2 not a number (", BStr), ")"))) | |
243 | + ) | |
244 | + else | |
245 | + builtin_op_tag(logic(Op), Tag), | |
246 | + Result = maybe.error(func_error( | |
247 | + Tag, | |
248 | + 2, | |
249 | + string.append(string.append( | |
250 | + "arg 1 not a number (", AStr), ")"))) | |
251 | + ) | |
252 | + ). |
@@ -167,6 +167,14 @@ | ||
167 | 167 | :- pred builtin_divide_bind `with_type` execute_pred `with_inst` execute_pred. |
168 | 168 | |
169 | 169 | %-----------------------------------------------------------------------------% |
170 | +% Bitwise components. | |
171 | +%-----------------------------------------------------------------------------% | |
172 | + | |
173 | +:- pred builtin_and_bind `with_type` execute_pred `with_inst` execute_pred. | |
174 | +:- pred builtin_or_bind `with_type` execute_pred `with_inst` execute_pred. | |
175 | +:- pred builtin_xor_bind `with_type` execute_pred `with_inst` execute_pred. | |
176 | + | |
177 | +%-----------------------------------------------------------------------------% | |
170 | 178 | % Define components. |
171 | 179 | %-----------------------------------------------------------------------------% |
172 | 180 |
@@ -370,10 +378,16 @@ builtin_ge_bind(E, R, !RT) :- builtin_comparison_bind(builtin_ge, E, R, !RT). | ||
370 | 378 | |
371 | 379 | %-----------------------------------------------------------------------------% |
372 | 380 | |
373 | -builtin_plus_bind(E, R, !RT) :- builtin_arithmetic_bind(builtin_plus, plus, E, R). | |
374 | -builtin_minus_bind(E, R, !RT) :- builtin_arithmetic_bind(builtin_minus, minus, E, R). | |
375 | -builtin_times_bind(E, R, !RT) :- builtin_arithmetic_bind(builtin_times, times, E, R). | |
376 | -builtin_divide_bind(E, R, !RT) :- builtin_arithmetic_bind(builtin_divide, divide, E, R). | |
381 | +builtin_plus_bind(E, R, !RT) :- builtin_math_bind(builtin_plus, plus, E, R). | |
382 | +builtin_minus_bind(E, R, !RT) :- builtin_math_bind(builtin_minus, minus, E, R). | |
383 | +builtin_times_bind(E, R, !RT) :- builtin_math_bind(builtin_times, times, E, R). | |
384 | +builtin_divide_bind(E, R, !RT) :- builtin_math_bind(builtin_divide, divide, E, R). | |
385 | + | |
386 | +%-----------------------------------------------------------------------------% | |
387 | + | |
388 | +builtin_and_bind(E, R, !RT) :- builtin_bit_bind(builtin_and, int_and, E, R). | |
389 | +builtin_or_bind(E, R, !RT) :- builtin_bit_bind(builtin_or, int_or, E, R). | |
390 | +builtin_xor_bind(E, R, !RT) :- builtin_bit_bind(builtin_xor, int_xor, E, R). | |
377 | 391 | |
378 | 392 | %-----------------------------------------------------------------------------% |
379 | 393 | % Used to implement let and def |