Created
March 2, 2012 16:19
-
-
Save dobesv/1959419 to your computer and use it in GitHub Desktop.
Changes I made to the Fantom compiler module to make it easier to create my DSL
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
using compiler | |
class CoroutineDslPlugin : DslPlugin | |
{ | |
new make(Compiler c) : super(c) {} | |
override Expr compile(DslExpr dsl) | |
{ | |
src := dsl.src | |
loc := dsl.srcLoc | |
unit := CompilationUnit(loc, pod) | |
tokenizer := Tokenizer(compiler, loc, "{ $src }", compiler.input.includeDoc) | |
unit.tokens = tokenizer.tokenize | |
// Clone imports from the current unit | |
parentUnit := units.find |u| { return u.loc.file == loc.file } | |
unit.importedTypes = parentUnit.importedTypes | |
tmpClassDef := unit.types.first | |
//unit.types.add(tmpClassDef); | |
parser := Parser(compiler, unit, compiler.closures) { | |
curType = dsl.enclosingType | |
curSlot = dsl.enclosingSlot | |
curClosure = dsl.enclosingClosure | |
closureCount = this.compiler.closures.size | |
} | |
try { | |
FuncType signature := FuncType([,], [,], ns.resolveType("sys::Void")) | |
ClosureExpr closure := parser.closure(loc, signature) | |
// TODO Here is where we would transform it to support | |
InitClosures(compiler).process(closure) | |
Normalize(compiler).visitTypeDef(closure.cls) | |
closure.cls.dump | |
return closure | |
} catch (sys::NullErr e) | |
{ | |
echo(e) | |
e.trace | |
throw err("Null pointer exception during parse!", loc); | |
} | |
} | |
} |
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
using sys::Test | |
using coroutine | |
class CoroutineTest : Test | |
{ | |
Void testSimpleEcho() { | |
x := Coroutine<| echo("This is a test!") |> | |
x() | |
} | |
Void testSimpleEchoReturn() { | |
// Just making sure we haven't messed up the return statement support somehow | |
x := Coroutine<| echo("This is a test!"); return |> | |
x() | |
} | |
Void testEnclosedVar1() { | |
i := 1 | |
x := Coroutine<| echo("$i"); i++ |> | |
x() | |
x() | |
} | |
Void testEnclosedVar2() { | |
i := 1 | |
x := Coroutine<| i++ |> | |
x() | |
x() | |
echo("x == $x") | |
} | |
} |
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
diff --git a/src/compiler/fan/ast/Expr.fan b/src/compiler/fan/ast/Expr.fan | |
--- a/src/compiler/fan/ast/Expr.fan | |
+++ b/src/compiler/fan/ast/Expr.fan | |
@@ -1590,12 +1590,16 @@ | |
** | |
class DslExpr : Expr | |
{ | |
- new make(Loc loc, CType anchorType, Loc srcLoc, Str src) | |
+ new make(Loc loc, CType anchorType, Loc srcLoc, TypeDef enclosingType, | |
+ SlotDef enclosingSlot, ClosureExpr? enclosingClosure, Str src) | |
: super(loc, ExprId.dsl) | |
{ | |
this.anchorType = anchorType | |
this.src = src | |
this.srcLoc = srcLoc | |
+ this.enclosingType = enclosingType; | |
+ this.enclosingSlot = enclosingSlot; | |
+ this.enclosingClosure = enclosingClosure; | |
} | |
override Str toStr() | |
@@ -1613,6 +1617,9 @@ | |
Loc srcLoc // location of first char of src | |
Int leadingTabs // number of leading tabs on original Fantom line | |
Int leadingSpaces // number of leading non-tab chars on original Fantom line | |
+ TypeDef enclosingType // enclosing class | |
+ SlotDef enclosingSlot // enclosing method or field initializer | |
+ ClosureExpr? enclosingClosure // if inside a closure | |
} | |
************************************************************************** | |
diff --git a/src/compiler/fan/parser/Parser.fan b/src/compiler/fan/parser/Parser.fan | |
--- a/src/compiler/fan/parser/Parser.fan | |
+++ b/src/compiler/fan/parser/Parser.fan | |
@@ -1581,7 +1581,7 @@ | |
{ | |
srcLoc := Loc(cur.file, cur.line, cur.col+2) | |
dslVal := cur as TokenValDsl | |
- return DslExpr(loc, ctype, srcLoc, consume.val) | |
+ return DslExpr(loc, ctype, srcLoc, curType, curSlot, curClosure, consume.val) | |
{ | |
leadingTabs = dslVal.leadingTabs | |
leadingSpaces = dslVal.leadingSpaces | |
@@ -1997,7 +1997,7 @@ | |
** | |
** Parse body of closure expression and return ClosureExpr. | |
** | |
- private ClosureExpr closure(Loc loc, FuncType funcType) | |
+ public ClosureExpr closure(Loc loc, FuncType funcType) | |
{ | |
if (curSlot == null) throw err("Unexpected closure") | |
@@ -2426,10 +2426,10 @@ | |
private TokenVal? peek // next token | |
private Token? peekt // next token type | |
private Bool inFieldInit // are we currently in a field initializer | |
- private TypeDef? curType // current TypeDef scope | |
- private SlotDef? curSlot // current SlotDef scope | |
- private ClosureExpr? curClosure // current ClosureExpr if inside closure | |
- private Int? closureCount // number of closures parsed inside curSlot | |
+ TypeDef? curType // current TypeDef scope | |
+ SlotDef? curSlot // current SlotDef scope | |
+ ClosureExpr? curClosure // current ClosureExpr if inside closure | |
+ Int? closureCount // number of closures parsed inside curSlot | |
private ClosureExpr[] closures // list of all closures parsed | |
} | |
\ No newline at end of file | |
diff --git a/src/compiler/fan/steps/InitClosures.fan b/src/compiler/fan/steps/InitClosures.fan | |
--- a/src/compiler/fan/steps/InitClosures.fan | |
+++ b/src/compiler/fan/steps/InitClosures.fan | |
@@ -39,7 +39,7 @@ | |
// Process | |
////////////////////////////////////////////////////////////////////////// | |
- private Void process(ClosureExpr c) | |
+ Void process(ClosureExpr c) | |
{ | |
// class Class$Method$Num : |A,B..->R| | |
// { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment