Archived
1
0
Fork 0

Added conditionals != == < > and variants

This commit is contained in:
Brandon Rozek 2018-06-12 18:37:18 -04:00
parent f592d69179
commit 8f26cd847e
5 changed files with 145 additions and 2 deletions

View file

@ -1,5 +1,7 @@
run: prompt.c loperations.o lnumbers.o lexpressions.o lio.o lerror.o lenvironment.o mpc.o run: prompt.c lconditionals.o loperations.o lnumbers.o lexpressions.o lio.o lerror.o lenvironment.o mpc.o
cc -std=c99 -Wall prompt.c loperations.o lnumbers.o lexpressions.o lio.o lerror.o lenvironment.o mpc.o -ledit -lm -o prompt cc -std=c99 -Wall prompt.c lconditionals.o loperations.o lnumbers.o lexpressions.o lio.o lerror.o lenvironment.o mpc.o -ledit -lm -o prompt
lconditionals.o: lval/conditionals.c lval/conditionals.h
cc -std=c99 -Wall -c lval/conditionals.c -o lconditionals.o
loperations.o: lval/operations.c lval/operations.h loperations.o: lval/operations.c lval/operations.h
cc -std=c99 -Wall -c lval/operations.c -o loperations.o cc -std=c99 -Wall -c lval/operations.c -o loperations.o
lnumbers.o: lval/numbers.c lval/numbers.h lnumbers.o: lval/numbers.c lval/numbers.h

2
lval.h
View file

@ -16,5 +16,7 @@
#include "lval/io.h" #include "lval/io.h"
// Add environments, variables, and functions // Add environments, variables, and functions
#include "lval/environment.h" #include "lval/environment.h"
// Add conditional statements
#include "lval/conditionals.h"
#endif #endif

110
lval/conditionals.c Normal file
View file

@ -0,0 +1,110 @@
#include "conditionals.h"
#include "numbers.h"
#include "operations.h"
#include "error.h"
lval* builtin_gt(lenv* e, lval* a) {
return builtin_ord(e, a, ">");
}
lval* builtin_lt(lenv* e, lval* a) {
return builtin_ord(e, a, "<");
}
lval* builtin_ge(lenv* e, lval* a) {
return builtin_ord(e, a, ">=");
}
lval* builtin_le(lenv* e, lval* a) {
return builtin_ord(e, a, "<=");
}
lval* builtin_ord(lenv* e, lval* a, char* op) {
LASSERT_NUM(op, a, 2);
LASSERT(a,
a->cell[0]->type == LVAL_LONG || a->cell[0]->type == LVAL_DOUBLE,
"Function '%s' passed incorrect type for argument %i. " \
"Got %s, Expected %s.", op, 0, ltype_name(a->cell[0]->type), "LONG or DOUBLE")
LASSERT(a,
a->cell[1]->type == LVAL_LONG || a->cell[0]->type == LVAL_DOUBLE,
"Function '%s' passed incorrect type for argument %i. " \
"Got %s, Expected %s.", op, 1, ltype_name(a->cell[0]->type), "LONG or DOUBLE")
int r;
double xVal = (a->cell[0]->type == LVAL_LONG)? a->cell[0]->data.num : a->cell[0]->data.dec;
double yVal = (a->cell[1]->type == LVAL_LONG)? a->cell[1]->data.num : a->cell[1]->data.dec;
if (strcmp(op, ">") == 0) {
r = (xVal > yVal);
}
if (strcmp(op, "<") == 0) {
r = (xVal < yVal);
}
if (strcmp(op, ">=") == 0) {
r = (xVal >= yVal);
}
if (strcmp(op, "<=") == 0) {
r = (xVal <= yVal);
}
lval_del(a);
return lval_long(r);
}
int lval_eq(lval* x, lval* y) {
// Different types are always unequal
if (x->type != y->type) { return 0; }
// Compare base on type
switch (x->type) {
// Compare numerical types
case LVAL_LONG: return (x->data.num == y->data.num);
case LVAL_DOUBLE: return (x->data.dec == y->data.dec);
// Compare string values
case LVAL_ERR: return (strcmp(x->err, y->err) == 0);
case LVAL_SYM: return (strcmp(x->sym, y->sym) == 0);
// If builtin compare, otherwise compare formals and body
case LVAL_FUN:
if (x->builtin || y->builtin) {
return x->builtin == y->builtin;
} else {
return lval_eq(x->formals, y->formals) &&
lval_eq(x->body, y->body);
}
case LVAL_QEXPR:
case LVAL_SEXPR:
if (x->count != y->count) { return 0; }
for (int i = 0; i < x->count; i++) {
// If any element not equal then whole list are not equal
if (!lval_eq(x->cell[i], y->cell[i])) { return 0; }
}
// Otherwise lists must be equal
return 1;
break;
}
return 0;
}
lval* builtin_cmp(lenv* e, lval* a, char* op) {
LASSERT_NUM(op, a, 2);
int r;
if (strcmp(op, "==") == 0) {
r = lval_eq(a->cell[0], a->cell[1]);
}
if (strcmp(op, "!=") == 0) {
r = !lval_eq(a->cell[0], a->cell[1]);
}
lval_del(a);
return lval_long(r);
}
lval* builtin_eq(lenv* e, lval* a) {
return builtin_cmp(e, a, "==");
}
lval* builtin_ne(lenv* e, lval* a) {
return builtin_cmp(e, a, "!=");
}

19
lval/conditionals.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef LVAL_CONDITIONALS
#define LVAL_CONDITIONALS
#include "base.h"
lval* builtin_gt(lenv* e, lval* a);
lval* builtin_lt(lenv* e, lval* a);
lval* builtin_ge(lenv* e, lval* a);
lval* builtin_le(lenv* e, lval* a);
lval* builtin_ord(lenv* e, lval* a, char* op);
int lval_eq(lval* x, lval* y);
lval* builtin_cmp(lenv* e, lval* a, char* op);
lval* builtin_eq(lenv* e, lval* a);
lval* builtin_ne(lenv* e, lval* a);
#endif

View file

@ -3,6 +3,7 @@
#include "error.h" #include "error.h"
#include "expressions.h" #include "expressions.h"
#include "operations.h" #include "operations.h"
#include "conditionals.h"
lenv* lenv_new(void) { lenv* lenv_new(void) {
lenv* e = (lenv*) malloc(sizeof(lenv)); lenv* e = (lenv*) malloc(sizeof(lenv));
@ -126,6 +127,15 @@ void lenv_add_builtins(lenv* e) {
lenv_add_builtin(e, "=", builtin_put); lenv_add_builtin(e, "=", builtin_put);
lenv_add_builtin(e, "ls", builtin_ls); lenv_add_builtin(e, "ls", builtin_ls);
lenv_add_builtin(e, "\\", builtin_lambda); lenv_add_builtin(e, "\\", builtin_lambda);
// Conditional functions
lenv_add_builtin(e, "<", builtin_lt);
lenv_add_builtin(e, ">", builtin_gt);
lenv_add_builtin(e, "<=", builtin_le);
lenv_add_builtin(e, ">=", builtin_ge);
lenv_add_builtin(e, "==", builtin_eq);
lenv_add_builtin(e, "!=", builtin_ne);
} }
lval* builtin_ls(lenv* e, lval* a) { lval* builtin_ls(lenv* e, lval* a) {