From d67676c7a607a64266f90fc6db6e2d83abd9147c Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Wed, 22 Jul 2015 23:01:35 -0400 Subject: [PATCH] Working on type validation for apply --- include/cyclone/types.h | 3 ++- runtime.c | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/include/cyclone/types.h b/include/cyclone/types.h index a76b9971..434b275c 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -55,7 +55,8 @@ typedef long tag_type; #define check_overflow(x,y) ((x) > (y)) #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 symbol_tag 1 #define forward_tag 2 diff --git a/runtime.c b/runtime.c index 94b6cc58..57106ca1 100644 --- a/runtime.c +++ b/runtime.c @@ -9,7 +9,29 @@ #include "cyclone/types.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) { \ integer_type l = Cyc_length(args); \ 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 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);} @@ -1231,8 +1259,9 @@ void _Cyc_91global_91vars(object cont, object args){ return_funcall1(cont, Cyc_global_variables); } void _car(object cont, object args) { Cyc_check_num_args("car", 1, args); - //Cyc_check_type("car", - return_funcall1(cont, car(car(args))); } + { object var = 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) { Cyc_check_num_args("cdr", 1, args); return_funcall1(cont, cdr(car(args))); }