]> git.eli173.com Git - klapaucius/commitdiff
added basic arithmetic operations
authorElijah Cohen <cohen@eli173.com>
Sat, 17 Aug 2024 04:42:01 +0000 (04:42 +0000)
committerElijah Cohen <cohen@eli173.com>
Sat, 17 Aug 2024 04:42:01 +0000 (04:42 +0000)
src/builtins/arithmetic.c
src/builtins/arithmetic.h
src/test.c

index 18327c1f272aa5d46cd9a98f3c1494bb23c052af..521ba178a00c5d8781bd9012931b0038106ec283 100644 (file)
@@ -11,7 +11,7 @@
 
 
 Sexpr* a_plus(Sexpr* b, Sexpr* rest, Sexpr* env) {
-       if(ARITH_PLUS_ARGS != u64_get_num_args(b)) {
+       if(ARITH_ADD_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
@@ -25,12 +25,81 @@ Sexpr* a_plus(Sexpr* b, Sexpr* rest, Sexpr* env) {
        return cons(from_uint(m + n), rest);
 }
 
+Sexpr* a_minus(Sexpr* b, Sexpr* rest, Sexpr* env) {
+       if(ARITH_SUB_ARGS != u64_get_num_args(b)) {
+               return cons(b, rest);
+       }
+       Sexpr* args = b->value.b.args;
+       Sexpr* i = eval(clone(car(args)), env);
+       Sexpr* j = eval(clone(car(cdr(args))), env);
+       uint64_t m = unquote(i)->value.u;
+       uint64_t n = unquote(j)->value.u;
+       sexpr_free(b);
+       sexpr_free(i);
+       sexpr_free(j);
+       return cons(from_uint(n - m), rest);
+}
+
+Sexpr* a_mul(Sexpr* b, Sexpr* rest, Sexpr* env) {
+       if(ARITH_MUL_ARGS != u64_get_num_args(b)) {
+               return cons(b, rest);
+       }
+       Sexpr* args = b->value.b.args;
+       Sexpr* i = eval(clone(car(args)), env);
+       Sexpr* j = eval(clone(car(cdr(args))), env);
+       uint64_t m = unquote(i)->value.u;
+       uint64_t n = unquote(j)->value.u;
+       sexpr_free(b);
+       sexpr_free(i);
+       sexpr_free(j);
+       return cons(from_uint(m * n), rest);
+}
+
+Sexpr* a_div(Sexpr* b, Sexpr* rest, Sexpr* env) {
+       if(ARITH_DIV_ARGS != u64_get_num_args(b)) {
+               return cons(b, rest);
+       }
+       Sexpr* args = b->value.b.args;
+       Sexpr* i = eval(clone(car(args)), env);
+       Sexpr* j = eval(clone(car(cdr(args))), env);
+       uint64_t m = unquote(i)->value.u;
+       uint64_t n = unquote(j)->value.u;
+       sexpr_free(b);
+       sexpr_free(i);
+       sexpr_free(j);
+       return cons(from_uint(n / m), rest);
+}
+
+Sexpr* a_mod(Sexpr* b, Sexpr* rest, Sexpr* env) {
+       if(ARITH_MOD_ARGS != u64_get_num_args(b)) {
+               return cons(b, rest);
+       }
+       Sexpr* args = b->value.b.args;
+       Sexpr* i = eval(clone(car(args)), env);
+       Sexpr* j = eval(clone(car(cdr(args))), env);
+       uint64_t m = unquote(i)->value.u;
+       uint64_t n = unquote(j)->value.u;
+       sexpr_free(b);
+       sexpr_free(i);
+       sexpr_free(j);
+       return cons(from_uint(n % m), rest);
+}
+
+
 Sexpr* x_arith_dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) {
        uint64_t code = b->value.b.opcode & 0xff;
 
        switch(code) {
-       case ARITH_PLUS:
+       case ARITH_ADD:
                return a_plus(b, rest, env);
+       case ARITH_SUB:
+               return a_minus(b, rest, env);
+       case ARITH_MUL:
+               return a_mul(b, rest, env);
+       case ARITH_DIV:
+               return a_div(b, rest, env);
+       case ARITH_MOD:
+               return a_mod(b, rest, env);
        default:
                return from_nil();
        }
@@ -39,11 +108,36 @@ Sexpr* x_arith_dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) {
 
 Sexpr* load_arith_env(Sexpr* env) {
        Sexpr* k;
+       Sexpr* v;
 
        k = from_sym("+");
-       Sexpr* a_plus = from_opcode((ARITH_PREFIX << 8) | ARITH_PLUS);
-       append_to_dict(env, k, a_plus);
-       sexpr_free(a_plus);
+       v = from_opcode((ARITH_PREFIX << 8) | ARITH_ADD);
+       append_to_dict(env, k, v);
+       sexpr_free(v);
+       sexpr_free(k);
+
+       k = from_sym("-");
+       v = from_opcode((ARITH_PREFIX << 8) | ARITH_SUB);
+       append_to_dict(env, k, v);
+       sexpr_free(v);
+       sexpr_free(k);
+
+               k = from_sym("*");
+       v = from_opcode((ARITH_PREFIX << 8) | ARITH_MUL);
+       append_to_dict(env, k, v);
+       sexpr_free(v);
+       sexpr_free(k);
+
+               k = from_sym("/");
+       v = from_opcode((ARITH_PREFIX << 8) | ARITH_DIV);
+       append_to_dict(env, k, v);
+       sexpr_free(v);
+       sexpr_free(k);
+
+               k = from_sym("%");
+       v = from_opcode((ARITH_PREFIX << 8) | ARITH_MOD);
+       append_to_dict(env, k, v);
+       sexpr_free(v);
        sexpr_free(k);
        return env;
 }
index bbfa4f015f69600b3141408a38f951f0906b5a79..0969286d1d80db3fd4be6845143b552ac1399659 100644 (file)
@@ -6,8 +6,16 @@
 #define ARITH_PREFIX 0x01
 
 
-#define ARITH_PLUS 0x00
-#define ARITH_PLUS_ARGS 2
+#define ARITH_ADD 0x00
+#define ARITH_ADD_ARGS 2
+#define ARITH_SUB 0x01
+#define ARITH_SUB_ARGS 2
+#define ARITH_MUL 0x02
+#define ARITH_MUL_ARGS 2
+#define ARITH_DIV 0x03
+#define ARITH_DIV_ARGS 2
+#define ARITH_MOD 0x04
+#define ARITH_MOD_ARGS 2
 
 Sexpr* x_arith_dispatch(Sexpr* s, Sexpr* rest, Sexpr* env);
 Sexpr* load_arith_env(Sexpr* env);
index 6eabb6d45f32496de31f41a3f340a3fc892964cf..0a970b8d86318403a76442e561069e9dcfb277c6 100644 (file)
@@ -288,6 +288,11 @@ void eval_tests() {
        run_eval_test("(not 4326)");
        run_eval_test("(not nil)");
        run_eval_test("(def asdf 545)");
+       run_eval_test("(- 100 20)");
+       run_eval_test("(* 100 20)");
+       run_eval_test("(/ 100 20)");
+       run_eval_test("(/ 100 21)");
+       run_eval_test("(% 54 7)");
 }