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
|
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
2
lval.h
|
@ -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
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 "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) {
|
||||||
|
|
Reference in a new issue