-module(scheme_prelude). -export([cons/2, car/1, cdr/1, listxqs/1]). % Scheme prelude for programs compiled from Scheme to Erlang. % A few conventions apply: % - question marks become _p, so even? becomes even_p % - exclamation marks are outlawed because the Scheme subset % is pure-functional, so set! and its ilk are not present. % - hyphens become _mn, so list-ref becomes list_mnref % - underscores will become double underscores. % At present, this still leaves an ambiguity between even-p and % even?, but we will ignore that. All that aside, operator % symbols become three-character abbreviations whose names all % begin with an underscore. For example: % + -> _pl % * -> _st % - -> _mn % / -> _dv % Therefore, symbols can still be used in variable names, such % as *some-variable* which becomes _stsome_mnvariable_st. This % would be hideous to work with, but for our purposes is % transparent enough. % variadic functions xpl([A]) -> A; xpl([A|B]) -> A + xpl(B). xst([A]) -> A; xst([A|B]) -> A * xst(B). xmn([A]) -> A; xmn([A|B]) -> A - xmn(B). list(L) -> L. xeq(A, B) -> A == B. cons(A, B) -> [A|B]. car([A|_]) -> A. cdr([_|B]) -> B. append(A, B) -> lists:append(A, B). filter(Proc, L) -> lists:filter(Proc, L). map(Proc, L) -> lists:map(Proc, L). member(X, [X|L]) -> [X|L]; member(X, [_|L]) -> member(X, L); member(_, []) -> false. assoc(X, [{X, A}|L]) -> {X, A}; assoc(X, [{_, _}|L]) -> scheme_prelude:assoc(X, L); assoc(_, []) -> false. reverse(L) -> lists:reverse(L). reduce(Proc, [X|L]) -> lists:foldl(Proc, X, L). listxqs([_|B]) -> scheme_prelude:list_qs(B); listxqs([]) -> true; listxqs(_) -> false. nullxqs([]) -> true; nullxqs(_) -> false. pairxqs([_|_]) -> true; pairxqs(_) -> false. numberxqs(X) -> is_number(X). equalsxqs(X, Y) -> X == Y. length([X|Y]) -> 1 + scheme_prelude:length(Y); length([]) -> 0. symbolxqs(X) -> is_atom(X). booleanxqs(true) -> true; booleanxqs(false) -> true; booleanxqs(_) -> false. scheme_and(L) -> all(fun(X) -> scheme_prelude:is_true end, L). scheme_or(L) -> any(fun(X) -> scheme_prelude:is_true end, L). all(Func, [X|XS]) -> case Func(X) of scheme_not(false) -> true; scheme_not(_) -> false. is_true(false) -> false; is_true(X) -> X.