Skip to content

Commit

Permalink
[#42] Remove ISeq implementation for all collections except clojerl.L…
Browse files Browse the repository at this point in the history
…ist and clojerl.erlang.List
  • Loading branch information
jfacorro committed Feb 1, 2016
1 parent c1dd2ed commit e610317
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 76 deletions.
32 changes: 32 additions & 0 deletions priv/clojure/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,35 @@
([f x y args] (clj_core/invoke f (cons x (cons y (seq args)))))
([f x y z args] (clj_core/invoke f (cons x (cons y (cons z (seq args))))))
([f a b c d args] (clj_core/invoke f (cons a (cons b (cons c (cons d (seq args)))))))))

(def first
(fn* [xs] (clj_core/first xs)))

(def rest
(fn* [xs] (clj_core/rest xs)))

(def next
(fn* [xs] (clj_core/next xs)))

(def concat
(fn*
([] (list))
([x] (apply list x))
([x y]
(if (seq x)
(cons (first (seq x)) (concat (rest (seq x)) y))
y))
([x y & zs]
(if (seq zs)
(apply concat (concat x y) (first zs) (next zs))
(concat x y)))))

(def with-meta
(fn* [x meta] (clj_core/with_meta x meta)))

(def meta
(fn* [x] (clj_core/meta x)))

(def ^:macro defn
(fn* [_form _env name args & body]
`(def ~name (fn* ~args ~@body))))
7 changes: 7 additions & 0 deletions priv/examples/macro.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(ns examples.macro)

(clojure.core/defn hello
[x]
(clojure.core/prn [:hello x]))

(hello "Joni")
22 changes: 12 additions & 10 deletions src/clj_analyzer.erl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ is_special(S) ->
macroexpand_1(Env, Form) ->
Op = clj_core:first(Form),
{MacroVar, Env} = lookup_var(Op, false, Env),

case
is_special(Op)
orelse (not clj_core:'symbol?'(Op))
Expand All @@ -33,9 +34,9 @@ macroexpand_1(Env, Form) ->
true -> Form;
false ->
{MacroVar, Env} = lookup_var(Op, false, Env),
Fun = clj_core:deref(MacroVar),
Args = [Form, Env, clj_core:rest(Form)],
erlang:apply(Fun, Args)
Var = clj_core:deref(MacroVar),
Args = [Form, Env] ++ clj_core:seq(clj_core:rest(Form)),
clj_core:invoke(Var, Args)
end.

-spec macroexpand(clj_env:env(), 'clojerl.List':type()) -> any().
Expand Down Expand Up @@ -87,17 +88,17 @@ analyze_forms(Env, Forms) ->

-spec analyze_form(clj_env:env(), any()) -> clj_env:env().
analyze_form(Env, Form) ->
case clj_core:type(Form) of
'clojerl.Symbol' ->
analyze_symbol(Env, Form);
'clojerl.List' ->
case {clj_core:type(Form), clj_core:'seq?'(Form)} of
{_, true} ->
Op = clj_core:first(Form),
analyze_seq(Env, Op, Form);
'clojerl.Vector' ->
{'clojerl.Symbol', _} ->
analyze_symbol(Env, Form);
{'clojerl.Vector', _} ->
analyze_vector(Env, Form);
'clojerl.Map' ->
{'clojerl.Map', _} ->
analyze_map(Env, Form);
'clojerl.Set' ->
{'clojerl.Set', _} ->
analyze_set(Env, Form);
_ ->
analyze_const(Env, Form)
Expand Down Expand Up @@ -612,6 +613,7 @@ validate_def_args(List) ->
{4, Str} when is_binary(Str) -> Str;
_ -> undefined
end,

case clj_core:count(List) of
C when C == 2;
C == 3, Docstring == undefined;
Expand Down
18 changes: 15 additions & 3 deletions src/clj_core.erl
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,27 @@ cons(Item, Seq) ->

-spec first(any()) -> any().
first(undefined) -> undefined;
first(Seq) -> 'clojerl.ISeq':first(Seq).
first(Seq) ->
case 'seq?'(Seq) of
true -> 'clojerl.ISeq':first(Seq);
false -> 'clojerl.ISeq':first(seq(Seq))
end.

-spec next(any()) -> any().
next(undefined) -> undefined;
next(Seq) -> 'clojerl.ISeq':next(Seq).
next(Seq) ->
case 'seq?'(Seq) of
true -> 'clojerl.ISeq':next(Seq);
false -> 'clojerl.ISeq':next(seq(Seq))
end.

-spec rest(any()) -> any().
rest(undefined) -> undefined;
rest(Seq) -> 'clojerl.ISeq':more(Seq).
rest(Seq) ->
case 'seq?'(Seq) of
true -> 'clojerl.ISeq':more(Seq);
false -> 'clojerl.ISeq':more(seq(Seq))
end.

-spec second(any()) -> any().
second(Seq) ->
Expand Down
11 changes: 0 additions & 11 deletions src/lang/collections/clojerl.Map.erl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
-behavior('clojerl.Counted').
-behavior('clojerl.Stringable').
-behavior('clojerl.Seqable').
-behavior('clojerl.ISeq').
-behavior('clojerl.IMeta').
-behavior('clojerl.IColl').
-behavior('clojerl.ILookup').
Expand All @@ -14,10 +13,6 @@
-export(['clojerl.Counted.count'/1]).
-export(['clojerl.Stringable.str'/1]).
-export(['clojerl.Seqable.seq'/1]).
-export([ 'clojerl.ISeq.first'/1
, 'clojerl.ISeq.next'/1
, 'clojerl.ISeq.more'/1
]).
-export([ 'clojerl.IMeta.meta'/1
, 'clojerl.IMeta.with_meta'/2
]).
Expand Down Expand Up @@ -75,12 +70,6 @@ vals(#?TYPE{name = ?M, data = Map}) -> maps:values(Map).
X -> X
end.

'clojerl.ISeq.first'(Map) -> clj_core:first(clj_core:seq(Map)).

'clojerl.ISeq.next'(Map) -> clj_core:next(clj_core:seq(Map)).

'clojerl.ISeq.more'(Map) -> clj_core:rest(clj_core:seq(Map)).

'clojerl.IMeta.meta'(#?TYPE{name = ?M, info = Info}) ->
maps:get(meta, Info, undefined).

Expand Down
25 changes: 0 additions & 25 deletions src/lang/collections/clojerl.Set.erl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
-behavior('clojerl.Counted').
-behavior('clojerl.Stringable').
-behavior('clojerl.Seqable').
-behavior('clojerl.ISeq').
-behavior('clojerl.IMeta').
-behavior('clojerl.IColl').
-behavior('clojerl.ILookup').
Expand All @@ -14,10 +13,6 @@
-export(['clojerl.Counted.count'/1]).
-export(['clojerl.Stringable.str'/1]).
-export(['clojerl.Seqable.seq'/1]).
-export([ 'clojerl.ISeq.first'/1
, 'clojerl.ISeq.next'/1
, 'clojerl.ISeq.more'/1
]).
-export([ 'clojerl.IMeta.meta'/1
, 'clojerl.IMeta.with_meta'/2
]).
Expand Down Expand Up @@ -53,26 +48,6 @@ new(Values) when is_list(Values) ->
_ -> gb_sets:to_list(Set)
end.

'clojerl.ISeq.first'(#?TYPE{name = ?M, data = Set}) ->
Iterator = gb_sets:iterator(Set),
case gb_sets:next(Iterator) of
none -> undefined;
{X, _} -> X
end.

'clojerl.ISeq.next'(#?TYPE{name = ?M, data = Set}) ->
case gb_sets:to_list(Set) of
[] -> undefined;
[_ | []] -> undefined;
[_ | Items] -> clj_core:list(Items)
end.

'clojerl.ISeq.more'(#?TYPE{name = ?M, data = GbSet} = Set) ->
case gb_sets:size(GbSet) of
0 -> clj_core:list([]);
_ -> 'clojerl.ISeq.next'(Set)
end.

'clojerl.IMeta.meta'(#?TYPE{name = ?M, info = Info}) ->
maps:get(meta, Info, undefined).

Expand Down
27 changes: 0 additions & 27 deletions src/lang/collections/clojerl.Vector.erl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
-behavior('clojerl.Counted').
-behavior('clojerl.IColl').
-behavior('clojerl.IMeta').
-behavior('clojerl.ISeq').
-behavior('clojerl.ISequential').
-behavior('clojerl.Seqable').
-behavior('clojerl.Stringable').
Expand All @@ -15,10 +14,6 @@
-export(['clojerl.Counted.count'/1]).
-export(['clojerl.Stringable.str'/1]).
-export(['clojerl.Seqable.seq'/1]).
-export([ 'clojerl.ISeq.first'/1
, 'clojerl.ISeq.next'/1
, 'clojerl.ISeq.more'/1
]).
-export([ 'clojerl.IMeta.meta'/1
, 'clojerl.IMeta.with_meta'/2
]).
Expand Down Expand Up @@ -57,28 +52,6 @@ new(Items) when is_list(Items) ->
'clojerl.IMeta.with_meta'(#?TYPE{name = ?M, info = Info} = Vector, Metadata) ->
Vector#?TYPE{info = Info#{meta => Metadata}}.

'clojerl.ISeq.first'(#?TYPE{name = ?M, data = Array}) ->
case array:size(Array) of
0 -> undefined;
_ -> array:get(0, Array)
end.

'clojerl.ISeq.next'(#?TYPE{name = ?M, data = Array}) ->
case array:size(Array) of
0 -> undefined;
_ ->
%% Reset the first element and get all non-resset elements.
RestArray = array:reset(0, Array),
Items = array:sparse_to_list(RestArray),
clj_core:list(Items)
end.

'clojerl.ISeq.more'(#?TYPE{name = ?M, data = Array} = Vector) ->
case array:size(Array) of
0 -> clj_core:list([]);
_ -> 'clojerl.ISeq.next'(Vector)
end.

'clojerl.Seqable.seq'(#?TYPE{name = ?M, data = Array}) ->
case array:size(Array) of
0 -> undefined;
Expand Down
8 changes: 8 additions & 0 deletions src/lang/collections/clojerl.erlang.List.erl
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
-module('clojerl.erlang.List').

-behavior('clojerl.Counted').
-behavior('clojerl.IColl').
-behavior('clojerl.ISeq').
-behavior('clojerl.ISequential').
-behavior('clojerl.Seqable').
-behavior('clojerl.Stringable').

-export(['clojerl.Counted.count'/1]).
-export([ 'clojerl.IColl.count'/1
, 'clojerl.IColl.cons'/2
, 'clojerl.IColl.empty'/1
Expand All @@ -18,6 +20,12 @@
-export(['clojerl.Seqable.seq'/1]).
-export(['clojerl.Stringable.str'/1]).

%%------------------------------------------------------------------------------
%% Protocols
%%------------------------------------------------------------------------------

'clojerl.Counted.count'(Items) -> length(Items).

'clojerl.Stringable.str'([]) ->
<<"()">>;
'clojerl.Stringable.str'(Items) ->
Expand Down

0 comments on commit e610317

Please sign in to comment.