mirror of
https://github.com/samsonjs/lake.git
synced 2026-04-27 14:57:43 +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;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int int_val(LakeInt *i)
|
|
||||||
{
|
|
||||||
return i->val;
|
|
||||||
}
|
|
||||||
|
|
||||||
LakeInt *int_cmp(LakeInt *a, LakeInt *b)
|
LakeInt *int_cmp(LakeInt *a, LakeInt *b)
|
||||||
{
|
{
|
||||||
int aN = a->val, bN = b->val;
|
int aN = a->val, bN = b->val;
|
||||||
|
|
|
||||||
1
int.h
1
int.h
|
|
@ -15,7 +15,6 @@
|
||||||
LakeInt *int_make(void);
|
LakeInt *int_make(void);
|
||||||
LakeInt *int_copy(LakeInt *i);
|
LakeInt *int_copy(LakeInt *i);
|
||||||
LakeInt *int_from_c(int n);
|
LakeInt *int_from_c(int n);
|
||||||
int int_val(LakeInt *i);
|
|
||||||
LakeInt *int_cmp(LakeInt *a, LakeInt *b);
|
LakeInt *int_cmp(LakeInt *a, LakeInt *b);
|
||||||
LakeBool *int_eq(LakeInt *a, LakeInt *b);
|
LakeBool *int_eq(LakeInt *a, LakeInt *b);
|
||||||
LakeStr *int_to_str(LakeInt *i);
|
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);
|
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)
|
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();
|
Env *env = env_toplevel();
|
||||||
DEFINE("null?", 1, prim_nullP);
|
DEFINE("null?", prim_nullP, 1);
|
||||||
DEFINE("pair?", 1, prim_pairP);
|
DEFINE("pair?", prim_pairP, 1);
|
||||||
DEFINE("not", 1, prim_not);
|
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;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
2
lake.h
2
lake.h
|
|
@ -77,6 +77,8 @@ struct lake_int {
|
||||||
};
|
};
|
||||||
typedef struct lake_int LakeInt;
|
typedef struct lake_int LakeInt;
|
||||||
|
|
||||||
|
#define INT_VAL(x) (x->val)
|
||||||
|
|
||||||
struct lake_str {
|
struct lake_str {
|
||||||
LakeVal base;
|
LakeVal base;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue