diff options
author | tomsmeding <tom.smeding@gmail.com> | 2016-08-23 20:58:50 +0200 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2016-08-23 20:58:50 +0200 |
commit | cac651cd88f8da1e5957b0cc13fa25d79e1887fc (patch) | |
tree | 38b2645803df92661b797a64f18772e691d3d8fd /inter_builtins.c | |
parent | 44602cb35735575c15cfcb92779337778649df8a (diff) |
Many things
- two-letter AST union members
- AST_QUOTED
- AST_LAMBDA
- an interpreter that works
- function registering in the interpreter
- some builtins
Diffstat (limited to 'inter_builtins.c')
-rw-r--r-- | inter_builtins.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/inter_builtins.c b/inter_builtins.c new file mode 100644 index 0000000..cc96afd --- /dev/null +++ b/inter_builtins.c @@ -0,0 +1,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 |