|
|
@ -31,6 +31,13 @@ Pointer func(Pointer code, Pointer env) { |
|
|
|
return fn; |
|
|
|
return fn; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pointer macro(Pointer code, Pointer env) { |
|
|
|
|
|
|
|
Pointer fn = memory_new(MACRO, sizeof(Func)); |
|
|
|
|
|
|
|
FUNC(fn).code = code; |
|
|
|
|
|
|
|
FUNC(fn).env = env; |
|
|
|
|
|
|
|
return fn; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** FUNCTIONS **/ |
|
|
|
/** FUNCTIONS **/ |
|
|
|
|
|
|
|
|
|
|
|
Pointer add_fn(Pointer args, Pointer env) { |
|
|
|
Pointer add_fn(Pointer args, Pointer env) { |
|
|
@ -198,11 +205,75 @@ Pointer fn_fn(Pointer args, Pointer env) { |
|
|
|
return func(args, env); |
|
|
|
return func(args, env); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pointer defmacro_fn(Pointer args, Pointer env) { |
|
|
|
|
|
|
|
return environment_set(NIL, CAR(args), macro(CDR(args), env)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Pointer exit_fn(Pointer args, Pointer env) { |
|
|
|
Pointer exit_fn(Pointer args, Pointer env) { |
|
|
|
(void) args; (void) env; |
|
|
|
(void) args; (void) env; |
|
|
|
exit(1); |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pointer eq_fn(Pointer args, Pointer env) { |
|
|
|
|
|
|
|
(void) env; |
|
|
|
|
|
|
|
Pointer a = CAR(args); |
|
|
|
|
|
|
|
Pointer b = CAR(CDR(args)); |
|
|
|
|
|
|
|
Type type = TYPE(a); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (type != TYPE(b)) { |
|
|
|
|
|
|
|
return NIL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (type) { |
|
|
|
|
|
|
|
case NUMBER:
|
|
|
|
|
|
|
|
return NUMBER(a) == NUMBER(b) ? T : NIL; |
|
|
|
|
|
|
|
case STRING: |
|
|
|
|
|
|
|
return strcmp(STRING(a).data, STRING(b).data) == 0 ? T : NIL; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
return a == b ? T : NIL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pointer lt_fn(Pointer args, Pointer env) { |
|
|
|
|
|
|
|
(void) env; |
|
|
|
|
|
|
|
Pointer a = CAR(args); |
|
|
|
|
|
|
|
Pointer b = CAR(CDR(args)); |
|
|
|
|
|
|
|
if (TYPE(a) != NUMBER || TYPE(b) != NUMBER) { |
|
|
|
|
|
|
|
return UNDEFINED; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return NUMBER(a) < NUMBER(b) ? T : NIL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pointer gt_fn(Pointer args, Pointer env) { |
|
|
|
|
|
|
|
(void) env; |
|
|
|
|
|
|
|
Pointer a = CAR(args); |
|
|
|
|
|
|
|
Pointer b = CAR(CDR(args)); |
|
|
|
|
|
|
|
if (TYPE(a) != NUMBER || TYPE(b) != NUMBER) { |
|
|
|
|
|
|
|
return UNDEFINED; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return NUMBER(a) > NUMBER(b) ? T : NIL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pointer le_fn(Pointer args, Pointer env) { |
|
|
|
|
|
|
|
(void) env; |
|
|
|
|
|
|
|
Pointer a = CAR(args); |
|
|
|
|
|
|
|
Pointer b = CAR(CDR(args)); |
|
|
|
|
|
|
|
if (TYPE(a) != NUMBER || TYPE(b) != NUMBER) { |
|
|
|
|
|
|
|
return UNDEFINED; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return NUMBER(a) <= NUMBER(b) ? T : NIL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pointer ge_fn(Pointer args, Pointer env) { |
|
|
|
|
|
|
|
(void) env; |
|
|
|
|
|
|
|
Pointer a = CAR(args); |
|
|
|
|
|
|
|
Pointer b = CAR(CDR(args)); |
|
|
|
|
|
|
|
if (TYPE(a) != NUMBER || TYPE(b) != NUMBER) { |
|
|
|
|
|
|
|
return UNDEFINED; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return NUMBER(a) >= NUMBER(b) ? T : NIL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#define SET_FUNC(s, fn) environment_set(NIL, symbol1(s), native_func(fn)) |
|
|
|
#define SET_FUNC(s, fn) environment_set(NIL, symbol1(s), native_func(fn)) |
|
|
|
#define SET_FORM(s, fn) environment_set(NIL, symbol1(s), special_form(fn)) |
|
|
|
#define SET_FORM(s, fn) environment_set(NIL, symbol1(s), special_form(fn)) |
|
|
|
|
|
|
|
|
|
|
@ -232,6 +303,11 @@ void init(void) { |
|
|
|
SET_FUNC("peek-char", peek_char_fn); |
|
|
|
SET_FUNC("peek-char", peek_char_fn); |
|
|
|
SET_FUNC("read-char", read_char_fn); |
|
|
|
SET_FUNC("read-char", read_char_fn); |
|
|
|
SET_FUNC("exit", exit_fn); |
|
|
|
SET_FUNC("exit", exit_fn); |
|
|
|
|
|
|
|
SET_FUNC("=", eq_fn); |
|
|
|
|
|
|
|
SET_FUNC("<", lt_fn); |
|
|
|
|
|
|
|
SET_FUNC(">", gt_fn); |
|
|
|
|
|
|
|
SET_FUNC("<=", le_fn); |
|
|
|
|
|
|
|
SET_FUNC(">=", ge_fn); |
|
|
|
|
|
|
|
|
|
|
|
SET_FORM("if", if_fn); |
|
|
|
SET_FORM("if", if_fn); |
|
|
|
SET_FORM("let", let_fn); |
|
|
|
SET_FORM("let", let_fn); |
|
|
@ -241,6 +317,7 @@ void init(void) { |
|
|
|
SET_FORM("def", def_fn); |
|
|
|
SET_FORM("def", def_fn); |
|
|
|
SET_FORM("set", set_fn); |
|
|
|
SET_FORM("set", set_fn); |
|
|
|
SET_FORM("fn", fn_fn); |
|
|
|
SET_FORM("fn", fn_fn); |
|
|
|
|
|
|
|
SET_FORM("defmacro", defmacro_fn); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void repl(void) { |
|
|
|
void repl(void) { |
|
|
|