Contenu connexe Similaire à Grammarware Memes (20) Plus de Eelco Visser (20) Grammarware Memes4. WebDSL Web Programming Language
define page post(p: Post, title: String) {
init{ p.update(); }
title{ output(p.title) }
bloglayout(p.blog){
placeholder view { postView(p) }
postComments(p)
}
}
define ajax postView(p: Post) {
pageHeader2{ output(p.title) }
postBodyLayout(p) {
postContent(p)
postExtendedContent(p)
postActions(p)
}
}
14. X-ware is a Memeplex
memeplex: selection of memes from the meme pool
16. Grammarware is about
(Parsing) Text
module users
imports library
entity User {
email : String
password : String
isAdmin : Bool
}
18. Grammarware is about
Structure
Module(
"users"
, [ Imports("library")
, Entity(
"User"
, [ Property("email", Type("String"))
, Property("password", Type("String"))
, Property("isAdmin", Type("Bool"))
]
)
]
)
25. EnFun: Entities with Functions
module blog
entity String {
function plus(that:String): String
}
entity Bool { }
entity Set<T> {
function add(x: T)
function remove(x: T)
function member(x: T): Bool
}
entity Blog {
posts : Set<Post>
function newPost(): Post {
var p : Post := Post.new();
posts.add(p);
}
}
entity Post {
title : String
}
27. Signature & Terms
constructors
Module : ID * List(Definition) -> Module
Imports : ID -> Definition
Module(
"application"
, [Imports("library"),
Imports("users"),
Imports("frontend")]
)
28. Entities & Properties
constructors
Entity : ID * List(Property) -> Definition
Type : ID -> Type
New : Type -> Exp
constructors
Property : ID * Type -> Property
This : Exp
PropAccess : Exp * ID -> Exp
Module("users"
, [ Imports("library")
, Entity("User"
, [ Property("email", Type("String"))
, Property("password", Type("String"))
, Property("isAdmin", Type("Bool"))])])
29. Constants & Operators & Variables
constructors constructors
String : STRING -> Exp Geq : Exp * Exp -> Exp
Int : INT -> Exp Leq : Exp * Exp -> Exp
False : Exp Gt : Exp * Exp -> Exp
True : Exp Lt : Exp * Exp -> Exp
Eq : Exp * Exp -> Exp
Mul : Exp * Exp -> Exp
Minus : Exp * Exp -> Exp
Plus : Exp * Exp -> Exp
Or : Exp * Exp -> Exp
And : Exp * Exp -> Exp
Not : Exp -> Exp
constructors
VarDecl : ID * Type -> Stat
VarDeclInit : ID * Type * Exp -> Stat
Assign : Exp * Exp -> Stat
Var : ID -> Exp
30. Statements & Functions
constructors
Exp : Exp -> Stat
Block : List(Stat) -> Stat
Seq : List(Stat) -> Stat
While : Exp * List(Stat) -> Stat
IfElse : Exp * List(Stat) * List(ElseIf) * Option(Else) -> Stat
Else : List(Stat) -> Else
ElseIf : Exp * List(Stat) -> ElseIf
constructors
FunDef : ID * List(Arg) * Type * List(Stat) -> Property
FunDecl : ID * List(Arg) * Type -> Property
Arg : ID * Type -> Arg
Return : Exp -> Stat
MethCall : Exp * ID * List(Exp) -> Exp
ThisCall : ID * List(Exp) -> Exp
32. Transformation by Strategic Rewriting
rules
desugar:
Plus(e1, e2) -> MethCall(e1, "plus", [e2])
desugar:
Or(e1, e2) -> MethCall(e1, "or", [e2])
desugar :
VarDeclInit(x, t, e) ->
Seq([VarDecl(x, t),
Assign(Var(x), e)])
strategies
desugar-all = topdown(repeat(desugar))
33. Return-Lifting Applied
function fact(n: Int): Int { function fact(n: Int): Int {
var res: Int;
if(n == 0) { if(n == 0) {
return 1; res := 1;
} else { } else {
return this * fact(n - 1); res := this * fact(n - 1);
} }
return res;
} }
34. Return-Lifting Rules
rules
lift-return-all =
alltd(lift-return; normalize-all)
lift-return :
FunDef(x, arg*, Some(t), stat1*) ->
FunDef(x, arg*, Some(t), Seq([
VarDecl(y, t),
Seq(stat2*),
Return(Var(y))
]))
where y := <new>;
stat2* := <alltd(replace-return(|y))> stat1*
replace-return(|y) :
Return(e) -> Assign(y, e)
35. Seq Normalization
strategies
normalize-all = innermost-L(normalize)
rules // seq lifting
normalize :
[Seq(stat1*) | stat2*@[_|_]] -> [Seq([stat1*,stat2*])]
normalize :
[stat, Seq(stat*)] -> [Seq([stat | stat*])]
normalize :
Block([Seq(stat1*)]) -> Block(stat1*)
normalize :
FunDef(x, arg*, t, [Seq(stat*)]) -> FunDef(x, arg*, t, stat*)
37. Small Step Operational Semantics
rules // driver
steps = repeat(step)
step:
State([Frame(fn, this, slots, cont)|f*], heap) ->
State(stack', heap')
where
cont' := <eval> cont;
stack' := <update-stack (|...)> [Frame(..., cont')|f*];
heap' := <update-heap(|...)> heap
38. Small Step Operational Semantics
eval(|this, slots, heap):
Var(x) -> val
where val := <lookup> (x, slots)
eval(|this, slots, heap):
PropAccess(Ptr(p), prop) -> val
where
Object(_, props) := <lookup> (p, heap);
val := <lookup> (prop, props)
40. Declarative Syntax Definition
Entity("User", [
Property("first", Type("String")),
Property("last", Type("String"))
])
signature
constructors
Entity : ID * List(Property) -> Definition
Type : ID -> Type
Property : ID * Type -> Property
41. Declarative Syntax Definition
entity User { Entity("User", [
first : String Property("first", Type("String")),
last : String Property("last", Type("String"))
} ])
signature
constructors
Entity : ID * List(Property) -> Definition
Type : ID -> Type
Property : ID * Type -> Property
42. Declarative Syntax Definition
context-free syntax
"entity" ID "{" Property* "}" -> Definition {"Entity"}
ID -> Type {"Type"}
ID ":" Type -> Property {"Property"}
entity User { Entity("User", [
first : String Property("first", Type("String")),
last : String Property("last", Type("String"))
} ])
signature
constructors
Entity : ID * List(Property) -> Definition
Type : ID -> Type
Property : ID * Type -> Property
43. Declarative Syntax Definition
context-free syntax
"entity" ID "{" Property* "}" -> Definition {"Entity"}
ID -> Type {"Type"}
ID ":" Type -> Property {"Property"}
entity User { Entity("User", [
first : String Property("first", Type("String")),
last : String Property("last", Type("String"))
} ])
signature
constructors
Entity : ID * List(Property) -> Definition
Type : ID -> Type
Property : ID * Type -> Property
44. Context-free Syntax
context-free syntax constructors
"true" -> Exp {"True"} True : Exp
"false" -> Exp {"False"} False : Exp
"!" Exp -> Exp {"Not"} Not : Exp -> Exp
Exp "&&" Exp -> Exp {"And"} And : Exp * Exp -> Exp
Exp "||" Exp -> Exp {"Or"} Or : Exp * Exp -> Exp
45. Lexical Syntax
context-free syntax constructors
"true" -> Exp {"True"} True : Exp
"false" -> Exp {"False"} False : Exp
"!" Exp -> Exp {"Not"} Not : Exp -> Exp
Exp "&&" Exp -> Exp {"And"} And : Exp * Exp -> Exp
Exp "||" Exp -> Exp {"Or"} Or : Exp * Exp -> Exp
lexical syntax constructors
[a-zA-Z][a-zA-Z0-9]* -> ID : String -> ID
"-"? [0-9]+ -> INT : String -> INT
[ tnr] -> LAYOUT
scannerless generalized (LR) parsing
46. Ambiguity
context-free syntax constructors
"true" -> Exp {"True"} True : Exp
"false" -> Exp {"False"} False : Exp
"!" Exp -> Exp {"Not"} Not : Exp -> Exp
Exp "&&" Exp -> Exp {"And"} And : Exp * Exp -> Exp
Exp "||" Exp -> Exp {"Or"} Or : Exp * Exp -> Exp
isPublic || isDraft && (author == principal())
amb([
And(Or(Var("isPublic"), Var("isDraft")),
Eq(Var("author"), ThisCall("principal", []))),
Or(Var("isPublic"),
And(Var("isDraft"), Eq(Var("author"), ThisCall("principal", []))))
])
47. Disambiguation by Encoding Precedence
context-free syntax constructors
"true" -> Exp {"True"} True : Exp
"false" -> Exp {"False"} False : Exp
"!" Exp -> Exp {"Not"} Not : Exp -> Exp
Exp "&&" Exp -> Exp {"And"} And : Exp * Exp -> Exp
Exp "||" Exp -> Exp {"Or"} Or : Exp * Exp -> Exp
context-free syntax
"(" Exp ")" -> Exp0 {bracket}
"true" -> Exp0 {"True"}
"false" -> Exp0 {"False"}
Exp0 -> Exp1
"!" Exp0 -> Exp1 {"Not"}
Exp1 -> Exp2
Exp1 "&&" Exp2 -> Exp2 {"And"}
Exp2 -> Exp3
Exp2 "||" Exp3 -> Exp3 {"Or"}
48. Declarative Disambiguation
context-free syntax
"true" -> Exp {"True"}
"false" -> Exp {"False"}
"!" Exp -> Exp {"Not"}
Exp "&&" Exp -> Exp {"And", left}
Exp "||" Exp -> Exp {"Or", left}
"(" Exp ")" -> Exp {bracket}
context-free priorities
{left: Exp.Not} >
{left: Exp.Mul} >
{left: Exp.Plus Exp.Minus} >
{left: Exp.And} >
{non-assoc: Exp.Eq Exp.Lt Exp.Gt Exp.Leq Exp.Geq}
isPublic || isDraft && (author == principal())
Or(Var("isPublic"),
And(Var("isDraft"),
Eq(Var("author"), ThisCall("principal", []))))
50. Code Generation by String Concatenation
to-java:
Property(x, Type(t)) -> <concat-strings>[
"private ", t, " ", x, ";nn",
"public ", t, " get_", x, " {n",
" return ", x, ";n",
"}n",
"public void set_", x, " (", t, " ", x, ") {n",
" this.", x, " = ", x, ";n",
"}"
]
51. String Interpolation Templates
to-java:
Property(x, Type(t)) -> $[
private [t] [x];
public [t] get_[x] {
return [x];
}
public void set_[x] ([t] [x]) {
this.[x] = [x];
}
]
53. Generating Structured Representations
to-java:
Property(x, Type(t)) -> [
Field([Private()], Type(t), Var(x)),
Method([Public()], Type(t), $[get_[x]], [], [
Return(Var(x))
]),
Method([Public()], None(), $[set_[x]], [Param(Type(t), x)], [
Assign(FieldAccess(This(), x), Var(x))
])
]
54. Concrete Object Syntax
to-java:
Property(x, Type(t)) -> |[
private t x;
public t get_#x {
return x;
}
public void set_#x (t x) {
this.x = x;
}
]|
55. Rewriting with Concrete Object Syntax
module desugar
imports Enfun
strategies
desugar-all = topdown(repeat(desugar))
rules
desugar: |[ !e ]| -> |[ e.not() ]|
desugar: |[ e1 && e2 ]| -> |[ e1.and(e2) ]|
desugar: |[ e1 || e2 ]| -> |[ e1.or(e2) ]|
desugar: |[ e1 + e2 ]| -> |[ e1.plus(e2) ]|
desugar: |[ e1 * e2 ]| -> |[ e1.times(e2) ]|
desugar: |[ e1 - e2 ]| -> |[ e1.minus(e2) ]|
56. Rewriting with Concrete Object Syntax
lift-return-cs :
|[ function x(arg*) : t { stat1* } ]| ->
|[ function x(arg*): t {
var y : t;
( stat2* )
return y;
} ]|
where y := <new>;
stat2* := <alltd(replace-return(|y))> stat1*
lift-return :
FunDef(x, arg*, Some(t), stat1*) ->
FunDef(x, arg*, Some(t), Seq([
VarDecl(y, t),
Seq(stat2*),
Return(Var(y))
]))
where y := <new>;
stat2* := <alltd(replace-return(|y))> stat1*
58. Code Formatting
module users
entity String { }
entity User { first : String last : String }
Module(
"demo1"
module users
, [ Entity("String", None(), None(), [])
, Entity( entity String {
"User"
}
, [ Property("first", Type("String"))
, Property("last", Type("String"))
] entity User {
) first : String
]
)
last : String
}
63. Completion Templates
completions
completion template Definition : "entity ID { }" =
"entity " <ID:ID> " {nt" (cursor) "n}" (blank)
completion template Type : "ID" =
<ID:ID>
completion template Property : "ID : ID " =
<ID:ID> " : " <ID:Type> (blank)
64. Syntax Templates: Structure + Layout
context-free syntax
"entity" ID "{" Property* "}" -> Definition {"Entity"}
ID -> Type {"Type"}
ID ":" Type -> Property {"Property"}
templates
signature
constructors
Entity : ID * List(Property) -> Definition
Definition.Entity = < Type : ID -> Type
Property : ID * Type -> Property
entity <ID> {
<Property*; separator="n">
completions
} completion template Definition : "entity ID { }" =
> "entity " <ID:ID> " {nt" (cursor) "n}" (blank)
completion template Type : "ID<>" =
<ID:ID> "<" <:Type> ">"
Type.Type = <<ID>> completion template Property : "ID : ID " =
<ID:ID> " : " <ID:Type> (blank)
Property.Property = <
prettyprint-Definition =
<ID> : <Type> ?Entity(x, prop*)
; ![ H(
> [SOpt(HS(), "0")]
, [ S("entity ")
, <pp-one-Z(prettyprint-ID)> x
, S(" {")
]
)
, <pp-indent(|"2")> [<pp-V-list(prettyprint-Property)> p*]
, H([SOpt(HS(), "0")], [S("}")]
)
]
66. Example: Checking Method Calls
module renaming
entity String {
function plus(that:String): String { ... }
}
entity User {
firstName : String
lastName : String
fullName : String
function rename(first: String, last: String) {
fullName := first.plus(0); // argument has wrong type
fullName := first.plus(); // too few arguments
fullName := first.plus(last, last); // too many arguments
fullName := first.plus(last); // correct
}
}
67. Constraint Checks
rules // errors
type-error :
(e, t) -> (e, $[Type [<pp>t] expected instead of [<pp>t']])
where <type-of> e => t'; not(<subtype>(t', t))
rules // functions
constraint-error:
|[ e.x(e*) ]| -> (x, $[Expects [m] arguments, found [n]])
where <lookup-type> x => (t*, t);
<length> e* => n; <length> t* => m;
not(<eq>(m, n))
constraint-error:
|[ e.x(e*) ]| -> <zip; filter(type-error)> (e*, t*)
where <lookup-type> x => (t*, t)
68. Type Analysis
rules // constants
type-of : |[ true ]| -> TypeBool()
type-of : |[ false ]| -> TypeBool()
type-of : Int(i) -> TypeInt()
type-of : String(x) -> TypeString()
69. Types of Names
rules // names
type-of :
Var(x) -> <lookup-type> x
type-of :
|[ e.x ]| -> t
where <lookup-type> x => t
type-of :
|[ e.x(e*) ]| -> t
where <lookup-type> x => (t*, t)
type-of :
|[ f(e*) ]| -> t
where <lookup-type> f => (t*, t)
71. Definitions and References
definition
test type refers to entity [[
module test
entity [[String]] { }
entity User {
first : [[String]]
last : String
}
]] resolve #2 to #1
reference
72. From Tree to Graph
Module(
"test"
, [ Entity("String", [])
, Entity(
"User"
, [ Property("first", )
, Property("last", )
]
)
]
)
73. Unique Names
Module(
"users"{[Module(), "users"]}
, [ Entity("String"{[Type(), "String", "users"]}, [])
, Entity(
"User"{[Type(), "User", "users"]}
, [ Property(
"first"{[Property(), "first", "User", "users"]}
, Type("String"{[Type(), "String", "users"]}))
, Property(
"last"{[Property(), "last", "User", "users"]}
, Type("String"{[Type(), "String", "users"]}))
]
)
]
)
+ index mapping unique names to values
74. Spoofax Name Binding Language
namespaces Module Type See the full story in
SLE talk on Friday
rules
Entity(c, _) :
defines Type c
Type(x, _) :
refers to Type x
Module(m, _) :
defines Module m
scopes Type
Imports(m) :
imports Type from Module m
abstract from name resolution algorithmics