Step 0 of Make-a-Lisp for Erlang
authorNathan Fiedler <nathanfiedler@fastmail.fm>
Sun, 15 Mar 2015 14:13:47 +0000 (07:13 -0700)
committerNathan Fiedler <nathanfiedler@fastmail.fm>
Sat, 4 Apr 2015 15:59:16 +0000 (08:59 -0700)
Requires rebar to build.

make test^erlang^step0 passes

.gitignore
Makefile
README.md
erlang/Makefile [new file with mode: 0644]
erlang/rebar.config [new file with mode: 0644]
erlang/rebar.config.script [new file with mode: 0644]
erlang/src/env.erl [new file with mode: 0644]
erlang/src/mal.app.src [new file with mode: 0644]
erlang/src/step0_repl.erl [new file with mode: 0644]

index cb3427d..59f6605 100644 (file)
@@ -25,6 +25,9 @@ cs/*.dll
 cs/*.mdb
 clojure/target
 clojure/.lein-repl-history
+erlang/ebin
+erlang/.rebar
+erlang/src/*.beam
 go/step*
 go/mal
 java/target/
index 63c8d06..e4b441d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ PYTHON = python
 # Settings
 #
 
-IMPLS = bash c clojure coffee cpp cs factor forth go haskell java \
+IMPLS = bash c clojure coffee cpp cs erlang factor forth go haskell java \
        julia js lua make mal ocaml matlab miniMAL nim perl php ps \
        python r racket ruby rust scala swift vb
 
@@ -57,6 +57,7 @@ clojure_STEP_TO_PROG = clojure/src/$($(1)).clj
 coffee_STEP_TO_PROG =  coffee/$($(1)).coffee
 cpp_STEP_TO_PROG =     cpp/$($(1))
 cs_STEP_TO_PROG =      cs/$($(1)).exe
+erlang_STEP_TO_PROG =  erlang/$($(1))
 factor_STEP_TO_PROG =  factor/src/$($(1))/$($(1)).factor
 forth_STEP_TO_PROG =   forth/$($(1)).fs
 go_STEP_TO_PROG =      go/$($(1))
@@ -95,6 +96,7 @@ clojure_RUNSTEP = lein with-profile +$(1) trampoline run $(3)
 coffee_RUNSTEP =  coffee ../$(2) $(3)
 cpp_RUNSTEP =     ../$(2) $(3)
 cs_RUNSTEP =      mono ../$(2) --raw $(3)
+erlang_RUNSTEP =  ../$(2) $(3)
 factor_RUNSTEP =  factor ../$(2) $(3)
 forth_RUNSTEP =   gforth ../$(2) $(3)
 go_RUNSTEP =      ../$(2) $(3)
@@ -211,4 +213,3 @@ $(IMPL_PERF):
           $(call $(impl)_RUNSTEP,stepA,$(call $(impl)_STEP_TO_PROG,stepA),../tests/perf2.mal); \
          echo 'Running: $(call $(impl)_RUNSTEP,stepA,$(call $(impl)_STEP_TO_PROG,stepA),../tests/perf3.mal)'; \
           $(call $(impl)_RUNSTEP,stepA,$(call $(impl)_STEP_TO_PROG,stepA),../tests/perf3.mal))
-
index 71344fa..7b71d40 100644 (file)
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
 
 Mal is a Clojure inspired Lisp interpreter.
 
-Mal is implemented in 31 different languages:
+Mal is implemented in 32 different languages:
 
 * Bash shell
 * C
@@ -12,6 +12,7 @@ Mal is implemented in 31 different languages:
 * C#
 * Clojure
 * CoffeeScript
+* Erlang
 * Factor
 * Forth
 * Go
@@ -136,6 +137,16 @@ cd coffee
 coffee ./stepX_YYY
 ```
 
+### Erlang
+
+Requires [rebar](https://github.com/rebar/rebar) to build.
+
+```
+cd erlang
+MAL_STEP=stepX_YYY rebar compile escriptize
+./stepX_YYY
+```
+
 ### Factor
 
 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
diff --git a/erlang/Makefile b/erlang/Makefile
new file mode 100644 (file)
index 0000000..4de7497
--- /dev/null
@@ -0,0 +1,34 @@
+#####################
+
+SOURCES_BASE = src/step0_repl.erl
+SOURCES_LISP = src/env.erl
+SOURCES = $(SOURCES_BASE) $(word $(words $(SOURCES_LISP)),${SOURCES_LISP})
+
+#####################
+
+SRCS = step0_repl.erl
+BINS = $(SRCS:%.erl=%)
+
+#####################
+
+all: $(BINS) mal
+
+mal: $(word $(words $(BINS)),$(BINS))
+       cp $< $@
+
+define dep_template
+$(1): $(SOURCES_BASE) src/$(1).erl
+       MAL_STEP=$(1) rebar compile escriptize
+endef
+
+$(foreach b,$(BINS),$(eval $(call dep_template,$(b))))
+
+clean:
+       rm -f $(BINS) mal
+
+.PHONY: stats stats-lisp
+
+stats: $(SOURCES)
+       @wc $^
+stats-lisp: $(SOURCES_LISP)
+       @wc $^
diff --git a/erlang/rebar.config b/erlang/rebar.config
new file mode 100644 (file)
index 0000000..cbd11c8
--- /dev/null
@@ -0,0 +1,13 @@
+%%
+%% rebar configuration file (https://github.com/rebar/rebar)
+%%
+
+{require_otp_vsn, "17"}.
+
+{erl_opts, [debug_info, fail_on_warning]}.
+
+{clean_files, [
+    "ebin",
+    "src/*.beam",
+    "step0_repl"
+]}.
diff --git a/erlang/rebar.config.script b/erlang/rebar.config.script
new file mode 100644 (file)
index 0000000..c20ba33
--- /dev/null
@@ -0,0 +1,10 @@
+%%
+%% rebar dynamic configuration file
+%% (https://github.com/rebar/rebar/wiki/Dynamic-configuration)
+%%
+
+case os:getenv("MAL_STEP") of
+    false -> CONFIG; % env var not defined
+    []    -> CONFIG; % env var set to empty string
+    Step  -> CONFIG ++ [{escript_name, Step}]
+end.
diff --git a/erlang/src/env.erl b/erlang/src/env.erl
new file mode 100644 (file)
index 0000000..511ada4
--- /dev/null
@@ -0,0 +1,25 @@
+%%%
+%%% Environement
+%%%
+
+-module(env).
+
+-export([env_new/1, env_bind/3, env_find/2, env_root/1, env_set/3, env_get/2]).
+
+env_new(_Outer) ->
+       ok.
+
+env_bind(_Env, _Bindings, _Exprs) ->
+       ok.
+
+env_find(_Env, _Key) ->
+       ok.
+
+env_root(_Env) ->
+       ok.
+
+env_set(_Env, _Key, _Value) ->
+       ok.
+
+env_get(_Env, _Key) ->
+       ok.
diff --git a/erlang/src/mal.app.src b/erlang/src/mal.app.src
new file mode 100644 (file)
index 0000000..11d54c1
--- /dev/null
@@ -0,0 +1,11 @@
+{application, mal, [
+    {description, "Make-a-Lisp Erlang"},
+    {vsn, "1"},
+    {registered, []},
+    {applications, [
+        kernel,
+        stdlib
+    ]},
+    {mod, {mal_app, []}},
+    {env, []}
+]}.
diff --git a/erlang/src/step0_repl.erl b/erlang/src/step0_repl.erl
new file mode 100644 (file)
index 0000000..54644cf
--- /dev/null
@@ -0,0 +1,30 @@
+%%%
+%%% Step 0: REPL
+%%%
+
+-module(step0_repl).
+
+-export([main/1]).
+
+main(_) ->
+    case io:get_line(standard_io, "user> ") of
+        eof ->
+            % break out of the loop
+            io:format("~n"),
+            ok;
+        {error, Reason} ->
+            io:format("Error reading input: ~p~n", [Reason]),
+            exit(ioerr);
+        Line ->
+            io:format("~s~n", [print(eval(read(string:strip(Line, both, $\n))))]),
+            main("")
+    end.
+
+read(String) ->
+    String.
+
+eval(String) ->
+    String.
+
+print(String) ->
+    String.