Last active
September 18, 2017 18:51
-
-
Save vizanto/b200479f43cd6f5568660225ff23a804 to your computer and use it in GitHub Desktop.
WIP: Clojure frontend for Haxe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package hxclj; | |
import hxclj.edn.Parser; | |
import byte.ByteData; | |
class Main { | |
static function main() { | |
var expr = "^:yo clojure.core// (.lol wut) .1 (+ 0N 0.1M 0xdeadbeef 1 2 ~a ~@aas)"; | |
// trace("Parse ", expr); | |
var input = sys.io.File.getBytes("test.clj"); | |
var parser = new Parser(@:privateAccess new ByteData(input), "test.clj"); | |
parser.read(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package hxclj.edn; | |
import hxparse.Parser.parse as parse; | |
import haxe.io.Input; | |
private enum Token { | |
TBCurlyOpen; // { | |
TBCurlyClose; // } | |
TBRoundOpen; // ( | |
TBRoundClose; // ) | |
TBSquareOpen; // [ | |
TBSquareClose; // ] | |
TCharacter(v:String); // \ | |
TComment(v:String); // ; | |
TDispatch; // # | |
TMetadata; // ^ | |
TInteger(v:String); | |
TRatio(v:String); | |
TFloat(v:String); | |
TNil; | |
TTrue; | |
TFalse; | |
TQuote; // ' | |
TSyntaxQuote; // ` | |
TUnQuote; // ~ | |
TUnQuoteSplice; // ~@ | |
TString(v:String); // " | |
TKeyword(v:String); // :TSymbol | |
TSymbol(v:String); // A-z 0-9, *, +, !, -, _, ', ?, /, and non-repeating : | |
TWhitespace(v:String); // , space etc | |
TEof; | |
} | |
/* | |
See: https://clojure.org/reference/reader | |
https://github.com/clojure/tools.reader/blob/master/src/main/clojure/clojure/tools/reader.clj | |
https://github.com/Simn/hxparse/blob/master/test/JSONParser.hx | |
*/ | |
class CljLexer extends hxparse.Lexer implements hxparse.RuleBuilder | |
{ | |
static var intPattern = ~/^([-+]?)(?:(0)|([1-9][0-9]*)|0[xX]([0-9A-Fa-f]+)|0([0-7]+)|([1-9][0-9]?)[rR]([0-9A-Za-z]+)|0[0-9]+)(N)?$/; | |
static var ratioPattern = ~/^([-+]?[0-9]+)\/([0-9]+)$/; | |
static var floatPattern = ~/^([-+]?[0-9]+(\.[0-9]*)?([eE][-+]?[0-9]+)?)M?$/; | |
public static var tok = @:rule [ | |
"\\{" => TBCurlyOpen, | |
"\\}" => TBCurlyClose, | |
"\\(" => TBRoundOpen, | |
"\\)" => TBRoundClose, | |
"\\[" => TBSquareOpen, | |
"\\]" => TBSquareClose, | |
"\\\\([^ ,\r\n\t]+|[ \r\n])" => { | |
var v = lexer.current; | |
if (v.length == 2 || ~/^\\(newline|space|tab|formfeed|backspace|return|u[0-9A-Fa-f]+)$/.match(v)) | |
TCharacter(v); | |
else throw 'Unsupported character: "${v}"'; | |
}, | |
";[^\r\n]*" => TComment(lexer.current), | |
"#" => TDispatch, | |
"^" => TMetadata, | |
"[-+]?[0-9]+[0-9xXA-Fa-feErRMN.]*" => { | |
var v = lexer.current; | |
if ( intPattern.match(v)) TInteger(v); | |
else if (ratioPattern.match(v)) TRatio(v); | |
else if (floatPattern.match(v)) TFloat(v); | |
else throw "Invalid number: " + v; | |
}, | |
'nil' => TNil, | |
'true' => TTrue, | |
'false' => TFalse, | |
"'" => TQuote, | |
'`' => TSyntaxQuote, | |
'~' => TUnQuote, | |
'~@' => TUnQuoteSplice, | |
'"' => { | |
buf = new StringBuf(); | |
lexer.token(string); | |
TString(buf.toString()); | |
}, | |
':[^ ,\r\n\t";@^`~()\\[\\]{}\\\\]+' => TKeyword(lexer.current), // ':[-a-zA-Z*+!_\'?/.][-0-9a-zA-Z*+!_\'?/.]*' | |
'[^ ,\r\n\t";@^`~()\\[\\]{}\\\\]+' => TSymbol(lexer.current), // '[-a-zA-Z*+!_\'?/.][-0-9a-zA-Z*+!_\'?/.]*' | |
"[ ,\r\n\t]+" => cast(lexer, CljLexer).handleWhitespace(), | |
"" => TEof | |
]; | |
function handleWhitespace() { | |
return if (false) TWhitespace(current); else token(tok); | |
} | |
static var buf:StringBuf; | |
public static var string = @:rule [ | |
'\\\\"' => { | |
buf.add(lexer.current); | |
lexer.token(string); | |
}, | |
'\\\\' => { | |
buf.addChar('\\'.code); | |
lexer.token(string); | |
}, | |
'"' => { | |
lexer.curPos().pmax; | |
}, | |
'[^\\\\"]+' => { | |
buf.add(lexer.current); | |
lexer.token(string); | |
}, | |
]; | |
} | |
class Parser extends hxparse.Parser<hxparse.LexerTokenSource<Token>, Token> | |
{ | |
public function new(input:byte.ByteData, sourceName:String) { | |
var lexer = new CljLexer(input, sourceName); | |
var ts = new hxparse.LexerTokenSource(lexer, CljLexer.tok); | |
super(ts); | |
} | |
public function read() { | |
var token = null; | |
while ((token = stream.token()) != TEof) trace(token); | |
// return parse(switch stream { | |
// case t: trace(t); | |
// }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment