/* * $Id: prim_math.c,v 1.3 2005-09-20 11:19:15 bacon Exp $ */ #include #include 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_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 (!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) { 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_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_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; }