From d4e84782ef662588571e0b90beeda5be5c49e414 Mon Sep 17 00:00:00 2001 From: Sam Stevens Date: Thu, 29 May 2014 15:28:07 +0100 Subject: [PATCH] Added equality comparisons == and != --- functions.c | 32 ++++++++++++++++++++++------ functions.h | 8 +++++-- lang.h | 2 ++ lenv.c | 1 - lval.c | 40 +++++++++++++++++++++++++++++++++++ lval.h | 3 +++ main.h | 13 ++++++++---- nbproject/Makefile-Release.mk | 16 +++++++------- nbproject/configurations.xml | 13 +++++++++++- 9 files changed, 106 insertions(+), 22 deletions(-) diff --git a/functions.c b/functions.c index 44560f1..20614ed 100644 --- a/functions.c +++ b/functions.c @@ -27,6 +27,8 @@ void lenv_add_builtin_funcs(lenv* env) { lenv_add_builtin(env, "<", builtin_comp_lt); lenv_add_builtin(env, ">=", builtin_comp_ge); lenv_add_builtin(env, "<=", builtin_comp_le); + lenv_add_builtin(env, "==", builtin_comp_eq); + lenv_add_builtin(env, "!=", builtin_comp_neq); //List/Util functions lenv_add_builtin(env, "list", builtin_list); @@ -57,6 +59,8 @@ char* builtin_op_strname(BUILTIN_OP_TYPE op) { case BUILTIN_COMP_LT: return "<"; case BUILTIN_COMP_GE: return ">="; case BUILTIN_COMP_LE: return "<="; + case BUILTIN_COMP_EQ: return "=="; + case BUILTIN_COMP_NEQ: return "!="; default: return "UNKNOWN"; } } @@ -74,7 +78,7 @@ lval* builtin_op(lenv* env, lval* val, BUILTIN_OP_TYPE op) { if (op == BUILTIN_OP_SUB && val->cell_count == 0) { x->data.num = -x->data.num; - } + } while(val->cell_count > 0) { //Get next to process @@ -128,7 +132,7 @@ lval* builtin_pow(lenv* env, lval* val){ //End Math Functions //Start Comparison Functions -lval* builtin_comp(lenv* env, lval* val, BUILTIN_OP_TYPE op) { +lval* builtin_comp_num(lenv* env, lval* val, BUILTIN_OP_TYPE op) { char* opName = builtin_op_strname(op); LASSERT_ARG_COUNT(opName, val, val, 2); LASSERT_TYPE(opName, val, val->cell_list[0], LVAL_NUM); @@ -149,16 +153,32 @@ lval* builtin_comp(lenv* env, lval* val, BUILTIN_OP_TYPE op) { return lval_num(r); } lval* builtin_comp_gt(lenv* env, lval* val) { - return builtin_comp(env, val, BUILTIN_COMP_GT); + return builtin_comp_num(env, val, BUILTIN_COMP_GT); } lval* builtin_comp_lt(lenv* env, lval* val) { - return builtin_comp(env, val, BUILTIN_COMP_LT); + return builtin_comp_num(env, val, BUILTIN_COMP_LT); } lval* builtin_comp_ge(lenv* env, lval* val) { - return builtin_comp(env, val, BUILTIN_COMP_GE); + return builtin_comp_num(env, val, BUILTIN_COMP_GE); } lval* builtin_comp_le(lenv* env, lval* val) { - return builtin_comp(env, val, BUILTIN_COMP_LE); + return builtin_comp_num(env, val, BUILTIN_COMP_LE); +} + +lval* builtin_comp_value(lenv* env, lval* val, BUILTIN_OP_TYPE op) { + LASSERT_ARG_COUNT(builtin_op_strname(op), val, val, 2); + BOOL result = FALSE; + result = lval_equal(val->cell_list[0], val->cell_list[1]); + if (op == BUILTIN_COMP_NEQ) { + result = !result; + } + return lval_num((int)result); +} +lval* builtin_comp_eq(lenv* env, lval* val) { + return builtin_comp_value(env, val, BUILTIN_COMP_EQ); +} +lval* builtin_comp_neq(lenv* env, lval* val) { + return builtin_comp_value(env, val, BUILTIN_COMP_NEQ); } //End Comparison Functions diff --git a/functions.h b/functions.h index d91aac6..a45cac2 100644 --- a/functions.h +++ b/functions.h @@ -18,7 +18,8 @@ extern "C" { enum BUILTIN_OP_TYPE { BUILTIN_OP_ADD, BUILTIN_OP_SUB, BUILTIN_OP_DIV, BUILTIN_OP_MUL, BUILTIN_OP_POW, - BUILTIN_COMP_GT, BUILTIN_COMP_LT, BUILTIN_COMP_GE, BUILTIN_COMP_LE + BUILTIN_COMP_GT, BUILTIN_COMP_LT, BUILTIN_COMP_GE, BUILTIN_COMP_LE, + BUILTIN_COMP_EQ, BUILTIN_COMP_NEQ }; char* builtin_op_strname(BUILTIN_OP_TYPE op); @@ -36,11 +37,14 @@ extern "C" { lval* builtin_pow(lenv* env, lval* val); //Comparison Functions - lval* builtin_comp(lenv* env, lval* val, BUILTIN_OP_TYPE op); + lval* builtin_comp_num(lenv* env, lval* val, BUILTIN_OP_TYPE op); lval* builtin_comp_gt(lenv* env, lval* val); lval* builtin_comp_lt(lenv* env, lval* val); lval* builtin_comp_ge(lenv* env, lval* val); lval* builtin_comp_le(lenv* env, lval* val); + lval* builtin_comp_value(lenv* env, lval* val, BUILTIN_OP_TYPE op); + lval* builtin_comp_eq(lenv* env, lval* val); + lval* builtin_comp_neq(lenv* env, lval* val); //List/Util functions lval* builtin_list(lenv* env, lval* val); diff --git a/lang.h b/lang.h index 4939aa0..f0e9691 100644 --- a/lang.h +++ b/lang.h @@ -34,6 +34,8 @@ extern "C" { LASSERT(val, subject->cell_count >= expectedNum, \ LERR_SYNTAX, "%s Expected %ld or more arguments got %ld", name, expectedNum, subject->cell_count ) + + mpc_ast_t* tokenize(char *input); lval* parse(mpc_ast_t *t); lval* eval_builtin_op(lval* val, char* op); diff --git a/lenv.c b/lenv.c index e84e243..73c0af2 100644 --- a/lenv.c +++ b/lenv.c @@ -1,5 +1,4 @@ #include -#include #include "lang.h" #include "util.h" diff --git a/lval.c b/lval.c index 1c2dabd..872e72d 100644 --- a/lval.c +++ b/lval.c @@ -1,4 +1,5 @@ #include +#include #include "lang.h" #include "util.h" @@ -135,6 +136,45 @@ lval* lval_call(lenv* env, lval* function, lval* args) { return eval(func->env, lval_add(lval_s_expr(), lval_copy(func->body))); } +BOOL lval_equal(lval* a, lval* b) { + if (a->type != b->type) { + return FALSE; + } + + switch(a->type) { + case LVAL_ERR: return a->data.err.num == b->data.err.num; + case LVAL_EXIT: return TRUE; + case LVAL_NUM: return fabs(a->data.num - b->data.num) <= DBL_EPSILON; + case LVAL_SYM: return strcmp(a->data.sym, b->data.sym) == 0; + case LVAL_FUNC: + if (a->data.func->builtin != NULL) { + if (b->data.func->builtin != NULL) { + return a->data.func->builtin == a->data.func->builtin; + } else { + return FALSE; + } + } else { + if (b->data.func->builtin == NULL) { + return FALSE; + } else { + return lval_equal(b->data.func->formals, b->data.func->formals) + && lval_equal(b->data.func->body, b->data.func->body); + } + } + case LVAL_Q_EXPR: + case LVAL_S_EXPR: + if (a->cell_count != b->cell_count) { return 0; } + for (int i = 0; i < a->cell_count; i++) { + if (!lval_equal(a->cell_list[i], b->cell_list[i])) { + return FALSE; + } + } + return TRUE; + + default: return FALSE; + } +} + void lval_delete(lval* val) { switch(val->type) { case LVAL_NUM: break; diff --git a/lval.h b/lval.h index ce164ce..bb0614b 100644 --- a/lval.h +++ b/lval.h @@ -19,6 +19,7 @@ typedef struct lval lval; struct lval_func; typedef struct lval_func lval_func; +#include "main.h" #include "lenv.h" enum VAL_TYPE { LVAL_ERR, LVAL_NUM, LVAL_SYM, LVAL_FUNC, LVAL_S_EXPR, LVAL_Q_EXPR, LVAL_EXIT }; @@ -67,7 +68,9 @@ lval* lval_add(lval* val, lval* x); lval* lval_pop(lval* val, int i); lval* lval_take(lval* val, int i); lval* lval_join(lval* a, lval* b); + lval* lval_call(lenv* env, lval* function, lval* args); +BOOL lval_equal(lval* a, lval* b); void lval_delete(lval* val); lval* lval_copy(lval* current); diff --git a/main.h b/main.h index c9494d5..ffa64d8 100644 --- a/main.h +++ b/main.h @@ -13,12 +13,17 @@ extern "C" { #endif #define VERSION "0.1" + + typedef unsigned char BOOL; + +#define TRUE 1 +#define FALSE 0 -int main(int argc, char** argv); + int main(int argc, char** argv); -void lval_expr_print(lval* val, char* open, char* close); -void lval_print(lval* val); -void lval_println(lval* val); + void lval_expr_print(lval* val, char* open, char* close); + void lval_print(lval* val); + void lval_println(lval* val); #ifdef __cplusplus } diff --git a/nbproject/Makefile-Release.mk b/nbproject/Makefile-Release.mk index e742379..fb11923 100644 --- a/nbproject/Makefile-Release.mk +++ b/nbproject/Makefile-Release.mk @@ -58,7 +58,7 @@ FFLAGS= ASFLAGS= # Link Libraries and Options -LDLIBSOPTIONS= +LDLIBSOPTIONS=-lm `pkg-config --libs libedit` # Build Targets .build-conf: ${BUILD_SUBPROJECTS} @@ -71,37 +71,37 @@ ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/klisp: ${OBJECTFILES} ${OBJECTDIR}/functions.o: functions.c ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/functions.o functions.c + $(COMPILE.c) -O3 -w -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/functions.o functions.c ${OBJECTDIR}/lang.o: lang.c ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lang.o lang.c + $(COMPILE.c) -O3 -w -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lang.o lang.c ${OBJECTDIR}/lenv.o: lenv.c ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lenv.o lenv.c + $(COMPILE.c) -O3 -w -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lenv.o lenv.c ${OBJECTDIR}/lib/mpc/mpc.o: lib/mpc/mpc.c ${MKDIR} -p ${OBJECTDIR}/lib/mpc ${RM} "$@.d" - $(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lib/mpc/mpc.o lib/mpc/mpc.c + $(COMPILE.c) -O3 -w -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lib/mpc/mpc.o lib/mpc/mpc.c ${OBJECTDIR}/lval.o: lval.c ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lval.o lval.c + $(COMPILE.c) -O3 -w -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lval.o lval.c ${OBJECTDIR}/main.o: main.c ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.c + $(COMPILE.c) -O3 -w -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.c ${OBJECTDIR}/util.o: util.c ${MKDIR} -p ${OBJECTDIR} ${RM} "$@.d" - $(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/util.o util.c + $(COMPILE.c) -O3 -w -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/util.o util.c # Subprojects .build-subprojects: diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index ceee75e..2b91b0e 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -104,7 +104,12 @@ - 5 + 6 + 3 + + lib/mpc + + 0 5 @@ -115,6 +120,12 @@ 5 + + + Mathematics + `pkg-config --libs libedit` + +