blob: c7efca0cd4b7286457e8ce1f556066a99974966b [file] [log] [blame]
swissChilib3ca4fb2021-04-20 10:33:00 -07001#include "std.h"
swissChilif68671f2021-07-05 14:14:44 -07002#include "../plat/plat.h"
swissChilif3e7f182021-04-20 13:57:22 -07003#include <stdlib.h>
swissChilif68671f2021-07-05 14:14:44 -07004#include <string.h>
swissChilib3ca4fb2021-04-20 10:33:00 -07005
swissChili53472e82021-05-08 16:06:32 -07006value_t l_plus(value_t a, value_t b)
swissChilib3ca4fb2021-04-20 10:33:00 -07007{
swissChili53472e82021-05-08 16:06:32 -07008 if (!integerp(a) || !integerp(b))
swissChilib3ca4fb2021-04-20 10:33:00 -07009 return nil;
10
11 return (((a >> 2) + (b >> 2)) << 2) | INT_TAG;
12}
13
swissChili53472e82021-05-08 16:06:32 -070014value_t l_minus(value_t a, value_t b)
swissChili6aff2bb2021-04-20 15:02:53 -070015{
swissChili53472e82021-05-08 16:06:32 -070016 if (!integerp(a) || !integerp(b))
swissChili6aff2bb2021-04-20 15:02:53 -070017 return nil;
18
19 return (((a >> 2) - (b >> 2)) << 2) | INT_TAG;
20}
21
swissChili53472e82021-05-08 16:06:32 -070022value_t l_times(value_t a, value_t b)
swissChili6aff2bb2021-04-20 15:02:53 -070023{
swissChili53472e82021-05-08 16:06:32 -070024 if (!integerp(a) || !integerp(b))
swissChili6aff2bb2021-04-20 15:02:53 -070025 return nil;
26
27 return (((a >> 2) * (b >> 2)) << 2) | INT_TAG;
28}
29
swissChili53472e82021-05-08 16:06:32 -070030value_t l_divide(value_t a, value_t b)
swissChili6aff2bb2021-04-20 15:02:53 -070031{
swissChili53472e82021-05-08 16:06:32 -070032 if (!integerp(a) || !integerp(b))
swissChili6aff2bb2021-04-20 15:02:53 -070033 return nil;
34
35 return (((a >> 2) / (b >> 2)) << 2) | INT_TAG;
36}
37
swissChili53472e82021-05-08 16:06:32 -070038value_t l_printval(value_t val)
swissChili8fc5e2f2021-04-22 13:45:10 -070039{
swissChili53472e82021-05-08 16:06:32 -070040 printval(val, 0);
swissChili8fc5e2f2021-04-22 13:45:10 -070041 return nil;
42}
43
swissChiliddc97542021-07-04 11:47:42 -070044value_t l_apply(value_t func, value_t args)
45{
46 if (!closurep(func))
47 return nil;
48
49 if (!listp(args))
50 return nil;
51
52 return call_list_closure((struct closure *)(func ^ CLOSURE_TAG), args);
53}
54
swissChili2999dd12021-07-02 14:19:53 -070055void add_function(struct environment *env, char *name, void *func, int nargs, enum namespace ns)
swissChilib3ca4fb2021-04-20 10:33:00 -070056{
swissChili53472e82021-05-08 16:06:32 -070057 struct function *last, *new = malloc(sizeof(struct function));
swissChilib3ca4fb2021-04-20 10:33:00 -070058
59 last = env->first;
60 new->prev = last;
61 new->name = name;
62 new->nargs = nargs;
63 new->code_ptr = func;
swissChili2999dd12021-07-02 14:19:53 -070064 new->namespace = ns;
swissChilib3ca4fb2021-04-20 10:33:00 -070065
swissChilif3e7f182021-04-20 13:57:22 -070066 env->first = new;
swissChilib3ca4fb2021-04-20 10:33:00 -070067}
68
swissChili53472e82021-05-08 16:06:32 -070069void load_std(struct environment *env)
swissChilib3ca4fb2021-04-20 10:33:00 -070070{
swissChili2999dd12021-07-02 14:19:53 -070071 add_function(env, "+", l_plus, 2, NS_FUNCTION);
72 add_function(env, "-", l_minus, 2, NS_FUNCTION);
73 add_function(env, "*", l_times, 2, NS_FUNCTION);
74 add_function(env, "/", l_divide, 2, NS_FUNCTION);
swissChili8fc5e2f2021-04-22 13:45:10 -070075
swissChili2999dd12021-07-02 14:19:53 -070076 add_function(env, "car", car, 1, NS_FUNCTION);
77 add_function(env, "cdr", cdr, 1, NS_FUNCTION);
78 add_function(env, "cons", cons, 2, NS_FUNCTION);
swissChili8fc5e2f2021-04-22 13:45:10 -070079
swissChili2999dd12021-07-02 14:19:53 -070080 add_function(env, "print", l_printval, 1, NS_FUNCTION);
swissChiliddc97542021-07-04 11:47:42 -070081
82 add_function(env, "apply", l_apply, 2, NS_FUNCTION);
swissChilif68671f2021-07-05 14:14:44 -070083
84 if (!load_library(env, "std"))
85 {
86 err("Could not load library `std`, make sure your $LISP_LIBRARY_PATH is correct.");
87 }
88}
89
90bool load_library(struct environment *env, char *name)
91{
92 char *lib_paths = getenv("LISP_LIBRARY_PATH");
93
94 if (!lib_paths)
95 lib_paths = "/lib/lisp";
96
97 for (char *p = strtok(lib_paths, ":"); p; p = strtok(NULL, ":"))
98 {
99 static char path[512];
100 snprintf(path, 512, "%s/%s.lisp", p, name);
101
102 if (file_exists(path))
103 {
104 return load(env, path);
105 }
106
107 snprintf(path, 512, "%s/%s/%s.lisp", p, name, name);
108
109 if (file_exists(path))
110 {
111 return load(env, path);
112 }
113 }
114
115 return false;
swissChilib3ca4fb2021-04-20 10:33:00 -0700116}