1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "inter_builtins.h"
#include "interpreter.h"
#include "util.h"
InterRet builtin_do(InterState *is,int nargs,AST **args){
assert(args);
InterRet ir;
for(int i=0;i<nargs;i++){
assert(args[i]);
ir=inter_runcode(is,args[i]);
if(ir.errstr)return ir;
if(i<nargs-1)ast_free(ir.ast);
}
return ir;
}
InterRet builtin_print(InterState *is,int nargs,AST **args){
(void)is;
assert(args);
for(int i=0;i<nargs;i++){
assert(args[i]);
char *s=ast_stringify(args[i]);
if(i>0)putchar(' ');
printf("%s",s);
free(s);
}
putchar('\n');
return ir_ast(ast_list(0,malloc(1,AST*)));
}
#define BUILTIN_ARITH_OP(op,name,defval,expr) \
InterRet builtin_##name(InterState *is,int nargs,AST **args){ \
(void)is; \
assert(args); \
if(nargs==0)return ir_ast(ast_number(defval)); \
for(int i=0;i<nargs;i++){ \
assert(args[i]); \
if(args[i]->type!=AST_NUMBER){ \
return ir_err_c("Non-number argument passed to builtin '" #op "'"); \
} \
} \
double res=args[0]->nu.num; \
for(int i=1;i<nargs;i++){ \
double n=args[i]->nu.num; \
res=expr; \
} \
return ir_ast(ast_number(res)); \
}
BUILTIN_ARITH_OP(+,sum,0,res+n)
BUILTIN_ARITH_OP(-,difference,0,res-n)
BUILTIN_ARITH_OP(*,product,1,res*n)
BUILTIN_ARITH_OP(/,quotient,1,res/n)
BUILTIN_ARITH_OP(%,remainder,1,floatmod(res,n))
#undef BUILTIN_ARITH_OP
|