Working on type validation for apply

This commit is contained in:
Justin Ethier 2015-07-22 23:01:35 -04:00
parent d95daed1dd
commit d67676c7a6
2 changed files with 34 additions and 4 deletions

View file

@ -55,7 +55,8 @@ typedef long tag_type;
#define check_overflow(x,y) ((x) > (y)) #define check_overflow(x,y) ((x) > (y))
#endif #endif
/* Define tag values. Could be an enum... */ /* Define tag values. Could be an enum...
Remember to update tag_names in runtime.c when adding new tags */
#define cons_tag 0 #define cons_tag 0
#define symbol_tag 1 #define symbol_tag 1
#define forward_tag 2 #define forward_tag 2

View file

@ -9,7 +9,29 @@
#include "cyclone/types.h" #include "cyclone/types.h"
#include "cyclone/runtime.h" #include "cyclone/runtime.h"
/* TODO: working on validation for applying functions */ const char *tag_names[20] = { \
"pair" \
, "symbol" \
, "" \
, "closure" \
, "closure" \
, "closure" \
, "closure" \
, "closure" \
, "closure" \
, "integer" \
, "double" \
, "string" \
, "primitive" \
, "eof" \
, "port" \
, "boolean" \
, "C primitive" \
, "vector" \
, "" \
, "" };
/* Error handling section */
#define Cyc_check_num_args(fnc_name, num_args, args) { \ #define Cyc_check_num_args(fnc_name, num_args, args) { \
integer_type l = Cyc_length(args); \ integer_type l = Cyc_length(args); \
if (num_args > l.value) { \ if (num_args > l.value) { \
@ -19,6 +41,12 @@
} \ } \
} }
void Cyc_invalid_type_error(int tag, object found) {
char buf[256];
snprintf(buf, 255, "Invalid type: expected %s, found", tag_names[tag]);
Cyc_rt_raise2(buf, found);
}
/* Funcall section, these are hardcoded here to support /* Funcall section, these are hardcoded here to support
functions in this module. */ functions in this module. */
#define funcall1(cfn,a1) if (type_of(cfn) == cons_tag || prim(cfn)) { Cyc_apply(0, (closure)a1, cfn); } else { ((cfn)->fn)(1,cfn,a1);} #define funcall1(cfn,a1) if (type_of(cfn) == cons_tag || prim(cfn)) { Cyc_apply(0, (closure)a1, cfn); } else { ((cfn)->fn)(1,cfn,a1);}
@ -1231,8 +1259,9 @@ void _Cyc_91global_91vars(object cont, object args){
return_funcall1(cont, Cyc_global_variables); } return_funcall1(cont, Cyc_global_variables); }
void _car(object cont, object args) { void _car(object cont, object args) {
Cyc_check_num_args("car", 1, args); Cyc_check_num_args("car", 1, args);
//Cyc_check_type("car", { object var = car(args);
return_funcall1(cont, car(car(args))); } if (eq(boolean_f, Cyc_is_cons(var))) Cyc_invalid_type_error(cons_tag, var);
return_funcall1(cont, car(var)); }}
void _cdr(object cont, object args) { void _cdr(object cont, object args) {
Cyc_check_num_args("cdr", 1, args); Cyc_check_num_args("cdr", 1, args);
return_funcall1(cont, cdr(car(args))); } return_funcall1(cont, cdr(car(args))); }