mirror of
https://github.com/kanaka/mal.git
synced 2024-09-20 01:57:09 +03:00
Haxe: step0 and step1.
This commit is contained in:
parent
b1fef5d72a
commit
6c4c14bd8a
9
Makefile
9
Makefile
@ -22,9 +22,10 @@ mal_TEST_OPTS = --start-timeout 60 --test-timeout 120
|
||||
# Settings
|
||||
#
|
||||
|
||||
IMPLS = awk bash c d clojure coffee cpp crystal cs erlang elixir es6 factor forth fsharp go groovy \
|
||||
guile haskell java julia js kotlin lua make mal ocaml matlab miniMAL nim \
|
||||
perl php ps python r racket rpython ruby rust scala swift tcl vb vimscript
|
||||
IMPLS = awk bash c d clojure coffee cpp crystal cs erlang elixir es6 \
|
||||
factor forth fsharp go groovy guile haskell haxe java julia \
|
||||
js kotlin lua make mal ocaml matlab miniMAL nim perl php ps \
|
||||
python r racket rpython ruby rust scala swift tcl vb vimscript
|
||||
|
||||
step0 = step0_repl
|
||||
step1 = step1_read_print
|
||||
@ -112,6 +113,7 @@ go_STEP_TO_PROG = go/$($(1))
|
||||
groovy_STEP_TO_PROG = groovy/$($(1)).groovy
|
||||
java_STEP_TO_PROG = java/src/main/java/mal/$($(1)).java
|
||||
haskell_STEP_TO_PROG = haskell/$($(1))
|
||||
haxe_STEP_TO_PROG = haxe/$($(1)).py
|
||||
julia_STEP_TO_PROG = julia/$($(1)).jl
|
||||
js_STEP_TO_PROG = js/$($(1)).js
|
||||
kotlin_STEP_TO_PROG = kotlin/$($(1)).jar
|
||||
@ -167,6 +169,7 @@ fsharp_RUNSTEP = mono ../$(2) --raw $(3)
|
||||
go_RUNSTEP = ../$(2) $(3)
|
||||
groovy_RUNSTEP = groovy ../$(2) $(3)
|
||||
haskell_RUNSTEP = ../$(2) $(3)
|
||||
haxe_RUNSTEP = python3 ../$(2) $(3)
|
||||
java_RUNSTEP = mvn -quiet exec:java -Dexec.mainClass="mal.$($(1))" $(if $(3), -Dexec.args="$(3)",)
|
||||
julia_RUNSTEP = ../$(2) $(3)
|
||||
js_RUNSTEP = node ../$(2) $(3)
|
||||
|
33
haxe/Dockerfile
Normal file
33
haxe/Dockerfile
Normal file
@ -0,0 +1,33 @@
|
||||
FROM ubuntu:vivid
|
||||
MAINTAINER Joel Martin <github@martintribe.org>
|
||||
|
||||
##########################################################
|
||||
# General requirements for testing or common across many
|
||||
# implementations
|
||||
##########################################################
|
||||
|
||||
RUN apt-get -y update
|
||||
|
||||
# Required for running tests
|
||||
RUN apt-get -y install make python
|
||||
|
||||
# Some typical implementation and test requirements
|
||||
RUN apt-get -y install curl libreadline-dev libedit-dev
|
||||
|
||||
RUN mkdir -p /mal
|
||||
WORKDIR /mal
|
||||
|
||||
##########################################################
|
||||
# Specific implementation requirements
|
||||
##########################################################
|
||||
|
||||
# Install Haxe
|
||||
RUN apt-get -y install software-properties-common && \
|
||||
add-apt-repository -y ppa:haxe/releases && \
|
||||
apt-get -y update
|
||||
RUN apt-get install -y haxe && \
|
||||
mkdir /root/haxelib && haxelib setup /root/haxelib
|
||||
|
||||
# Install support for C++ compilation
|
||||
RUN apt-get -y install g++
|
||||
RUN haxelib install hxcpp
|
8
haxe/Makefile
Normal file
8
haxe/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# Python step rules
|
||||
s%.py: S%.hx
|
||||
haxe -main $(patsubst %.hx,%,$<) -python $@
|
||||
|
||||
step1_read_print.py: types/Types.hx reader/Reader.hx printer/Printer.hx
|
||||
|
||||
clean:
|
||||
rm -r *.py
|
38
haxe/Step0_repl.hx
Normal file
38
haxe/Step0_repl.hx
Normal file
@ -0,0 +1,38 @@
|
||||
class Step0_repl {
|
||||
// READ
|
||||
static function READ(str:String) {
|
||||
return str;
|
||||
}
|
||||
|
||||
// EVAL
|
||||
static function EVAL(ast:String, env:String) {
|
||||
return ast;
|
||||
}
|
||||
|
||||
// PRINT
|
||||
static function PRINT(exp:String) {
|
||||
return exp;
|
||||
}
|
||||
|
||||
// repl
|
||||
static function rep(line:String) {
|
||||
return PRINT(EVAL(READ(line), ""));
|
||||
}
|
||||
|
||||
public static function main() {
|
||||
#if js
|
||||
#error "JS not supported yet"
|
||||
#end
|
||||
while (true) {
|
||||
try {
|
||||
Sys.print("user> ");
|
||||
var line = Sys.stdin().readLine();
|
||||
Sys.println(rep(line));
|
||||
} catch (exc:haxe.io.Eof) {
|
||||
Sys.exit(0);
|
||||
} catch (exc:Dynamic) {
|
||||
Sys.println(exc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
45
haxe/Step1_read_print.hx
Normal file
45
haxe/Step1_read_print.hx
Normal file
@ -0,0 +1,45 @@
|
||||
import types.Types.MalType;
|
||||
import reader.*;
|
||||
import printer.*;
|
||||
|
||||
class Step1_read_print {
|
||||
// READ
|
||||
static function READ(str:String):MalType {
|
||||
return Reader.read_str(str);
|
||||
}
|
||||
|
||||
// EVAL
|
||||
static function EVAL(ast:MalType, env:String) {
|
||||
return ast;
|
||||
}
|
||||
|
||||
// PRINT
|
||||
static function PRINT(exp:MalType):String {
|
||||
return Printer.pr_str(exp, true);
|
||||
}
|
||||
|
||||
// repl
|
||||
static function rep(line:String) {
|
||||
return PRINT(EVAL(READ(line), ""));
|
||||
}
|
||||
|
||||
public static function main() {
|
||||
#if js
|
||||
#error "JS not supported yet"
|
||||
#end
|
||||
while (true) {
|
||||
try {
|
||||
Sys.print("user> ");
|
||||
var line = Sys.stdin().readLine();
|
||||
if (line == "") { continue; }
|
||||
Sys.println(rep(line));
|
||||
} catch (exc:BlankLine) {
|
||||
continue;
|
||||
} catch (exc:haxe.io.Eof) {
|
||||
Sys.exit(0);
|
||||
} catch (exc:Dynamic) {
|
||||
Sys.println(exc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
haxe/printer/Printer.hx
Normal file
30
haxe/printer/Printer.hx
Normal file
@ -0,0 +1,30 @@
|
||||
package printer;
|
||||
|
||||
import types.Types.MalType;
|
||||
import types.Types.MalType.*;
|
||||
|
||||
class Printer {
|
||||
public static function pr_str(exp:MalType, print_readably:Bool = true) {
|
||||
var _r = print_readably;
|
||||
return switch(exp) {
|
||||
case MalNil: "nil";
|
||||
case MalTrue: "true";
|
||||
case MalFalse: "false";
|
||||
case MalInt(v): Std.string(v);
|
||||
case MalString(v):
|
||||
if (_r) {
|
||||
'"' + v + '"';
|
||||
} else {
|
||||
v;
|
||||
}
|
||||
case MalSymbol(v): Std.string(v);
|
||||
case MalList(l):
|
||||
var lst = l.map(function(e) {return pr_str(e,_r);});
|
||||
"(" + lst.join(" ") + ")";
|
||||
case MalVector(l):
|
||||
var lst = l.map(function(e) {return pr_str(e,_r);});
|
||||
"[" + lst.join(" ") + "]";
|
||||
case _: throw "unknown type for printing";
|
||||
}
|
||||
}
|
||||
}
|
6
haxe/reader/BlankLine.hx
Normal file
6
haxe/reader/BlankLine.hx
Normal file
@ -0,0 +1,6 @@
|
||||
package reader;
|
||||
|
||||
class BlankLine {
|
||||
public function new() {
|
||||
}
|
||||
}
|
112
haxe/reader/Reader.hx
Normal file
112
haxe/reader/Reader.hx
Normal file
@ -0,0 +1,112 @@
|
||||
package reader;
|
||||
|
||||
import types.Types.MalType;
|
||||
import types.Types.MalType.*;
|
||||
|
||||
class Reader {
|
||||
// Reader class implementation
|
||||
var tokens:Array<String>;
|
||||
var position:Int = 0;
|
||||
|
||||
public function new(toks:Array<String>) {
|
||||
tokens = toks;
|
||||
}
|
||||
|
||||
public function next() {
|
||||
return tokens[position++];
|
||||
}
|
||||
|
||||
public function peek() {
|
||||
if (tokens.length > position) {
|
||||
return tokens[position];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Static functions grouped with Reader class
|
||||
static function tokenize(str:String) {
|
||||
var re = ~/[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"`,;)]*)/g;
|
||||
var tokens = new Array<String>();
|
||||
var pos = 0;
|
||||
while (re.matchSub(str, pos)) {
|
||||
var t = re.matched(1);
|
||||
if (t == "" || t.charAt(0) == ";") { break; }
|
||||
tokens.push(t);
|
||||
var pos_len = re.matchedPos();
|
||||
pos = pos_len.pos + pos_len.len;
|
||||
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
static function read_atom(rdr:Reader) {
|
||||
var re_int = ~/^[0-9]*$/;
|
||||
var re_str = ~/^".*"$/;
|
||||
var token = rdr.next();
|
||||
return switch (token) {
|
||||
case "nil":
|
||||
MalNil;
|
||||
case "true":
|
||||
MalTrue;
|
||||
case "false":
|
||||
MalFalse;
|
||||
case _ if (re_int.match(token)):
|
||||
MalInt(Std.parseInt(token));
|
||||
case _ if (re_str.match(token)):
|
||||
MalString(token.substr(1, token.length-2));
|
||||
case _:
|
||||
MalSymbol(token);
|
||||
}
|
||||
}
|
||||
|
||||
static function read_seq(rdr:Reader, start, end) {
|
||||
var lst = [];
|
||||
var token = rdr.next();
|
||||
if (token != start) {
|
||||
throw "expected '$start'";
|
||||
}
|
||||
while ((token = rdr.peek()) != end) {
|
||||
if (token == null) {
|
||||
throw "expected '$end', got EOF";
|
||||
}
|
||||
lst.push(read_form(rdr));
|
||||
}
|
||||
rdr.next();
|
||||
return lst;
|
||||
}
|
||||
|
||||
static function read_form(rdr:Reader):MalType {
|
||||
var token = rdr.peek();
|
||||
return switch (token) {
|
||||
// reader macros/transforms
|
||||
case "'": rdr.next();
|
||||
MalList([MalSymbol("quote"), read_form(rdr)]);
|
||||
case "`": rdr.next();
|
||||
MalList([MalSymbol("quasiquote"), read_form(rdr)]);
|
||||
case "~": rdr.next();
|
||||
MalList([MalSymbol("unquote"), read_form(rdr)]);
|
||||
case "~@": rdr.next();
|
||||
MalList([MalSymbol("splice-unquote"), read_form(rdr)]);
|
||||
case "^": rdr.next();
|
||||
var meta = read_form(rdr);
|
||||
MalList([MalSymbol("with-meta"), read_form(rdr), meta]);
|
||||
case "@": rdr.next();
|
||||
MalList([MalSymbol("deref"), read_form(rdr)]);
|
||||
|
||||
// list
|
||||
case ")": throw("unexpected ')'");
|
||||
case "(": MalList(read_seq(rdr, '(', ')'));
|
||||
case "]": throw("unexpected ']'");
|
||||
case "[": MalVector(read_seq(rdr, '[', ']'));
|
||||
case _: read_atom(rdr);
|
||||
}
|
||||
}
|
||||
|
||||
public static function read_str(str:String):MalType {
|
||||
var tokens = tokenize(str);
|
||||
if (tokens.length == 0) { throw(new BlankLine()); }
|
||||
return read_form(new Reader(tokens));
|
||||
}
|
||||
}
|
19
haxe/types/Types.hx
Normal file
19
haxe/types/Types.hx
Normal file
@ -0,0 +1,19 @@
|
||||
package types;
|
||||
|
||||
enum MalType {
|
||||
MalNil;
|
||||
MalTrue;
|
||||
MalFalse;
|
||||
MalInt(val:Int);
|
||||
MalString(val:String);
|
||||
MalSymbol(val:String);
|
||||
MalList(val:Array<MalType>);
|
||||
MalVector(val:Array<MalType>);
|
||||
}
|
||||
|
||||
class Types {
|
||||
public static function hello() {
|
||||
trace("hello world");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user