Added conditionals != == < > and variants
This commit is contained in:
parent
f592d69179
commit
8f26cd847e
5 changed files with 145 additions and 2 deletions
6
Makefile
6
Makefile
|
@ -1,5 +1,7 @@
|
|||
run: prompt.c 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
|
||||
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 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
|
||||
cc -std=c99 -Wall -c lval/operations.c -o loperations.o
|
||||
lnumbers.o: lval/numbers.c lval/numbers.h
|
||||
|
|
2
lval.h
2
lval.h
|
@ -16,5 +16,7 @@
|
|||
#include "lval/io.h"
|
||||
// Add environments, variables, and functions
|
||||
#include "lval/environment.h"
|
||||
// Add conditional statements
|
||||
#include "lval/conditionals.h"
|
||||
|
||||
#endif
|
||||
|
|
110
lval/conditionals.c
Normal file
110
lval/conditionals.c
Normal 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
19
lval/conditionals.h
Normal 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
|
|
@ -3,6 +3,7 @@
|
|||
#include "error.h"
|
||||
#include "expressions.h"
|
||||
#include "operations.h"
|
||||
#include "conditionals.h"
|
||||
|
||||
lenv* lenv_new(void) {
|
||||
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, "ls", builtin_ls);
|
||||
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) {
|
||||
|
|
Reference in a new issue