mirror of
https://github.com/samsonjs/lake.git
synced 2026-03-25 08:55:49 +00:00
define math primitives + - * and /
This commit is contained in:
parent
d0c17ee2cc
commit
619a2ed04e
4 changed files with 108 additions and 10 deletions
5
int.c
5
int.c
|
|
@ -40,11 +40,6 @@ LakeInt *int_from_c(int n)
|
|||
return i;
|
||||
}
|
||||
|
||||
int int_val(LakeInt *i)
|
||||
{
|
||||
return i->val;
|
||||
}
|
||||
|
||||
LakeInt *int_cmp(LakeInt *a, LakeInt *b)
|
||||
{
|
||||
int aN = a->val, bN = b->val;
|
||||
|
|
|
|||
1
int.h
1
int.h
|
|
@ -15,7 +15,6 @@
|
|||
LakeInt *int_make(void);
|
||||
LakeInt *int_copy(LakeInt *i);
|
||||
LakeInt *int_from_c(int n);
|
||||
int int_val(LakeInt *i);
|
||||
LakeInt *int_cmp(LakeInt *a, LakeInt *b);
|
||||
LakeBool *int_eq(LakeInt *a, LakeInt *b);
|
||||
LakeStr *int_to_str(LakeInt *i);
|
||||
|
|
|
|||
110
lake.c
110
lake.c
|
|
@ -48,14 +48,116 @@ static LakeVal *prim_not(LakeList *args)
|
|||
return VAL(not);
|
||||
}
|
||||
|
||||
static LakeVal *prim_add(LakeList *args)
|
||||
{
|
||||
int result = 0;
|
||||
size_t n = LIST_N(args);
|
||||
size_t i;
|
||||
for (i = 0; i < n; ++i) {
|
||||
LakeVal *v = LIST_VAL(args, i);
|
||||
if (!IS(TYPE_INT, v)) {
|
||||
ERR("argument %zu is not an integer: %s", i, repr(v));
|
||||
return NULL;
|
||||
}
|
||||
result += INT_VAL(INT(v));
|
||||
}
|
||||
return VAL(int_from_c(result));
|
||||
}
|
||||
|
||||
static LakeVal *prim_sub(LakeList *args)
|
||||
{
|
||||
size_t n = LIST_N(args);
|
||||
|
||||
if (n < 1) {
|
||||
ERR("- requires at least one argument");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
size_t i;
|
||||
for (i = 0; i < n; ++i) {
|
||||
LakeVal *v = LIST_VAL(args, i);
|
||||
if (!IS(TYPE_INT, v)) {
|
||||
ERR("argument %zu is not an integer: %s", i, repr(v));
|
||||
return NULL;
|
||||
}
|
||||
result -= INT_VAL(INT(v));
|
||||
}
|
||||
return VAL(int_from_c(result));
|
||||
}
|
||||
|
||||
static LakeVal *prim_mul(LakeList *args)
|
||||
{
|
||||
int result = 1;
|
||||
size_t n = LIST_N(args);
|
||||
size_t i;
|
||||
for (i = 0; i < n; ++i) {
|
||||
LakeVal *v = LIST_VAL(args, i);
|
||||
if (!IS(TYPE_INT, v)) {
|
||||
ERR("argument %zu is not an integer: %s", i, repr(v));
|
||||
return NULL;
|
||||
}
|
||||
result *= INT_VAL(INT(v));
|
||||
}
|
||||
return VAL(int_from_c(result));
|
||||
}
|
||||
|
||||
#define DIVIDE_BY_ZERO() ERR("divide by zero")
|
||||
|
||||
static LakeVal *prim_div(LakeList *args)
|
||||
{
|
||||
size_t n = LIST_N(args);
|
||||
|
||||
if (n < 1) {
|
||||
ERR("/ requires at least one argument");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LakeVal *v = LIST_VAL(args, 0);
|
||||
if (!IS(TYPE_INT, v)) {
|
||||
ERR("argument 0 is not an integer: %s", repr(v));
|
||||
return NULL;
|
||||
}
|
||||
int result = INT_VAL(INT(v));
|
||||
|
||||
if (n == 1) {
|
||||
if (result == 0) {
|
||||
DIVIDE_BY_ZERO();
|
||||
return NULL;
|
||||
}
|
||||
result = 1 / result;
|
||||
}
|
||||
else {
|
||||
size_t i;
|
||||
for (i = 1; i < n; ++i) {
|
||||
v = LIST_VAL(args, i);
|
||||
if (!IS(TYPE_INT, v)) {
|
||||
ERR("argument %zu is not an integer: %s", i, repr(v));
|
||||
return NULL;
|
||||
}
|
||||
int val = INT_VAL(INT(v));
|
||||
if (val == 0) {
|
||||
DIVIDE_BY_ZERO();
|
||||
return NULL;
|
||||
}
|
||||
result /= val;
|
||||
}
|
||||
}
|
||||
return VAL(int_from_c(result));
|
||||
}
|
||||
|
||||
static Env *primitive_bindings(void)
|
||||
{
|
||||
#define DEFINE(name, arity, fn) env_define(env, sym_intern(name), VAL(prim_make(name, arity, fn)))
|
||||
#define DEFINE(name, fn, arity) env_define(env, sym_intern(name), VAL(prim_make(name, arity, fn)))
|
||||
|
||||
Env *env = env_toplevel();
|
||||
DEFINE("null?", 1, prim_nullP);
|
||||
DEFINE("pair?", 1, prim_pairP);
|
||||
DEFINE("not", 1, prim_not);
|
||||
DEFINE("null?", prim_nullP, 1);
|
||||
DEFINE("pair?", prim_pairP, 1);
|
||||
DEFINE("not", prim_not, 1);
|
||||
DEFINE("+", prim_add, ARITY_VARARGS);
|
||||
DEFINE("-", prim_sub, ARITY_VARARGS);
|
||||
DEFINE("*", prim_mul, ARITY_VARARGS);
|
||||
DEFINE("/", prim_div, ARITY_VARARGS);
|
||||
return env;
|
||||
}
|
||||
|
||||
|
|
|
|||
2
lake.h
2
lake.h
|
|
@ -77,6 +77,8 @@ struct lake_int {
|
|||
};
|
||||
typedef struct lake_int LakeInt;
|
||||
|
||||
#define INT_VAL(x) (x->val)
|
||||
|
||||
struct lake_str {
|
||||
LakeVal base;
|
||||
size_t n;
|
||||
|
|
|
|||
Loading…
Reference in a new issue