From b5cbca0e8d5b97d50dbf07553f5a898d2ee067fb Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 20 Sep 2005 12:06:51 +0000 Subject: [PATCH] *** empty log message *** --- ase/lsp/eval.c | 9 +- ase/lsp/init.c | 6 +- ase/lsp/makefile.cl | 2 +- ase/lsp/makefile.in | 2 +- ase/lsp/mem.c | 4 +- ase/lsp/obj.h | 8 +- ase/lsp/prim.c | 142 +-------------------------- ase/lsp/prim.h | 16 ++- ase/lsp/prim_compar.c | 207 +++++++++++++++++++++++++++++++++++++++ ase/lsp/prim_math.c | 220 +++++++++++++++++++++++++++++++++++++++--- ase/test/lsp/t2.lsp | 3 +- ase/test/lsp/t3.lsp | 8 ++ ase/test/lsp/t4.lsp | 7 ++ ase/test/lsp/t5.lsp | 7 ++ 14 files changed, 473 insertions(+), 168 deletions(-) create mode 100644 ase/lsp/prim_compar.c create mode 100644 ase/test/lsp/t3.lsp create mode 100644 ase/test/lsp/t4.lsp create mode 100644 ase/test/lsp/t5.lsp diff --git a/ase/lsp/eval.c b/ase/lsp/eval.c index 741f0111..d417f82f 100644 --- a/ase/lsp/eval.c +++ b/ase/lsp/eval.c @@ -1,5 +1,5 @@ /* - * $Id: eval.c,v 1.11 2005-09-20 09:17:06 bacon Exp $ + * $Id: eval.c,v 1.12 2005-09-20 12:06:51 bacon Exp $ */ #include @@ -31,7 +31,8 @@ xp_lsp_obj_t* xp_lsp_eval (xp_lsp_t* lsp, xp_lsp_obj_t* obj) } */ - if ((assoc = xp_lsp_lookup(lsp->mem, obj)) == XP_NULL) { + assoc = xp_lsp_lookup(lsp->mem, obj); + if (assoc == XP_NULL || assoc->value == XP_NULL) { if (lsp->opt_undef_symbol) { lsp->errnum = XP_LSP_ERR_UNDEF_SYMBOL; return XP_NULL; @@ -121,8 +122,8 @@ static xp_lsp_obj_t* eval_cons (xp_lsp_t* lsp, xp_lsp_obj_t* cons) return apply (lsp, func, cdr); } else if (XP_LSP_TYPE(func) == XP_LSP_OBJ_PRIM) { - // primitive function - return XP_LSP_PIMPL(func) (lsp, cdr); + /* primitive function */ + return XP_LSP_PRIM(func) (lsp, cdr); } else { //TODO: emit the name for debugging diff --git a/ase/lsp/init.c b/ase/lsp/init.c index 9e28792f..bc96c432 100644 --- a/ase/lsp/init.c +++ b/ase/lsp/init.c @@ -1,5 +1,5 @@ /* - * $Id: init.c,v 1.8 2005-09-20 11:19:15 bacon Exp $ + * $Id: init.c,v 1.9 2005-09-20 12:06:51 bacon Exp $ */ #include @@ -150,11 +150,15 @@ static int __add_builtin_prims (xp_lsp_t* lsp) ADD_PRIM (lsp, XP_TEXT("let"), xp_lsp_prim_let); ADD_PRIM (lsp, XP_TEXT("let*"), xp_lsp_prim_letx); + ADD_PRIM (lsp, XP_TEXT("="), xp_lsp_prim_eq); ADD_PRIM (lsp, XP_TEXT(">"), xp_lsp_prim_gt); ADD_PRIM (lsp, XP_TEXT("<"), xp_lsp_prim_lt); ADD_PRIM (lsp, XP_TEXT("+"), xp_lsp_prim_plus); ADD_PRIM (lsp, XP_TEXT("-"), xp_lsp_prim_minus); + ADD_PRIM (lsp, XP_TEXT("*"), xp_lsp_prim_multiply); + ADD_PRIM (lsp, XP_TEXT("/"), xp_lsp_prim_divide); + ADD_PRIM (lsp, XP_TEXT("%"), xp_lsp_prim_modulus); return 0; } diff --git a/ase/lsp/makefile.cl b/ase/lsp/makefile.cl index 72f6d4e5..c1a13d73 100644 --- a/ase/lsp/makefile.cl +++ b/ase/lsp/makefile.cl @@ -1,6 +1,6 @@ SRCS = name.c token.c array.c mem.c env.c error.c \ init.c read.c eval.c print.c \ - prim.c prim_prog.c prim_let.c + prim.c prim_prog.c prim_let.c prim_compar.c prim_math.c OBJS = $(SRCS:.c=.obj) OUT = xplsp.lib diff --git a/ase/lsp/makefile.in b/ase/lsp/makefile.in index 77b48f02..05ca57f3 100644 --- a/ase/lsp/makefile.in +++ b/ase/lsp/makefile.in @@ -1,6 +1,6 @@ SRCS = name.c token.c array.c mem.c env.c error.c \ init.c read.c eval.c print.c \ - prim.c prim_prog.c prim_let.c prim_math.c + prim.c prim_prog.c prim_let.c prim_compar.c prim_math.c OBJS = $(SRCS:.c=.o) OUT = libxplsp.a diff --git a/ase/lsp/mem.c b/ase/lsp/mem.c index fb0600a8..fa10b332 100644 --- a/ase/lsp/mem.c +++ b/ase/lsp/mem.c @@ -1,5 +1,5 @@ /* - * $Id: mem.c,v 1.6 2005-09-20 11:19:15 bacon Exp $ + * $Id: mem.c,v 1.7 2005-09-20 12:06:51 bacon Exp $ */ #include @@ -536,7 +536,7 @@ xp_lsp_obj_t* xp_lsp_make_prim (xp_lsp_mem_t* mem, void* impl) obj = xp_lsp_alloc (mem, XP_LSP_OBJ_PRIM, xp_sizeof(xp_lsp_obj_prim_t)); if (obj == XP_NULL) return XP_NULL; - XP_LSP_PIMPL(obj) = impl; + XP_LSP_PRIM(obj) = impl; return obj; } diff --git a/ase/lsp/obj.h b/ase/lsp/obj.h index 72c332f2..e16e7bcd 100644 --- a/ase/lsp/obj.h +++ b/ase/lsp/obj.h @@ -1,5 +1,5 @@ /* - * $Id: obj.h,v 1.2 2005-09-20 11:19:15 bacon Exp $ + * $Id: obj.h,v 1.3 2005-09-20 12:06:51 bacon Exp $ */ #ifndef _XP_LSP_OBJ_H_ @@ -29,7 +29,7 @@ enum xp_uint32_t mark: 4; \ xp_uint32_t lock: 4; \ xp_size_t size; \ - struct xp_lsp_obj_t* link + struct xp_lsp_obj_t* link struct xp_lsp_obj_t { @@ -100,7 +100,7 @@ struct xp_lsp_obj_macro_t struct xp_lsp_obj_prim_t { XP_LSP_OBJ_HEADER; - void* impl; // xp_lsp_prim_t + void* impl; /* xp_lsp_prim_t */ }; typedef struct xp_lsp_obj_t xp_lsp_obj_t; @@ -146,6 +146,6 @@ typedef struct xp_lsp_obj_prim_t xp_lsp_obj_prim_t; #define XP_LSP_FBODY(x) (((xp_lsp_obj_func_t*)x)->body) #define XP_LSP_MFORMAL(x) (((xp_lsp_obj_macro_t*)x)->formal) #define XP_LSP_MBODY(x) (((xp_lsp_obj_macro_t*)x)->body) -#define XP_LSP_PIMPL(x) ((xp_lsp_prim_t)(((xp_lsp_obj_prim_t*)x)->impl)) +#define XP_LSP_PRIM(x) ((xp_lsp_prim_t)(((xp_lsp_obj_prim_t*)x)->impl)) #endif diff --git a/ase/lsp/prim.c b/ase/lsp/prim.c index 411dcfe7..5ebc311f 100644 --- a/ase/lsp/prim.c +++ b/ase/lsp/prim.c @@ -1,5 +1,5 @@ /* - * $Id: prim.c,v 1.6 2005-09-20 11:19:15 bacon Exp $ + * $Id: prim.c,v 1.7 2005-09-20 12:06:51 bacon Exp $ */ #include @@ -44,8 +44,6 @@ static int __add_prim (xp_lsp_mem_t* mem, return 0; } - - xp_lsp_obj_t* xp_lsp_prim_abort (xp_lsp_t* lsp, xp_lsp_obj_t* args) { XP_LSP_PRIM_CHECK_ARG_COUNT (lsp, args, 0, 0); @@ -173,9 +171,11 @@ xp_lsp_obj_t* xp_lsp_prim_while (xp_lsp_t* lsp, xp_lsp_obj_t* args) tmp = XP_LSP_CDR(args); while (XP_LSP_TYPE(tmp) == XP_LSP_OBJ_CONS) { - if (xp_lsp_eval(lsp, XP_LSP_CAR(tmp)) == XP_NULL) return XP_NULL; + if (xp_lsp_eval(lsp, XP_LSP_CAR(tmp)) == XP_NULL) + return XP_NULL; tmp = XP_LSP_CDR(tmp); } + if (tmp != lsp->mem->nil) { lsp->errnum = XP_LSP_ERR_BAD_ARG; return XP_NULL; @@ -397,137 +397,3 @@ xp_lsp_obj_t* xp_lsp_prim_demac (xp_lsp_t* lsp, xp_lsp_obj_t* args) } return mac; } - -xp_lsp_obj_t* xp_lsp_prim_gt (xp_lsp_t* lsp, xp_lsp_obj_t* args) -{ - xp_lsp_obj_t* p1, * p2; - int res; - - XP_LSP_PRIM_CHECK_ARG_COUNT (lsp, args, 2, 2); - xp_assert (XP_LSP_TYPE(args) == XP_LSP_OBJ_CONS); - - p1 = xp_lsp_eval (lsp, XP_LSP_CAR(args)); - if (p1 == XP_NULL) return XP_NULL; - // TODO: lock p1.... - - p2 = xp_lsp_eval (lsp, XP_LSP_CAR(XP_LSP_CDR(args))); - if (p2 == XP_NULL) return XP_NULL; - - if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_INT) { - if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_INT) { - res = XP_LSP_IVALUE(p1) > XP_LSP_IVALUE(p2); - } - else if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_REAL) { - res = XP_LSP_IVALUE(p1) > XP_LSP_RVALUE(p2); - } - else { - lsp->errnum = XP_LSP_ERR_BAD_VALUE; - return XP_NULL; - } - } - else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_REAL) { - if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_INT) { - res = XP_LSP_RVALUE(p1) > XP_LSP_IVALUE(p2); - } - else if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_REAL) { - res = XP_LSP_RVALUE(p1) > XP_LSP_RVALUE(p2); - } - else { - lsp->errnum = XP_LSP_ERR_BAD_VALUE; - return XP_NULL; - } - } - else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_SYMBOL) { - if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_SYMBOL) { - res = xp_lsp_comp_symbol2 ( - p1, XP_LSP_SYMVALUE(p2), XP_LSP_SYMLEN(p2)) > 0; - } - else { - lsp->errnum = XP_LSP_ERR_BAD_VALUE; - return XP_NULL; - } - } - else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_STRING) { - if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_STRING) { - res = xp_lsp_comp_string2 ( - p1, XP_LSP_STRVALUE(p2), XP_LSP_STRLEN(p2)) > 0; - } - else { - lsp->errnum = XP_LSP_ERR_BAD_VALUE; - return XP_NULL; - } - } - else { - lsp->errnum = XP_LSP_ERR_BAD_VALUE; - return XP_NULL; - } - - return (res)? lsp->mem->t: lsp->mem->nil; -} - -xp_lsp_obj_t* xp_lsp_prim_lt (xp_lsp_t* lsp, xp_lsp_obj_t* args) -{ - xp_lsp_obj_t* p1, * p2; - int res; - - XP_LSP_PRIM_CHECK_ARG_COUNT (lsp, args, 2, 2); - xp_assert (XP_LSP_TYPE(args) == XP_LSP_OBJ_CONS); - - p1 = xp_lsp_eval (lsp, XP_LSP_CAR(args)); - if (p1 == XP_NULL) return XP_NULL; - // TODO: lock p1.... - - p2 = xp_lsp_eval (lsp, XP_LSP_CAR(XP_LSP_CDR(args))); - if (p2 == XP_NULL) return XP_NULL; - - if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_INT) { - if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_INT) { - res = XP_LSP_IVALUE(p1) < XP_LSP_IVALUE(p2); - } - else if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_REAL) { - res = XP_LSP_IVALUE(p1) < XP_LSP_RVALUE(p2); - } - else { - lsp->errnum = XP_LSP_ERR_BAD_VALUE; - return XP_NULL; - } - } - else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_REAL) { - if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_INT) { - res = XP_LSP_RVALUE(p1) < XP_LSP_IVALUE(p2); - } - else if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_REAL) { - res = XP_LSP_RVALUE(p1) < XP_LSP_RVALUE(p2); - } - else { - lsp->errnum = XP_LSP_ERR_BAD_VALUE; - return XP_NULL; - } - } - else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_SYMBOL) { - if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_SYMBOL) { - res = xp_lsp_comp_symbol2 ( - p1, XP_LSP_SYMVALUE(p2), XP_LSP_SYMLEN(p2)) < 0; - } - else { - lsp->errnum = XP_LSP_ERR_BAD_VALUE; - return XP_NULL; - } - } - else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_STRING) { - if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_STRING) { - res = xp_lsp_comp_string2 ( - p1, XP_LSP_STRVALUE(p2), XP_LSP_STRLEN(p2)) < 0; - } - else { - lsp->errnum = XP_LSP_ERR_BAD_VALUE; - return XP_NULL; - } - } - else { - lsp->errnum = XP_LSP_ERR_BAD_VALUE; - return XP_NULL; - } - - return (res)? lsp->mem->t: lsp->mem->nil; -} diff --git a/ase/lsp/prim.h b/ase/lsp/prim.h index 6a091fd8..fdbd5fac 100644 --- a/ase/lsp/prim.h +++ b/ase/lsp/prim.h @@ -1,5 +1,5 @@ /* - * $Id: prim.h,v 1.3 2005-09-20 11:19:15 bacon Exp $ + * $Id: prim.h,v 1.4 2005-09-20 12:06:51 bacon Exp $ */ #ifndef _XP_LSP_PRIM_H_ @@ -32,11 +32,21 @@ xp_lsp_obj_t* xp_lsp_prim_demac (xp_lsp_t* lsp, xp_lsp_obj_t* args); xp_lsp_obj_t* xp_lsp_prim_let (xp_lsp_t* lsp, xp_lsp_obj_t* args); xp_lsp_obj_t* xp_lsp_prim_letx (xp_lsp_t* lsp, xp_lsp_obj_t* args); +/*--------------------- + prim_compar.c + ---------------------*/ +xp_lsp_obj_t* xp_lsp_prim_eq (xp_lsp_t* lsp, xp_lsp_obj_t* args); xp_lsp_obj_t* xp_lsp_prim_gt (xp_lsp_t* lsp, xp_lsp_obj_t* args); xp_lsp_obj_t* xp_lsp_prim_lt (xp_lsp_t* lsp, xp_lsp_obj_t* args); -xp_lsp_obj_t* xp_lsp_prim_plus (xp_lsp_t* lsp, xp_lsp_obj_t* args); -xp_lsp_obj_t* xp_lsp_prim_minus (xp_lsp_t* lsp, xp_lsp_obj_t* args); +/*--------------------- + prim_math.c + ---------------------*/ +xp_lsp_obj_t* xp_lsp_prim_plus (xp_lsp_t* lsp, xp_lsp_obj_t* args); +xp_lsp_obj_t* xp_lsp_prim_minus (xp_lsp_t* lsp, xp_lsp_obj_t* args); +xp_lsp_obj_t* xp_lsp_prim_multiply (xp_lsp_t* lsp, xp_lsp_obj_t* args); +xp_lsp_obj_t* xp_lsp_prim_divide (xp_lsp_t* lsp, xp_lsp_obj_t* args); +xp_lsp_obj_t* xp_lsp_prim_modulus (xp_lsp_t* lsp, xp_lsp_obj_t* args); #ifdef __cplusplus } diff --git a/ase/lsp/prim_compar.c b/ase/lsp/prim_compar.c new file mode 100644 index 00000000..b76dfbbe --- /dev/null +++ b/ase/lsp/prim_compar.c @@ -0,0 +1,207 @@ +/* + * $Id: prim_compar.c,v 1.1 2005-09-20 12:06:51 bacon Exp $ + */ + +#include +#include + +xp_lsp_obj_t* xp_lsp_prim_eq (xp_lsp_t* lsp, xp_lsp_obj_t* args) +{ + xp_lsp_obj_t* p1, * p2; + int res; + + XP_LSP_PRIM_CHECK_ARG_COUNT (lsp, args, 2, 2); + xp_assert (XP_LSP_TYPE(args) == XP_LSP_OBJ_CONS); + + p1 = xp_lsp_eval (lsp, XP_LSP_CAR(args)); + if (p1 == XP_NULL) return XP_NULL; + // TODO: lock p1.... + + p2 = xp_lsp_eval (lsp, XP_LSP_CAR(XP_LSP_CDR(args))); + if (p2 == XP_NULL) return XP_NULL; + + if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_INT) { + if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_INT) { + res = XP_LSP_IVALUE(p1) == XP_LSP_IVALUE(p2); + } + else if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_REAL) { + res = XP_LSP_IVALUE(p1) == XP_LSP_RVALUE(p2); + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + } + else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_REAL) { + if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_INT) { + res = XP_LSP_RVALUE(p1) == XP_LSP_IVALUE(p2); + } + else if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_REAL) { + res = XP_LSP_RVALUE(p1) == XP_LSP_RVALUE(p2); + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + } + else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_SYMBOL) { + if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_SYMBOL) { + res = xp_lsp_comp_symbol2 ( + p1, XP_LSP_SYMVALUE(p2), XP_LSP_SYMLEN(p2)) == 0; + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + } + else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_STRING) { + if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_STRING) { + res = xp_lsp_comp_string2 ( + p1, XP_LSP_STRVALUE(p2), XP_LSP_STRLEN(p2)) == 0; + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + + return (res)? lsp->mem->t: lsp->mem->nil; +} + +xp_lsp_obj_t* xp_lsp_prim_gt (xp_lsp_t* lsp, xp_lsp_obj_t* args) +{ + xp_lsp_obj_t* p1, * p2; + int res; + + XP_LSP_PRIM_CHECK_ARG_COUNT (lsp, args, 2, 2); + xp_assert (XP_LSP_TYPE(args) == XP_LSP_OBJ_CONS); + + p1 = xp_lsp_eval (lsp, XP_LSP_CAR(args)); + if (p1 == XP_NULL) return XP_NULL; + // TODO: lock p1.... + + p2 = xp_lsp_eval (lsp, XP_LSP_CAR(XP_LSP_CDR(args))); + if (p2 == XP_NULL) return XP_NULL; + + if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_INT) { + if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_INT) { + res = XP_LSP_IVALUE(p1) > XP_LSP_IVALUE(p2); + } + else if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_REAL) { + res = XP_LSP_IVALUE(p1) > XP_LSP_RVALUE(p2); + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + } + else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_REAL) { + if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_INT) { + res = XP_LSP_RVALUE(p1) > XP_LSP_IVALUE(p2); + } + else if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_REAL) { + res = XP_LSP_RVALUE(p1) > XP_LSP_RVALUE(p2); + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + } + else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_SYMBOL) { + if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_SYMBOL) { + res = xp_lsp_comp_symbol2 ( + p1, XP_LSP_SYMVALUE(p2), XP_LSP_SYMLEN(p2)) > 0; + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + } + else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_STRING) { + if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_STRING) { + res = xp_lsp_comp_string2 ( + p1, XP_LSP_STRVALUE(p2), XP_LSP_STRLEN(p2)) > 0; + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + + return (res)? lsp->mem->t: lsp->mem->nil; +} + +xp_lsp_obj_t* xp_lsp_prim_lt (xp_lsp_t* lsp, xp_lsp_obj_t* args) +{ + xp_lsp_obj_t* p1, * p2; + int res; + + XP_LSP_PRIM_CHECK_ARG_COUNT (lsp, args, 2, 2); + xp_assert (XP_LSP_TYPE(args) == XP_LSP_OBJ_CONS); + + p1 = xp_lsp_eval (lsp, XP_LSP_CAR(args)); + if (p1 == XP_NULL) return XP_NULL; + // TODO: lock p1.... + + p2 = xp_lsp_eval (lsp, XP_LSP_CAR(XP_LSP_CDR(args))); + if (p2 == XP_NULL) return XP_NULL; + + if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_INT) { + if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_INT) { + res = XP_LSP_IVALUE(p1) < XP_LSP_IVALUE(p2); + } + else if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_REAL) { + res = XP_LSP_IVALUE(p1) < XP_LSP_RVALUE(p2); + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + } + else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_REAL) { + if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_INT) { + res = XP_LSP_RVALUE(p1) < XP_LSP_IVALUE(p2); + } + else if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_REAL) { + res = XP_LSP_RVALUE(p1) < XP_LSP_RVALUE(p2); + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + } + else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_SYMBOL) { + if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_SYMBOL) { + res = xp_lsp_comp_symbol2 ( + p1, XP_LSP_SYMVALUE(p2), XP_LSP_SYMLEN(p2)) < 0; + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + } + else if (XP_LSP_TYPE(p1) == XP_LSP_OBJ_STRING) { + if (XP_LSP_TYPE(p2) == XP_LSP_OBJ_STRING) { + res = xp_lsp_comp_string2 ( + p1, XP_LSP_STRVALUE(p2), XP_LSP_STRLEN(p2)) < 0; + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + + return (res)? lsp->mem->t: lsp->mem->nil; +} diff --git a/ase/lsp/prim_math.c b/ase/lsp/prim_math.c index 94a0e44c..f9733ae6 100644 --- a/ase/lsp/prim_math.c +++ b/ase/lsp/prim_math.c @@ -1,5 +1,5 @@ /* - * $Id: prim_math.c,v 1.3 2005-09-20 11:19:15 bacon Exp $ + * $Id: prim_math.c,v 1.4 2005-09-20 12:06:51 bacon Exp $ */ #include @@ -9,38 +9,53 @@ xp_lsp_obj_t* xp_lsp_prim_plus (xp_lsp_t* lsp, xp_lsp_obj_t* args) { xp_lsp_obj_t* body, * tmp; xp_lsp_int_t ivalue = 0; - xp_lsp_real_t rvalue = 0.; + xp_lsp_real_t rvalue = .0; xp_bool_t realnum = xp_false; XP_LSP_PRIM_CHECK_ARG_COUNT (lsp, args, 1, XP_LSP_PRIM_MAX_ARG_COUNT); xp_assert (XP_LSP_TYPE(args) == XP_LSP_OBJ_CONS); body = args; - //while (body != lsp->mem->nil) { while (XP_LSP_TYPE(body) == XP_LSP_OBJ_CONS) { tmp = xp_lsp_eval (lsp, XP_LSP_CAR(body)); - if (tmp == XP_NULL) return XP_NULL; + if (tmp == XP_NULL) { + /*lsp->errnum = XP_LSP_ERR_BAD_VALUE; */ + return XP_NULL; + } if (XP_LSP_TYPE(tmp) == XP_LSP_OBJ_INT) { - if (!realnum) - ivalue = ivalue + XP_LSP_IVALUE(tmp); - else - rvalue = rvalue + XP_LSP_IVALUE(tmp); + if (body == args) { + xp_assert (realnum == xp_false); + ivalue = XP_LSP_IVALUE(tmp); + } + else { + if (!realnum) + ivalue = ivalue + XP_LSP_IVALUE(tmp); + else + rvalue = rvalue + XP_LSP_IVALUE(tmp); + } } else if (XP_LSP_TYPE(tmp) == XP_LSP_OBJ_REAL) { - if (!realnum) { + if (body == args) { + xp_assert (realnum == xp_false); realnum = xp_true; - rvalue = (xp_lsp_real_t)ivalue; + rvalue = XP_LSP_RVALUE(tmp); + } + else { + if (!realnum) { + realnum = xp_true; + rvalue = (xp_lsp_real_t)ivalue; + } + rvalue = rvalue + XP_LSP_RVALUE(tmp); } - - rvalue = rvalue + XP_LSP_RVALUE(tmp); } else { lsp->errnum = XP_LSP_ERR_BAD_VALUE; return XP_NULL; } + body = XP_LSP_CDR(body); } @@ -61,7 +76,7 @@ xp_lsp_obj_t* xp_lsp_prim_minus (xp_lsp_t* lsp, xp_lsp_obj_t* args) { xp_lsp_obj_t* body, * tmp; xp_lsp_int_t ivalue = 0; - xp_lsp_real_t rvalue = 0.; + xp_lsp_real_t rvalue = .0; xp_bool_t realnum = xp_false; XP_LSP_PRIM_CHECK_ARG_COUNT (lsp, args, 1, XP_LSP_PRIM_MAX_ARG_COUNT); @@ -122,3 +137,182 @@ xp_lsp_obj_t* xp_lsp_prim_minus (xp_lsp_t* lsp, xp_lsp_obj_t* args) return tmp; } +xp_lsp_obj_t* xp_lsp_prim_multiply (xp_lsp_t* lsp, xp_lsp_obj_t* args) +{ + xp_lsp_obj_t* body, * tmp; + xp_lsp_int_t ivalue = 0; + xp_lsp_real_t rvalue = .0; + xp_bool_t realnum = xp_false; + + XP_LSP_PRIM_CHECK_ARG_COUNT (lsp, args, 1, XP_LSP_PRIM_MAX_ARG_COUNT); + xp_assert (XP_LSP_TYPE(args) == XP_LSP_OBJ_CONS); + + body = args; + //while (body != lsp->mem->nil) { + while (XP_LSP_TYPE(body) == XP_LSP_OBJ_CONS) { + tmp = xp_lsp_eval (lsp, XP_LSP_CAR(body)); + if (tmp == XP_NULL) return XP_NULL; + + + if (XP_LSP_TYPE(tmp) == XP_LSP_OBJ_INT) { + if (body == args) { + xp_assert (realnum == xp_false); + ivalue = XP_LSP_IVALUE(tmp); + } + else { + if (!realnum) + ivalue = ivalue * XP_LSP_IVALUE(tmp); + else + rvalue = rvalue * XP_LSP_IVALUE(tmp); + } + } + else if (XP_LSP_TYPE(tmp) == XP_LSP_OBJ_REAL) { + if (body == args) { + xp_assert (realnum == xp_false); + realnum = xp_true; + rvalue = XP_LSP_RVALUE(tmp); + } + else { + if (!realnum) { + realnum = xp_true; + rvalue = (xp_lsp_real_t)ivalue; + } + rvalue = rvalue * XP_LSP_RVALUE(tmp); + } + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + + + body = XP_LSP_CDR(body); + } + + xp_assert (body == lsp->mem->nil); + + tmp = (realnum)? + xp_lsp_make_real (lsp->mem, rvalue): + xp_lsp_make_int (lsp->mem, ivalue); + if (tmp == XP_NULL) { + lsp->errnum = XP_LSP_ERR_MEM; + return XP_NULL; + } + + return tmp; +} + +xp_lsp_obj_t* xp_lsp_prim_divide (xp_lsp_t* lsp, xp_lsp_obj_t* args) +{ + xp_lsp_obj_t* body, * tmp; + xp_lsp_int_t ivalue = 0; + xp_lsp_real_t rvalue = .0; + xp_bool_t realnum = xp_false; + + XP_LSP_PRIM_CHECK_ARG_COUNT (lsp, args, 1, XP_LSP_PRIM_MAX_ARG_COUNT); + xp_assert (XP_LSP_TYPE(args) == XP_LSP_OBJ_CONS); + + body = args; + //while (body != lsp->mem->nil) { + while (XP_LSP_TYPE(body) == XP_LSP_OBJ_CONS) { + tmp = xp_lsp_eval (lsp, XP_LSP_CAR(body)); + if (tmp == XP_NULL) return XP_NULL; + + + if (XP_LSP_TYPE(tmp) == XP_LSP_OBJ_INT) { + if (body == args) { + xp_assert (realnum == xp_false); + ivalue = XP_LSP_IVALUE(tmp); + } + else { + if (!realnum) + ivalue = ivalue / XP_LSP_IVALUE(tmp); + else + rvalue = rvalue / XP_LSP_IVALUE(tmp); + } + } + else if (XP_LSP_TYPE(tmp) == XP_LSP_OBJ_REAL) { + if (body == args) { + xp_assert (realnum == xp_false); + realnum = xp_true; + rvalue = XP_LSP_RVALUE(tmp); + } + else { + if (!realnum) { + realnum = xp_true; + rvalue = (xp_lsp_real_t)ivalue; + } + rvalue = rvalue / XP_LSP_RVALUE(tmp); + } + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + + + body = XP_LSP_CDR(body); + } + + xp_assert (body == lsp->mem->nil); + + tmp = (realnum)? + xp_lsp_make_real (lsp->mem, rvalue): + xp_lsp_make_int (lsp->mem, ivalue); + if (tmp == XP_NULL) { + lsp->errnum = XP_LSP_ERR_MEM; + return XP_NULL; + } + + return tmp; +} + +xp_lsp_obj_t* xp_lsp_prim_modulus (xp_lsp_t* lsp, xp_lsp_obj_t* args) +{ + xp_lsp_obj_t* body, * tmp; + xp_lsp_int_t ivalue = 0; + + XP_LSP_PRIM_CHECK_ARG_COUNT (lsp, args, 1, XP_LSP_PRIM_MAX_ARG_COUNT); + xp_assert (XP_LSP_TYPE(args) == XP_LSP_OBJ_CONS); + + body = args; + //while (body != lsp->mem->nil) { + while (XP_LSP_TYPE(body) == XP_LSP_OBJ_CONS) { + tmp = xp_lsp_eval (lsp, XP_LSP_CAR(body)); + if (tmp == XP_NULL) return XP_NULL; + + if (XP_LSP_TYPE(tmp) == XP_LSP_OBJ_INT) { + if (body == args) { + ivalue = XP_LSP_IVALUE(tmp); + } + else { + ivalue = ivalue % XP_LSP_IVALUE(tmp); + } + } + else if (XP_LSP_TYPE(tmp) == XP_LSP_OBJ_REAL) { + if (body == args) { + ivalue = (xp_lsp_int_t)XP_LSP_RVALUE(tmp); + } + else { + ivalue = ivalue % (xp_lsp_int_t)XP_LSP_RVALUE(tmp); + } + } + else { + lsp->errnum = XP_LSP_ERR_BAD_VALUE; + return XP_NULL; + } + + + body = XP_LSP_CDR(body); + } + + xp_assert (body == lsp->mem->nil); + + tmp = xp_lsp_make_int (lsp->mem, ivalue); + if (tmp == XP_NULL) { + lsp->errnum = XP_LSP_ERR_MEM; + return XP_NULL; + } + + return tmp; +} diff --git a/ase/test/lsp/t2.lsp b/ase/test/lsp/t2.lsp index 5a39a4e7..95e76133 100644 --- a/ase/test/lsp/t2.lsp +++ b/ase/test/lsp/t2.lsp @@ -1,4 +1,5 @@ -(setq x (lambda (x) (+ x 20 30 40))) +;(setq x (lambda (x) (+ x 20 30 40))) +(defun x(x) (+ x 20 30 40)) (x 100) (x 100) (x 100) diff --git a/ase/test/lsp/t3.lsp b/ase/test/lsp/t3.lsp new file mode 100644 index 00000000..0a28bf6a --- /dev/null +++ b/ase/test/lsp/t3.lsp @@ -0,0 +1,8 @@ +; test while + +(setq x 10) +(setq y 10) +(while (< x 100) (setq y (+ x y)) (setq x (+ x 1))) +x +y + diff --git a/ase/test/lsp/t4.lsp b/ase/test/lsp/t4.lsp new file mode 100644 index 00000000..ac40a254 --- /dev/null +++ b/ase/test/lsp/t4.lsp @@ -0,0 +1,7 @@ +;Compute the factorial of N. +(defun factorial (N) + (if (= N 1) + 1 + (* N (factorial (- N 1))))) + +(factorial 10) diff --git a/ase/test/lsp/t5.lsp b/ase/test/lsp/t5.lsp new file mode 100644 index 00000000..01f2c56b --- /dev/null +++ b/ase/test/lsp/t5.lsp @@ -0,0 +1,7 @@ +; Compute the N'th Fibonacci number. +(defun fibonacci (N) + (if (or (zerop N) (= N 1)) + 1 + (+ (fibonacci (- N 1)) (fibonacci (- N 2))))) + +(fibonacci 5)