Unified KissState

This commit is contained in:
2020-11-15 11:07:07 -07:00
parent ac6c50a845
commit 8b7c018a4d

View File

@@ -8,6 +8,13 @@ import kiss.FieldForms;
import kiss.SpecialForms; import kiss.SpecialForms;
import kiss.Macros; import kiss.Macros;
typedef KissState = {
readTable:Map<String, ReadFunction>,
fieldForms:Map<String, FieldFormFunction>,
specialForms:Map<String, SpecialFormFunction>,
macros:Map<String, MacroFunction>
};
class Kiss { class Kiss {
/** /**
Build a Haxe class from a corresponding .kiss file Build a Haxe class from a corresponding .kiss file
@@ -17,24 +24,26 @@ class Kiss {
var stream = new Stream(kissFile); var stream = new Stream(kissFile);
var readTable = Reader.builtins(); var k = {
var fieldForms = FieldForms.builtins(); readTable: Reader.builtins(),
var specialForms = SpecialForms.builtins(); fieldForms: FieldForms.builtins(),
var macros = Macros.builtins(); specialForms: SpecialForms.builtins(),
macros: Macros.builtins()
};
while (true) { while (true) {
stream.dropWhitespace(); stream.dropWhitespace();
if (stream.isEmpty()) if (stream.isEmpty())
break; break;
var position = stream.position(); var position = stream.position();
var nextExp = Reader.read(stream, readTable); var nextExp = Reader.read(stream, k.readTable);
#if test #if test
trace(nextExp); trace(nextExp);
#end #end
// The last expression might be a comment, in which case None will be returned // The last expression might be a comment, in which case None will be returned
switch (nextExp) { switch (nextExp) {
case Some(nextExp): case Some(nextExp):
classFields.push(readerExpToField(nextExp, position, fieldForms, macros, specialForms)); classFields.push(readerExpToField(nextExp, position, k));
case None: case None:
stream.dropWhitespace(); // If there was a comment, drop whitespace that comes after stream.dropWhitespace(); // If there was a comment, drop whitespace that comes after
} }
@@ -43,19 +52,22 @@ class Kiss {
return classFields; return classFields;
} }
static function readerExpToField(exp:ReaderExp, position:String, fieldForms:Map<String, FieldFormFunction>, macros:Map<String, MacroFunction>, static function readerExpToField(exp:ReaderExp, position:String, k:KissState):Field {
specialForms:Map<String, SpecialFormFunction>):Field { var fieldForms = k.fieldForms;
return switch (exp) { return switch (exp) {
case CallExp(Symbol(formName), args) if (fieldForms.exists(formName)): case CallExp(Symbol(formName), args) if (fieldForms.exists(formName)):
fieldForms[formName](position, args, readerExpToHaxeExpr.bind(_, macros, specialForms)); fieldForms[formName](position, args, readerExpToHaxeExpr.bind(_, k));
default: default:
throw '$exp at $position is not a valid field form'; throw '$exp at $position is not a valid field form';
}; };
} }
static function readerExpToHaxeExpr(exp:ReaderExp, macros:Map<String, MacroFunction>, specialForms:Map<String, SpecialFormFunction>):Expr { static function readerExpToHaxeExpr(exp:ReaderExp, k:KissState):Expr {
var macros = k.macros;
var specialForms = k.specialForms;
// Bind the table arguments of this function for easy recursive calling/passing // Bind the table arguments of this function for easy recursive calling/passing
var convert = readerExpToHaxeExpr.bind(_, macros, specialForms); var convert = readerExpToHaxeExpr.bind(_, k);
var expr = switch (exp) { var expr = switch (exp) {
case Symbol(name): case Symbol(name):
Context.parse(name, Context.currentPos()); Context.parse(name, Context.currentPos());
@@ -71,7 +83,7 @@ class Kiss {
case CallExp(func, body): case CallExp(func, body):
{ {
pos: Context.currentPos(), pos: Context.currentPos(),
expr: ECall(readerExpToHaxeExpr(func, macros, specialForms), [for (bodyExp in body) readerExpToHaxeExpr(bodyExp, macros, specialForms)]) expr: ECall(convert(func), [for (bodyExp in body) convert(bodyExp)])
}; };
case ListExp(elements): case ListExp(elements):
{ {