aoc16
This commit is contained in:
parent
c4809a1393
commit
acff699d2c
3
assert.c
3
assert.c
@ -4,6 +4,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <execinfo.h>
|
||||
|
||||
int *FOO = NULL;
|
||||
void __print_backtrace__(void)
|
||||
{
|
||||
void *funs[100] = {0};
|
||||
@ -19,5 +20,7 @@ void __print_backtrace__(void)
|
||||
printf(" %s\n", names[i]);
|
||||
}
|
||||
|
||||
++*FOO;
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
42
builtins.c
42
builtins.c
@ -269,6 +269,7 @@ static ptr panic(ptr i)
|
||||
printf("error: ");
|
||||
println(get_head(i));
|
||||
failwith("explicit panic");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ptr concat_sym(ptr i)
|
||||
@ -276,7 +277,8 @@ static ptr concat_sym(ptr i)
|
||||
i = eval_elems(i);
|
||||
int len = 0;
|
||||
ptr cursor = i;
|
||||
while (kind(cursor) == T_CON) {
|
||||
while (kind(cursor) == T_CON)
|
||||
{
|
||||
len += strlen(get_symbol_str(get_symbol(get_head(cursor))));
|
||||
cursor = get_tail(cursor);
|
||||
}
|
||||
@ -285,7 +287,8 @@ static ptr concat_sym(ptr i)
|
||||
char buf[SYM_SIZE] = {0};
|
||||
|
||||
cursor = i;
|
||||
while (kind(cursor) == T_CON) {
|
||||
while (kind(cursor) == T_CON)
|
||||
{
|
||||
strcat(buf, get_symbol_str(get_symbol(get_head(cursor))));
|
||||
cursor = get_tail(cursor);
|
||||
}
|
||||
@ -297,13 +300,45 @@ static ptr progn(ptr i)
|
||||
{
|
||||
i = eval_elems(i);
|
||||
ptr result = new_nil();
|
||||
while (kind(i) == T_CON) {
|
||||
while (kind(i) == T_CON)
|
||||
{
|
||||
result = get_head(i);
|
||||
i = get_tail(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static ptr read(ptr i)
|
||||
{
|
||||
i = eval_elems(i);
|
||||
i = get_head(i);
|
||||
|
||||
ptr cursor = i;
|
||||
i64 size = 0;
|
||||
while (kind(cursor) == T_CON)
|
||||
{
|
||||
size++;
|
||||
cursor = get_tail(cursor);
|
||||
}
|
||||
|
||||
printf("%d\n\n", size);
|
||||
|
||||
char buf[size+1];
|
||||
cursor = i;
|
||||
i64 k = 0;
|
||||
|
||||
while (kind(cursor) == T_CON)
|
||||
{
|
||||
buf[k++] = (char) get_int(get_head(cursor));
|
||||
cursor = get_tail(cursor);
|
||||
}
|
||||
buf[k] = 0;
|
||||
|
||||
char *buf_ptr = &(buf[0]);
|
||||
|
||||
return parse(&buf_ptr);
|
||||
}
|
||||
|
||||
void register_builtins(void)
|
||||
{
|
||||
new_builtin(&eq, "=");
|
||||
@ -325,6 +360,7 @@ void register_builtins(void)
|
||||
new_builtin(&is_pair, "pair?");
|
||||
new_builtin(&is_list, "list?");
|
||||
|
||||
new_builtin(&read, "read");
|
||||
new_builtin(&eval_quote, "quote");
|
||||
new_builtin(&eval_quasiquote, "quasiquote");
|
||||
|
||||
|
||||
2
const.h
2
const.h
@ -2,7 +2,7 @@
|
||||
#define __CONST_H__
|
||||
|
||||
// number of "values" that can be stored in the interpreter
|
||||
#define MEM_LEN 100000
|
||||
#define MEM_LEN 10000000
|
||||
|
||||
// maximal usage in percent:
|
||||
// this is to avoid repeatedly running the garbage collector to free
|
||||
|
||||
45
eval.c
45
eval.c
@ -3,6 +3,7 @@
|
||||
|
||||
static ptr (*builtins[MAX_BUILTINS])(ptr) = {0};
|
||||
static int builtins_len = 1;
|
||||
static int debug = 0;
|
||||
|
||||
void new_builtin(ptr (*fun)(ptr), char *sym)
|
||||
{
|
||||
@ -94,6 +95,10 @@ static ptr beta_reduce(ptr code, ptr formal_arg, ptr arg, int inside_quote)
|
||||
|
||||
ptr eval(ptr i)
|
||||
{
|
||||
if (debug) {
|
||||
printf("[DEBUG] ");
|
||||
println(i);
|
||||
}
|
||||
switch (kind(i))
|
||||
{
|
||||
case T_NAT:
|
||||
@ -135,7 +140,14 @@ ptr eval(ptr i)
|
||||
return builtins[-fun](args);
|
||||
}
|
||||
|
||||
if (kind(fun) != T_CON) {
|
||||
if (is_pragma(fun))
|
||||
{
|
||||
debug = 1;
|
||||
return new_nil();
|
||||
}
|
||||
|
||||
if (kind(fun) != T_CON)
|
||||
{
|
||||
|
||||
printf("unexpected form of function application: (");
|
||||
print(fun);
|
||||
@ -145,7 +157,11 @@ ptr eval(ptr i)
|
||||
|
||||
ptr fun_head = elem(0, fun);
|
||||
|
||||
assert(is_functionlike(fun_head));
|
||||
if (!is_functionlike(fun_head))
|
||||
{
|
||||
println(fun_head);
|
||||
assert(is_functionlike(fun_head));
|
||||
}
|
||||
|
||||
if (is_lambda(fun_head))
|
||||
{
|
||||
@ -156,17 +172,40 @@ ptr eval(ptr i)
|
||||
ptr formal_args = elem(1, fun);
|
||||
ptr fun_body = elem(2, fun);
|
||||
|
||||
// TODO Partial app
|
||||
int partial_args_len = 0;
|
||||
ptr partial_args[10];
|
||||
|
||||
while (kind(formal_args) != T_NIL)
|
||||
{
|
||||
ptr f_arg = get_head(formal_args);
|
||||
ptr c_arg = get_head(args);
|
||||
|
||||
fun_body = beta_reduce(fun_body, f_arg, c_arg, false);
|
||||
if (is_partial_app(c_arg))
|
||||
{
|
||||
partial_args[partial_args_len++] = f_arg;
|
||||
assert(partial_args_len < 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
fun_body = beta_reduce(fun_body, f_arg, c_arg, false);
|
||||
}
|
||||
|
||||
formal_args = get_tail(formal_args);
|
||||
args = get_tail(args);
|
||||
}
|
||||
|
||||
// in this case we just return a different lambda
|
||||
if (partial_args_len > 0)
|
||||
{
|
||||
ptr new_formal_args = new_nil();
|
||||
while (partial_args_len)
|
||||
{
|
||||
new_formal_args = new_cons(partial_args[--partial_args_len], new_formal_args);
|
||||
}
|
||||
return new_cons(fun_head, new_cons(new_formal_args, new_cons(fun_body, new_nil())));
|
||||
}
|
||||
|
||||
if (is_macro(fun_head))
|
||||
{
|
||||
// macro expansion
|
||||
|
||||
61
input.txt
Normal file
61
input.txt
Normal file
@ -0,0 +1,61 @@
|
||||
Valve WT has flow rate=0; tunnels lead to valves BD, FQ
|
||||
Valve UG has flow rate=0; tunnels lead to valves FQ, YB
|
||||
Valve FN has flow rate=0; tunnels lead to valves TV, GA
|
||||
Valve RU has flow rate=11; tunnels lead to valves YZ, QS, BL, BT, WJ
|
||||
Valve RH has flow rate=0; tunnels lead to valves AS, II
|
||||
Valve FL has flow rate=0; tunnels lead to valves HR, PQ
|
||||
Valve KQ has flow rate=18; tunnels lead to valves FR, BN
|
||||
Valve PM has flow rate=25; tunnels lead to valves YZ, FR
|
||||
Valve RQ has flow rate=0; tunnels lead to valves FQ, MW
|
||||
Valve BL has flow rate=0; tunnels lead to valves RU, IR
|
||||
Valve FF has flow rate=0; tunnels lead to valves QS, ED
|
||||
Valve KP has flow rate=0; tunnels lead to valves QM, MA
|
||||
Valve YB has flow rate=0; tunnels lead to valves UG, HR
|
||||
Valve TV has flow rate=17; tunnels lead to valves BD, MT, FN
|
||||
Valve HY has flow rate=0; tunnels lead to valves DW, IU
|
||||
Valve KF has flow rate=0; tunnels lead to valves AA, HR
|
||||
Valve YC has flow rate=0; tunnels lead to valves II, MA
|
||||
Valve EE has flow rate=0; tunnels lead to valves AA, CD
|
||||
Valve ED has flow rate=9; tunnels lead to valves HG, FF
|
||||
Valve SA has flow rate=0; tunnels lead to valves MW, LS
|
||||
Valve II has flow rate=20; tunnels lead to valves YC, CY, QP, RH
|
||||
Valve BN has flow rate=0; tunnels lead to valves BT, KQ
|
||||
Valve MO has flow rate=0; tunnels lead to valves XO, VI
|
||||
Valve YZ has flow rate=0; tunnels lead to valves RU, PM
|
||||
Valve WJ has flow rate=0; tunnels lead to valves RU, QP
|
||||
Valve AW has flow rate=0; tunnels lead to valves HR, DW
|
||||
Valve MJ has flow rate=0; tunnels lead to valves BP, AA
|
||||
Valve DW has flow rate=4; tunnels lead to valves AU, CB, HY, GL, AW
|
||||
Valve QM has flow rate=0; tunnels lead to valves KP, FQ
|
||||
Valve LF has flow rate=5; tunnels lead to valves LS, QN, AU, BP, ZY
|
||||
Valve QS has flow rate=0; tunnels lead to valves FF, RU
|
||||
Valve BT has flow rate=0; tunnels lead to valves BN, RU
|
||||
Valve VI has flow rate=22; tunnel leads to valve MO
|
||||
Valve LS has flow rate=0; tunnels lead to valves LF, SA
|
||||
Valve QD has flow rate=0; tunnels lead to valves HR, ZY
|
||||
Valve HG has flow rate=0; tunnels lead to valves AS, ED
|
||||
Valve BD has flow rate=0; tunnels lead to valves WT, TV
|
||||
Valve CD has flow rate=0; tunnels lead to valves EE, MW
|
||||
Valve QP has flow rate=0; tunnels lead to valves II, WJ
|
||||
Valve MW has flow rate=7; tunnels lead to valves PQ, SA, CB, CD, RQ
|
||||
Valve AU has flow rate=0; tunnels lead to valves DW, LF
|
||||
Valve RR has flow rate=0; tunnels lead to valves AS, MA
|
||||
Valve GA has flow rate=0; tunnels lead to valves FN, MA
|
||||
Valve MT has flow rate=0; tunnels lead to valves CY, TV
|
||||
Valve HR has flow rate=14; tunnels lead to valves KF, YB, QD, AW, FL
|
||||
Valve AS has flow rate=16; tunnels lead to valves RR, RH, HG, IR
|
||||
Valve CY has flow rate=0; tunnels lead to valves MT, II
|
||||
Valve AA has flow rate=0; tunnels lead to valves OX, KF, GL, MJ, EE
|
||||
Valve IU has flow rate=0; tunnels lead to valves XO, HY
|
||||
Valve XO has flow rate=23; tunnels lead to valves IU, MO
|
||||
Valve FR has flow rate=0; tunnels lead to valves KQ, PM
|
||||
Valve CB has flow rate=0; tunnels lead to valves MW, DW
|
||||
Valve ZY has flow rate=0; tunnels lead to valves QD, LF
|
||||
Valve BP has flow rate=0; tunnels lead to valves LF, MJ
|
||||
Valve QN has flow rate=0; tunnels lead to valves LF, FQ
|
||||
Valve IR has flow rate=0; tunnels lead to valves AS, BL
|
||||
Valve PQ has flow rate=0; tunnels lead to valves FL, MW
|
||||
Valve GL has flow rate=0; tunnels lead to valves AA, DW
|
||||
Valve OX has flow rate=0; tunnels lead to valves MA, AA
|
||||
Valve MA has flow rate=10; tunnels lead to valves RR, YC, GA, OX, KP
|
||||
Valve FQ has flow rate=12; tunnels lead to valves QN, WT, UG, RQ, QM
|
||||
288
lisp
288
lisp
@ -10,8 +10,6 @@
|
||||
)
|
||||
))
|
||||
|
||||
(if (= 0 0) 1 2)
|
||||
|
||||
(def fold (.\ (init fun list)
|
||||
(if (pair? list)
|
||||
(fold (fun init (hd list)) fun (tl list))
|
||||
@ -66,6 +64,8 @@
|
||||
`(def #name (.\ #args #body))
|
||||
)
|
||||
|
||||
(defun /= (x y) (nil? (= x y)))
|
||||
|
||||
(defun square(x) (* x x))
|
||||
(square 9)
|
||||
|
||||
@ -301,44 +301,274 @@ Point
|
||||
|
||||
(symcat 'he 'he 'ho)
|
||||
|
||||
(def input nil)
|
||||
|
||||
(typedfun max ((list? values))
|
||||
(fold 0 (.\ (x y) (cond ((< x y) y) (else x))) values)
|
||||
)
|
||||
|
||||
(defun split.aux (split_val values)
|
||||
(cond
|
||||
((nil? values) nil)
|
||||
((= split_val (hd values)) (cons nil (split.aux split_val (tl values))))
|
||||
(else (let split' (split.aux split_val (tl values))
|
||||
(cond
|
||||
((nil? split') (list (list (hd values))))
|
||||
(else (cons
|
||||
(cons (hd values) (hd split'))
|
||||
(tl split')
|
||||
))
|
||||
)
|
||||
))
|
||||
)
|
||||
(typedfun min ((list? values))
|
||||
(fold 1000000000 (.\ (x y) (cond ((< x y) x) (else y))) values)
|
||||
)
|
||||
|
||||
(typedfun split ((any? split_val) (list? values))
|
||||
(let result (split.aux split_val values)
|
||||
(cond
|
||||
((nil? result) nil)
|
||||
((nil? (fst result)) (tl result))
|
||||
(else result)
|
||||
(defun split.aux(delimiter array)
|
||||
(cond
|
||||
((nil? array)
|
||||
(list nil nil))
|
||||
(else
|
||||
(let res (split.aux delimiter (tl array))
|
||||
(cond
|
||||
((/= delimiter (fst array))
|
||||
(list (cons (fst array) (fst res)) (snd res)))
|
||||
(else
|
||||
(list nil (cons (fst res) (snd res))))
|
||||
))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(max input)
|
||||
(defun split (delimiter array)
|
||||
(snd (split.aux delimiter (cons delimiter array)))
|
||||
)
|
||||
|
||||
(split 5 '(1 2 3 5 4))
|
||||
(split 5 '(1 2 3 5 4 5))
|
||||
(split 5 '(5 1 2 5 3 5 4 5))
|
||||
(typedfun sum((list? x)) (fold 0 + x))
|
||||
(defun succ(x) (+ 1 x))
|
||||
(typedfun len((list? x)) (fold 0 succ x))
|
||||
(defun pow(a b)
|
||||
(cond
|
||||
((= 0 b) 1)
|
||||
(else (* a (pow a (- b 1))))
|
||||
)
|
||||
)
|
||||
|
||||
(split (hd ",") "hello, world!")
|
||||
(typedfun string->int ((list? str))
|
||||
(let digit (- (hd str) (hd "0"))
|
||||
(let res (tl str)
|
||||
(cond
|
||||
((nil? res) digit)
|
||||
(else (+
|
||||
(string->int res)
|
||||
(* digit
|
||||
(pow 10 (len res))
|
||||
)
|
||||
))
|
||||
)
|
||||
)))
|
||||
|
||||
(defun take(n xs)
|
||||
(cond
|
||||
((= n 0)
|
||||
nil)
|
||||
((nil? xs)
|
||||
nil)
|
||||
(else
|
||||
(cons (hd xs) (take (- n 1) (tl xs))))
|
||||
)
|
||||
)
|
||||
|
||||
(defun drop(n xs)
|
||||
(cond
|
||||
((= n 0)
|
||||
xs)
|
||||
(else
|
||||
(drop (- n 1) (tl xs)))
|
||||
)
|
||||
)
|
||||
|
||||
(defun contains(x xs)
|
||||
(cond
|
||||
((nil? xs) nil)
|
||||
((= x (hd xs)) true)
|
||||
(else (contains x (tl xs)))
|
||||
)
|
||||
)
|
||||
|
||||
(defun mod(x y)
|
||||
(- x (* y (/ x y)))
|
||||
)
|
||||
|
||||
(defun chunk.aux(size xs)
|
||||
(cond
|
||||
((nil? xs)
|
||||
(list nil nil))
|
||||
(else
|
||||
(let rest (chunk.aux size (tl xs))
|
||||
(cond
|
||||
((= size (len (fst rest)))
|
||||
(list (list (hd xs)) (cons (fst rest) (snd rest))))
|
||||
(else
|
||||
(list (cons (hd xs) (fst rest)) (snd rest)))
|
||||
))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(typedfun chunk((int? size) (list? xs))
|
||||
(let sol (chunk.aux size xs)
|
||||
(filter id (cons (fst sol) (snd sol))))
|
||||
)
|
||||
|
||||
(defun flatten(xss)
|
||||
(fold (hd xss) concat (tl xss))
|
||||
)
|
||||
|
||||
(defun half(xs)
|
||||
(let half_len (/ (len xs) 2)
|
||||
(list
|
||||
(take half_len xs)
|
||||
(drop half_len xs)
|
||||
))
|
||||
)
|
||||
|
||||
(defun find_same(yss)
|
||||
(let xs (hd yss)
|
||||
(let ys (tl yss)
|
||||
(fst
|
||||
(filter
|
||||
(.\ (x)
|
||||
(all (.\ (y) (contains x y)) ys))
|
||||
xs)
|
||||
))))
|
||||
)
|
||||
|
||||
(defun and(a b)
|
||||
(cond (a (cond (b true))))
|
||||
)
|
||||
|
||||
(defun range(begin end)
|
||||
(iter (- end begin) succ begin)
|
||||
)
|
||||
|
||||
(def in
|
||||
(map (.\ (l) (drop 6 l))
|
||||
(filter id
|
||||
(split 10
|
||||
input)))
|
||||
)
|
||||
|
||||
(defun remove_space(string)
|
||||
(filter (.\ (char) (/= (hd " ") char)) string)
|
||||
)
|
||||
|
||||
(defun parse_valve(line)
|
||||
(let name (take 2 line)
|
||||
(let flow
|
||||
(string->int
|
||||
(fst
|
||||
(split (hd ";")
|
||||
(snd
|
||||
(split (hd "=")
|
||||
line)))))
|
||||
(let conns
|
||||
(map remove_space
|
||||
(split (hd ",")
|
||||
(drop 24
|
||||
(snd
|
||||
(split (hd ";")
|
||||
line)))))
|
||||
`(#name #flow #conns))))
|
||||
)
|
||||
(def valves
|
||||
(map parse_valve in)
|
||||
)
|
||||
|
||||
(def name fst)
|
||||
(def flow snd)
|
||||
(def conn trd)
|
||||
|
||||
(defun maybe_head(list)
|
||||
(cond
|
||||
((nil? list) nil)
|
||||
(else (hd list))
|
||||
)
|
||||
)
|
||||
|
||||
(defun or (x y)
|
||||
(cond
|
||||
(x x)
|
||||
(1 y)
|
||||
)
|
||||
)
|
||||
|
||||
(defun map.new() nil)
|
||||
(defun map.get_or(m key default)
|
||||
(or (map.get m key) default)
|
||||
)
|
||||
(defun map.get_all(m key)
|
||||
(map snd
|
||||
(filter (.\ (entry) (= key (fst entry)))
|
||||
m))
|
||||
)
|
||||
(defun map.get(map key)
|
||||
(maybe_head (map.get_all map key))
|
||||
)
|
||||
(defun map.update(m key fun)
|
||||
(map.ins m key (maybe_head (map fun (map.get_all m key))))
|
||||
)
|
||||
(defun map.update_or(map key default fun)
|
||||
(map.ins map key (fun (map.get_or map key default)))
|
||||
)
|
||||
(defun map.rem(map key)
|
||||
(filter (.\ (entry) (/= key (fst entry))) map)
|
||||
)
|
||||
(defun map.ins(map key val)
|
||||
(cons
|
||||
`(#key #val)
|
||||
(map.rem map key)
|
||||
)
|
||||
)
|
||||
(defun map.keys(m)
|
||||
(map fst m)
|
||||
)
|
||||
(def infty 10000000)
|
||||
|
||||
(def key fst)
|
||||
(def val snd)
|
||||
|
||||
'valves
|
||||
valves
|
||||
|
||||
(def names (map name valves))
|
||||
'names
|
||||
names
|
||||
|
||||
(defun repeat(amt list)
|
||||
(cond
|
||||
((= 0 amt) nil)
|
||||
(else (concat list (repeat (- amt 1) list)))
|
||||
)
|
||||
)
|
||||
|
||||
(defun make2(x) `(#x #x))
|
||||
|
||||
(def edges (flatten (map (.\ (vertex) (map (.\ (neighbor) (list (name vertex) neighbor)) (conn vertex))) valves)))
|
||||
(def dist0 (fold (map.new) (map.ins .. .. 0) (map make2 names)))
|
||||
|
||||
(defun smoler(a b)
|
||||
(cond
|
||||
((< a b) a)
|
||||
(else b)
|
||||
)
|
||||
)
|
||||
|
||||
dist0
|
||||
|
||||
(fold
|
||||
dist0
|
||||
(.\ (dist edge)
|
||||
(fold
|
||||
dist
|
||||
(.\ (d entry)
|
||||
(let from (fst edge)
|
||||
(let to (snd (key entry))
|
||||
(let len (+ 1 (val entry))
|
||||
(let e `(#from #to)
|
||||
(map.update_or d e infty (smoler .. len))
|
||||
)))))
|
||||
(filter (.\ (entry) (= (snd edge) (fst (key entry)))) dist)
|
||||
)
|
||||
)
|
||||
(repeat 30 edges)
|
||||
)
|
||||
|
||||
(= edges (repeat 1 edges))
|
||||
|
||||
'(end of program)
|
||||
|
||||
2
lisp.c
2
lisp.c
@ -38,7 +38,7 @@ int main(void)
|
||||
lisp[fsize] = 0;
|
||||
|
||||
init();
|
||||
dump();
|
||||
//dump();
|
||||
|
||||
char *lisp_ptr = &lisp[0];
|
||||
char **cursor = &lisp_ptr;
|
||||
|
||||
2
lisp.h
2
lisp.h
@ -97,6 +97,8 @@ int is_lambda(ptr i);
|
||||
int is_macro(ptr i);
|
||||
int is_functionlike(ptr i);
|
||||
int is_definition(ptr i);
|
||||
int is_partial_app(ptr i);
|
||||
int is_pragma(ptr i);
|
||||
|
||||
void print(ptr i);
|
||||
void println(ptr i);
|
||||
|
||||
84
mem.c
84
mem.c
@ -17,17 +17,19 @@ should never be GC'ed
|
||||
static ptr builtin_use;
|
||||
|
||||
#define make(name) \
|
||||
static ptr sym_ ## name = 0; \
|
||||
int is_ ## name(ptr i) \
|
||||
{ \
|
||||
return i == sym_ ## name; \
|
||||
}
|
||||
make(quote)
|
||||
make(unquote)
|
||||
make(quasiquote)
|
||||
make(lambda)
|
||||
make(macro)
|
||||
make(definition)
|
||||
static ptr sym_##name = 0; \
|
||||
int is_##name(ptr i) \
|
||||
{ \
|
||||
return i == sym_##name; \
|
||||
}
|
||||
make(quote);
|
||||
make(unquote);
|
||||
make(quasiquote);
|
||||
make(lambda);
|
||||
make(macro);
|
||||
make(definition);
|
||||
make(partial_app);
|
||||
make(pragma);
|
||||
#undef make
|
||||
|
||||
int is_functionlike(ptr i)
|
||||
@ -57,9 +59,40 @@ static void init_builtin_symbols(void)
|
||||
make_sym(sym_quote, "quote");
|
||||
make_sym(sym_unquote, "unquote");
|
||||
make_sym(sym_quasiquote, "quasiquote");
|
||||
make_sym(sym_partial_app, "..");
|
||||
make_sym(sym_pragma, "pragma");
|
||||
#undef make_sym
|
||||
}
|
||||
|
||||
/*
|
||||
reads the input file
|
||||
*/
|
||||
void read_input(void)
|
||||
{
|
||||
FILE *f = fopen("input.txt", "rb");
|
||||
assert(f);
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t fsize = (size_t)ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
char *buf = malloc(fsize + 1);
|
||||
assert(buf);
|
||||
|
||||
fread(buf, fsize, 1, f);
|
||||
fclose(f);
|
||||
buf[fsize] = 0;
|
||||
|
||||
ptr input = new_nil();
|
||||
for (char *cursor = buf + fsize - 1; cursor >= buf; cursor--)
|
||||
{
|
||||
input = new_cons(new_int(*cursor), input);
|
||||
}
|
||||
new_binding(new_symbol("input"), input);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
initializes the interpreter
|
||||
do NOT call twice
|
||||
@ -67,12 +100,12 @@ do NOT call twice
|
||||
void init(void)
|
||||
{
|
||||
static int initialized = 0;
|
||||
if (initialized) {
|
||||
if (initialized)
|
||||
{
|
||||
failwith("already initialized");
|
||||
}
|
||||
initialized = 1;
|
||||
|
||||
|
||||
mem[0].kind = T_NIL;
|
||||
|
||||
mem[1].kind = T_INT;
|
||||
@ -97,6 +130,7 @@ void init(void)
|
||||
init_builtin_symbols();
|
||||
register_builtins();
|
||||
builtin_use = empty;
|
||||
read_input();
|
||||
}
|
||||
|
||||
/* GC run count */
|
||||
@ -120,16 +154,17 @@ static void mark_globals(void)
|
||||
|
||||
ptr *walker;
|
||||
|
||||
/*
|
||||
searches the entire C stack for references to LISP values
|
||||
/*
|
||||
searches the entire C stack for references to LISP values
|
||||
if it finds any, it marks those values as 'in use'
|
||||
*/
|
||||
void stack_search_impl(void)
|
||||
{
|
||||
ptr dummy = 0;
|
||||
walker = &dummy;
|
||||
while (++walker != stack_top) {
|
||||
if (*walker < MEM_LEN && *walker > 0)
|
||||
while (++walker != stack_top)
|
||||
{
|
||||
if (*walker<MEM_LEN && * walker> 0)
|
||||
{
|
||||
mem[*walker].gc = gen;
|
||||
}
|
||||
@ -144,7 +179,8 @@ if it is a freshly marked value, it will also mark the child values
|
||||
*/
|
||||
static void maybe_mark(ptr i)
|
||||
{
|
||||
if (i < 0) return;
|
||||
if (i < 0)
|
||||
return;
|
||||
if (mem[i].gc != gen)
|
||||
{
|
||||
mem[i].gc = gen;
|
||||
@ -175,7 +211,7 @@ static void mark_all_reachable(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
marks all unreachable nodes as 'empty' and make them available to be reused
|
||||
*/
|
||||
static void reconstruct_empty_list(void)
|
||||
@ -204,14 +240,15 @@ static void reconstruct_empty_list(void)
|
||||
empty = prev_empty;
|
||||
|
||||
int usage = 100 - 100 * free_memory / MEM_LEN;
|
||||
//printf("GC go brrrr... (%d%%)\n", usage);
|
||||
if (usage > MAX_MEMORY_USAGE || usage > 99) {
|
||||
// printf("GC go brrrr... (%d%%)\n", usage);
|
||||
if (usage > MAX_MEMORY_USAGE || usage > 99)
|
||||
{
|
||||
printf("Out of memory.\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
garbage collector to free up nodes
|
||||
does not return if out of memory, instead will stop program
|
||||
*/
|
||||
@ -242,7 +279,8 @@ static ptr alloc(void)
|
||||
return new;
|
||||
}
|
||||
|
||||
static void check(ptr i) {
|
||||
static void check(ptr i)
|
||||
{
|
||||
if (i >= 0 && i < MEM_LEN)
|
||||
{
|
||||
if (mem[i].gc == ~0 && mem[i].kind == T_EMT)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user