5. Populist Domain-Specific Programming
Internal DSL
Programmatic encoding
Limited abstraction from implementation strategy
Bound to specific host language
Captures implementation, not understanding
6. Context-free Grammars
"return" Exp ";" -> Stm {"Return"}
Type ID ";" -> Stm {"VarDef"}
Type ID "=" Exp ";" -> Stm {"VarDef"}
ID "=" Exp ";" -> Stm {"Assign"}
"if" "(" Exp ")" Block -> Stm {"If"}
"if" "(" Exp ")" Block "else" Block -> Stm {"IfElse"}
"for" "(" Type ID "=" Exp ";" Exp ";" Stm ")" Block -> Stm {"For"}
"{" Stm* "}" -> Block {"Block"}
Block -> Stm
for (int i = i; i <10 ; i = i + 1;) {
int i;
i = i + 1;
}
Pure and declarative syntax definition: paradise lost and regained. Lennart C. L. Kats, Eelco Visser, Guido Wachsmuth.
Onward 2010: 918-932
7. Fundamentalist Domain-Specific Programming
External DSL
Abstraction from implementation strategy
Not bound to specific host language
Captures understanding
(and room for many implementations)
18. What is the Problem?
Mental model:
Name binding is defined in terms of
programmatic encoding of name resolution
Rules encoded in many language operations
Abstractions try to reduce overhead
of the programmatic encoding
19. Name Binding in Xtext
grammar DomainModel with Terminals
Domainmodel :
elements += Type*
;
Type:
DataType | Entity
;
DataType:
'datatype' name = ID
;
Entity:
'entity' name = ID ('extends' superType = [Entity])? '{'
features += Feature*
'}'
;
Feature:
many?='many'? name = ID ':' type = [Type]
;
21. Definitions and Reference
class C {
Class(_, c, _, _): }
defines Class c
class D {
ClassType(c) : C x;
refers to Class c }
Base(c) : class E : D {
refers to Class c C x;
}
22. Design Choice: Grammar Annotations
"class" Type@=ID "{" ClassBodyDecl* "}" -> Definition {"Class"}
Type@ID -> Type {"ClassType"}
Class(_, c, _) :
defines Class c
ClassType(c) :
refers to Class c
23. Unique and Non-Unique Definitions
class D {
C1 x;
Class(NonPartial(), c, _, _) : }
defines unique Class c class C1 {
D d;
Class(Partial(), c, _, _) : }
defines non-unique Class c class C2: C1 {
Int i;
Base(c) : }
refers to Class c partial class C3: C2 {
Int j;
ClassType(c) : }
refers to Class c partial class C3 {
Int k;
}
24. Namespaces
namespaces
Class Method Field Variable
Class(NonPartial(), c, _, _):
defines unique Class c
Field(_, f) :
class x {
defines unique Field f
int x;
void x() {
Method(_, m, _, _):
int x; x = x + 1;
defines unique Method m
}
Call(m, _) :
}
refers to Method m
VarDef(_, v):
defines unique Variable v
VarRef(x):
refers to Variable x
otherwise refers to Field x
25. Scope
class C {
Class(NonPartial(), c, _, _): int y;
defines unique Class c void m() {
scopes Field, Method int x;
x = y + 1;
Class(Partial(), c, _, _): }
defines non-unique Class c }
scopes Field, Method
class D {
Method(_, m, _, _): void m() {
defines unique Method m int x;
scopes Variable int y;
{ int x; x = y + 1; }
Block(_): x = y + 1;
scopes Variable }
}
26. C# Namespaces are Scopes
namespace N {
class N {}
Namespace(n, _):
namespace N {
defines Namespace n
class N {}
scopes Namespace, Class
}
}
27. Imports
using N;
Using(qn):
imports Class from Namespace ns namespace M {
where qn refers to Namespace ns class C { int f; }
}
Base(c):
imports Field namespace O {
from Class c {transitive} class E: M.C {
imports Method void m() {}
from Class c {transitive} }
class F:E { }
}
28. Definition Context
class C {
Foreach(t, v, exp, body): void m(int[] x) {
defines Variable v foreach (int x in x)
of type t WriteLine(x);
in body }
}
29. Interaction with Type System (1)
class C {
int i;
}
FieldAccess(e, f): class D {
refers to Field f in c C c;
where e has type ClassType(c) int i;
void init() {
i = c.i;
}
}
30. Interaction with Type System (2)
class C {
int i;
int get() { return i; }
Method(t, m, ps, _) :
}
defines Method m of type t
class D {
MethodCall(e, m, _):
C c;
refers to Method m
int i;
of type t in c
void init() {
where e has type ClassType(c)
i = c.get();
}
}
31. Interaction with Type System (3)
Method(t, m, ps, _) : class C {
defines unique Method m void m() {}
of type (ts, t) void m(int x) {}
where ps has type ts void m(bool x) {}
void m(int x, int y) {}
Param(t, p): void m(bool x, bool y) {}
defines unique Variable p void x() {
of type t m();
m(42);
MethodCall(e, m, es): m(true);
refers to Method m m(21, 21);
of type (ts, t) in c m(true, false);
where e has type ClassType(c) }
where es has type ts }
32. Name Binding
class
defines partial class
type
refers inheritance
namespaces
namespace
using
scopes
method
field
imports variable
parameter
block
34. Name Binding Language in Spoofax (*)
derivation of editor services
checking
code completion
reference resolution
multi-file analysis
parallel evaluation
incremental evaluation
(*) alpha; NBL is compiled to Stratego implementation of
name resolution algorithm (ask me for pointers)
35. Outlook
Language definition = CFG + NBD + TS + DS
Single source for
Language reference manual
Efficient (incremental) compiler
Execution engine (interpreter)
Integrated development environment