Separation of Concerns !
in Language Definition
Eelco Visser!
Delft University of Technology
“99% of errors found by Semmle are due to bad language design”
— Oege de Moor, CEO Semmle
Problem
Domain
Solution
Domain
General-
Purpose
Language
Problem
Domain
Solution
Domain
General-
Purpose
Language
• Lack of safety
Problem
Domain
Solution
Domain
General-
Purpose
Language
• Lack of safety
• Lack of abstraction
Problem
Domain
Solution
Domain
General-
Purpose
Language
• Lack of safety
• Lack of abstraction
• Distance from domain
Solution
Domain
Problem
Domain
General-
Purpose
Language
Domain-
Specific
Language
• Lack of safety
• Lack of abstraction
...
Solution
Domain
Problem
Domain
General-
Purpose
Language
Domain-
Specific
Language
• Language-based safety and security
• ...
Solution
Domain
Problem
Domain
General-
Purpose
Language
Domain-
Specific
Language
• Language-based safety and security
• ...
Solution
Domain
Problem
Domain
General-
Purpose
Language
Domain-
Specific
Language
• Language-based safety and security
• ...
General-
Purpose
Language
Solution
Domain
Problem
Domain
General-
Purpose
Language
Domain-
Specific
Language
Language
Desi...
Compiler +
Editor (IDE)
Language
Design
General-
Purpose
Language
Declarative-
Meta
Languages
Solution
Domain
Problem
Doma...
Compiler +
Editor (IDE)
Language
Design
General-
Purpose
Language
Declarative-
Meta
Languages
Language
Design
Language wor...
Compiler +
Editor (IDE)
Language
Design
General-
Purpose
Language
Declarative-
Meta
Languages
Language
Design
Language wor...
Compiler +
Editor (IDE)
Language
Design
General-
Purpose
Language
Declarative-
Meta
Languages
Language
Design
Language wor...
Compiler +
Editor (IDE)
Language
Design
General-
Purpose
Language
Declarative-
Meta
Languages
Language
Design
Language wor...
parser
parser
type checker
parser
type checker
code generator
parser
type checker
code generator
interpreter
parser
type checker
code generator
interpreter
parser
parser
type checker
code generator
interpreter
parser
error recovery
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
code completion
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
code completion
navigation
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
code completion
navigatio...
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
code completion
navigatio...
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
code completion
navigatio...
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
code completion
navigatio...
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
code completion
navigatio...
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
code completion
navigatio...
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
code completion
navigatio...
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
code completion
navigatio...
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
code completion
navigatio...
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
code completion
navigatio...
Language Design
Syntax
Definition
Name
Binding
Type
Constraints
Dynamic
Semantics
Transform
Syntax Definition
int fib(int n) {	
if(n <= 1) 	
return 1;	
else 	
return fib(n - 2) + fib(n - 1);	
}
Syntax: Phrase Structure of Programs
Syntax: Phrase Structure of Programs
}
int fib ( int n ) {
if ( n <= 1 )
return 1 ;
else
return fib ( n - 2 ) + fib ( n - ...
}int fib ( int n ) { if ( n <= 1 ) return 1 ; else return fib ( n - 2 ) + fib ( n - 1 ) ;
Syntax: Phrase Structure of Prog...
Exp.IntExp.Int
Exp.Leq Statement.Return Exp.Sub Exp.Sub
Exp.Call Exp.Call
Param.Param
IntType
ID
}int fib ( int n ) { if (...
Exp.IntExp.Int
Exp.Leq Statement.Return Exp.Sub Exp.Sub
Exp.Call Exp.Call
Exp.Add
Param.Param
IntType
ID
}int fib ( int n ...
Exp.IntExp.Int
Exp.Leq Statement.Return Exp.Sub Exp.Sub
Exp.Call Exp.Call
Exp.Add
Statement.Return
Param.Param
IntType
ID
...
Exp.IntExp.Int
Exp.Leq Statement.Return Exp.Sub Exp.Sub
Exp.Call Exp.Call
Exp.Add
Statement.Return
Param.Param
IntType
Sta...
Exp.IntExp.Int
Exp.Leq Statement.Return Exp.Sub Exp.Sub
Exp.Call Exp.Call
Exp.Add
Statement.Return
Param.Param
IntType
Def...
Function
IntType IntType
Param
Var Int Int
Leq Return
Return
Call
Add
Var Int
Sub
Var Int
Sub
Call
If
fib n n 1 1 fib n 2 ...
int fib(int n) {	
if(n <= 1) 	
return 1;	
else 	
return fib(n - 2) + fib(n - 1);	
}
Text
parse
Function(	
IntType()	
, "fib"	
, [Param(IntType(), "n")]	
, [ If(	
Leq(Var("n"), Int("1"))	
, Int("1")	
, Add(	
Call("fib"...
Type
Definition.Function
ID }( ) {Param* Statement*
Exp
Statement.Return
return ;
Statement.If
if ( ) elseExp Statement St...
Demo: Syntax Definition in SDF3
Language Design
Syntax!
Definition
Name !
Binding
Type!
Constraints
Dynamic!
Semantics
Trans...
Type
Definition.Function
ID }( ) {Param* Statement*
Exp
Statement.Return
return ;
Statement.If
if ( ) elseExp Statement St...
Statement.If = <	
if(<Exp>) 	
<Statement>	
else	
<Statement>	
>
Parser
Abstract syntax tree schema
Pretty-Printer
Syntacti...
Name and Type Analysis
Name Binding & Scope Rules
int fib(int n) {	
if(n <= 1) 	
return 1;	
else 	
return fib(n - 2) + fib(n - 1);	
}
what does t...
Demo: Name and Type Analysis in NaBL+TS
Language Design
Syntax!
Definition
Name !
Binding
Type!
Constraints
Dynamic!
Semant...
Declarative Name Binding and Scope Rules
binding rules	
!
Param(t, name) :	
defines Variable name	
	
Var(name) :	
refers t...
Semantics of Name Binding?
binding rules	
!
Param(t, name) :	
defines Variable name	
	
Var(name) :	
refers to Variable nam...
Interpretation!
& Verification
Language Design
Syntax!
Definition
Name !
Binding
Type!
Constraints
Dynamic!
Semantics
Transform
rules	
	
Num(i) --> I(i)	
	
Ifz(e1, e2, e3) --> v	
where e1 --> I(i), i = 0, e2 --> v	
	
Ifz(e1, e2, e3) --> v	
where e1 -...
Implicitly-Modular Structural Operational Semantics (I-MSOS)*
rules	
!
E env |- Var(x) --> v 	
where env[x] => T(e, env'),...
rules	
	
Ifz(e1, e2, e3) --> v	
where e1 --> I(i), i = 0, e2 --> v	
	
Ifz(e1, e2, e3) --> v	
where e1 --> I(i), i != 0, e3...
module PCF	
sorts Exp Param Type 	
templates	
Exp.Var = [[ID]]	
Exp.App = [[Exp] [Exp]] {left} 	
Exp.Fun = [	
	 fun [Param...
else 	
	 [Exp]	
]	
Type.IntType = [int]	
Type.FunType = [[Type] -> [Type]] 	
Param.Param = [[ID] : [Type]]	
	
context-free...
Summary
parser
type checker
code generator
interpreter
parser
error recovery
syntax highlighting
outline
code completion
navigatio...
Declarative Multi-Purpose Language Definition
Syntax
Definition
Name
Binding
Type
Constraints
Dynamic
Semantics
Transform
Declarative Multi-Purpose Language Definition
SDF3: Syntax
Definition
NaBL: Name
Binding
TS: Type
Constraints
DynSem:
Dynami...
Declarative Multi-Purpose Language Definition
SDF3: Syntax
Definition
NaBL: Name
Binding
TS: Type
Constraints
DynSem:
Dynami...
Separation of Concerns in Language Definition
Separation of Concerns in Language Definition
Separation of Concerns in Language Definition
Separation of Concerns in Language Definition
Separation of Concerns in Language Definition
Separation of Concerns in Language Definition
Separation of Concerns in Language Definition
Upcoming SlideShare
Loading in …5
×

Separation of Concerns in Language Definition

1,558 views

Published on

Slides for keynote at the Modularity 2014 conference in Lugano on April 23, 2014. (A considerable part of the talk consisted of live programming the syntax definition and name binding rules for a little language.)

Published in: Technology
  • Be the first to comment

Separation of Concerns in Language Definition

  1. 1. Separation of Concerns ! in Language Definition Eelco Visser! Delft University of Technology
  2. 2. “99% of errors found by Semmle are due to bad language design” — Oege de Moor, CEO Semmle
  3. 3. Problem Domain Solution Domain General- Purpose Language
  4. 4. Problem Domain Solution Domain General- Purpose Language • Lack of safety
  5. 5. Problem Domain Solution Domain General- Purpose Language • Lack of safety • Lack of abstraction
  6. 6. Problem Domain Solution Domain General- Purpose Language • Lack of safety • Lack of abstraction • Distance from domain
  7. 7. Solution Domain Problem Domain General- Purpose Language Domain- Specific Language • Lack of safety • Lack of abstraction • Distance from domain
  8. 8. Solution Domain Problem Domain General- Purpose Language Domain- Specific Language • Language-based safety and security • Lack of abstraction • Distance from domain
  9. 9. Solution Domain Problem Domain General- Purpose Language Domain- Specific Language • Language-based safety and security • High-level domain-specific abstraction • Distance from domain
  10. 10. Solution Domain Problem Domain General- Purpose Language Domain- Specific Language • Language-based safety and security • High-level domain-specific abstraction • Reduced distance from problem domain
  11. 11. General- Purpose Language Solution Domain Problem Domain General- Purpose Language Domain- Specific Language Language Design Compiler + Editor (IDE)
  12. 12. Compiler + Editor (IDE) Language Design General- Purpose Language Declarative- Meta Languages Solution Domain Problem Domain General- Purpose Language Domain- Specific Language Language Design
  13. 13. Compiler + Editor (IDE) Language Design General- Purpose Language Declarative- Meta Languages Language Design Language workbench
  14. 14. Compiler + Editor (IDE) Language Design General- Purpose Language Declarative- Meta Languages Language Design Language workbench Declarative multi-purpose meta-languages
  15. 15. Compiler + Editor (IDE) Language Design General- Purpose Language Declarative- Meta Languages Language Design Language workbench Declarative multi-purpose meta-languages Useable language implementations
  16. 16. Compiler + Editor (IDE) Language Design General- Purpose Language Declarative- Meta Languages Language Design Language workbench Declarative multi-purpose meta-languages Useable language implementations High quality language designs
  17. 17. parser
  18. 18. parser type checker
  19. 19. parser type checker code generator
  20. 20. parser type checker code generator interpreter
  21. 21. parser type checker code generator interpreter parser
  22. 22. parser type checker code generator interpreter parser error recovery
  23. 23. parser type checker code generator interpreter parser error recovery syntax highlighting
  24. 24. parser type checker code generator interpreter parser error recovery syntax highlighting outline
  25. 25. parser type checker code generator interpreter parser error recovery syntax highlighting outline code completion
  26. 26. parser type checker code generator interpreter parser error recovery syntax highlighting outline code completion navigation
  27. 27. parser type checker code generator interpreter parser error recovery syntax highlighting outline code completion navigation type checker
  28. 28. parser type checker code generator interpreter parser error recovery syntax highlighting outline code completion navigation type checker debugger
  29. 29. parser type checker code generator interpreter parser error recovery syntax highlighting outline code completion navigation type checker debugger syntax definition
  30. 30. parser type checker code generator interpreter parser error recovery syntax highlighting outline code completion navigation type checker debugger syntax definition static semantics
  31. 31. parser type checker code generator interpreter parser error recovery syntax highlighting outline code completion navigation type checker debugger syntax definition static semantics dynamic semantics
  32. 32. parser type checker code generator interpreter parser error recovery syntax highlighting outline code completion navigation type checker debugger syntax definition static semantics dynamic semantics abstract syntax
  33. 33. parser type checker code generator interpreter parser error recovery syntax highlighting outline code completion navigation type checker debugger syntax definition static semantics dynamic semantics abstract syntax type system
  34. 34. parser type checker code generator interpreter parser error recovery syntax highlighting outline code completion navigation type checker debugger syntax definition static semantics dynamic semantics abstract syntax type system operational semantics
  35. 35. parser type checker code generator interpreter parser error recovery syntax highlighting outline code completion navigation type checker debugger syntax definition static semantics dynamic semantics abstract syntax type system operational semantics type soundness proof
  36. 36. parser type checker code generator interpreter parser error recovery syntax highlighting outline code completion navigation type checker debugger syntax definition static semantics dynamic semantics abstract syntax type system operational semantics type soundness proof
  37. 37. Language Design Syntax Definition Name Binding Type Constraints Dynamic Semantics Transform
  38. 38. Syntax Definition
  39. 39. int fib(int n) { if(n <= 1) return 1; else return fib(n - 2) + fib(n - 1); } Syntax: Phrase Structure of Programs
  40. 40. Syntax: Phrase Structure of Programs } int fib ( int n ) { if ( n <= 1 ) return 1 ; else return fib ( n - 2 ) + fib ( n - 1 ) ;
  41. 41. }int fib ( int n ) { if ( n <= 1 ) return 1 ; else return fib ( n - 2 ) + fib ( n - 1 ) ; Syntax: Phrase Structure of Programs
  42. 42. Exp.IntExp.Int Exp.Leq Statement.Return Exp.Sub Exp.Sub Exp.Call Exp.Call Param.Param IntType ID }int fib ( int n ) { if ( n <= 1 ) return 1 ; else return fib ( n - 2 ) + fib ( n - 1 ) ; Exp.IntExp.Var Exp.IntExp.VarExp.VarIntType Syntax: Phrase Structure of Programs
  43. 43. Exp.IntExp.Int Exp.Leq Statement.Return Exp.Sub Exp.Sub Exp.Call Exp.Call Exp.Add Param.Param IntType ID }int fib ( int n ) { if ( n <= 1 ) return 1 ; else return fib ( n - 2 ) + fib ( n - 1 ) ; Exp.IntExp.Var Exp.IntExp.VarExp.VarIntType Syntax: Phrase Structure of Programs
  44. 44. Exp.IntExp.Int Exp.Leq Statement.Return Exp.Sub Exp.Sub Exp.Call Exp.Call Exp.Add Statement.Return Param.Param IntType ID }int fib ( int n ) { if ( n <= 1 ) return 1 ; else return fib ( n - 2 ) + fib ( n - 1 ) ; Exp.IntExp.Var Exp.IntExp.VarExp.VarIntType Syntax: Phrase Structure of Programs
  45. 45. Exp.IntExp.Int Exp.Leq Statement.Return Exp.Sub Exp.Sub Exp.Call Exp.Call Exp.Add Statement.Return Param.Param IntType Statement.If ID }int fib ( int n ) { if ( n <= 1 ) return 1 ; else return fib ( n - 2 ) + fib ( n - 1 ) ; Exp.IntExp.Var Exp.IntExp.VarExp.VarIntType Syntax: Phrase Structure of Programs
  46. 46. Exp.IntExp.Int Exp.Leq Statement.Return Exp.Sub Exp.Sub Exp.Call Exp.Call Exp.Add Statement.Return Param.Param IntType Definition.Function Statement.If ID }int fib ( int n ) { if ( n <= 1 ) return 1 ; else return fib ( n - 2 ) + fib ( n - 1 ) ; Exp.IntExp.Var Exp.IntExp.VarExp.VarIntType Syntax: Phrase Structure of Programs
  47. 47. Function IntType IntType Param Var Int Int Leq Return Return Call Add Var Int Sub Var Int Sub Call If fib n n 1 1 fib n 2 fib n 1 Abstract! Syntax! Tree
  48. 48. int fib(int n) { if(n <= 1) return 1; else return fib(n - 2) + fib(n - 1); } Text parse
  49. 49. Function( IntType() , "fib" , [Param(IntType(), "n")] , [ If( Leq(Var("n"), Int("1")) , Int("1") , Add( Call("fib", [Sub(Var("n"), Int("2"))]) , Call("fib", [Sub(Var("n"), Int("1"))]) ) ) ] ) int fib(int n) { if(n <= 1) return 1; else return fib(n - 2) + fib(n - 1); } Abstract ! Syntax ! Term Text parse
  50. 50. Type Definition.Function ID }( ) {Param* Statement* Exp Statement.Return return ; Statement.If if ( ) elseExp Statement Statement Exp.Add +Exp Exp Exp.Var ID Understanding Syntax =! Understanding Tree Structure parse(prettyprint(t)) = t No need to understand ! how parse works!
  51. 51. Demo: Syntax Definition in SDF3 Language Design Syntax! Definition Name ! Binding Type! Constraints Dynamic! Semantics Transform
  52. 52. Type Definition.Function ID }( ) {Param* Statement* Exp Statement.Return return ; Statement.If if ( ) elseExp Statement Statement Exp.Add +Exp Exp templates Definition.Function = < <Type> <ID>(<Param*; separator=",">) { <Statement*; separator="n"> } > ! Statement.If = < if(<Exp>) <Statement> else <Statement> > ! Statement.Return = <return <Exp>;> ! Exp.Add = <<Exp> + <Exp>> ! Exp.Var = <<ID>>Exp.Var ID The Syntax Definition Formalism SDF3
  53. 53. Statement.If = < if(<Exp>) <Statement> else <Statement> > Parser Abstract syntax tree schema Pretty-Printer Syntactic completion templates Folding rules Error recovery rules Syntactic coloring Outline rules Syntax Definition Multi-Purpose Declarative Syntax Definition
  54. 54. Name and Type Analysis
  55. 55. Name Binding & Scope Rules int fib(int n) { if(n <= 1) return 1; else return fib(n - 2) + fib(n - 1); } what does this variable refer to? Our contribution ! - declarative language for name binding & scope rules - generation of incremental name resolution algorithm ! - Konat, Kats, Wachsmuth, Visser (SLE 2012) - Wachsmuth, Konat, Vergu, Groenewegen, Visser (SLE 2013) which function is being called here? Needed for ! - checking correct use of names and types - lookup in interpretation and compilation - navigation in IDE - code completion State-of-the-art ! - programmatic encoding of name resolution algorithms
  56. 56. Demo: Name and Type Analysis in NaBL+TS Language Design Syntax! Definition Name ! Binding Type! Constraints Dynamic! Semantics Transform
  57. 57. Declarative Name Binding and Scope Rules binding rules ! Param(t, name) : defines Variable name Var(name) : refers to Variable name ! Function(t, name, param*, s) : defines Function name scopes Variable, Function ! Call(name, exp*) : refers to Function name Incremental name resolution algorithm Name checks Semantic code completion Reference resolution
  58. 58. Semantics of Name Binding? binding rules ! Param(t, name) : defines Variable name Var(name) : refers to Variable name ! Function(t, name, param*, s) : defines Function name scopes Variable, Function ! Call(name, exp*) : refers to Function name Research: how to characterize correctness of the result of name resolution without appealing to the algorithm itself? Analogy: declarative semantics of syntax definition
  59. 59. Interpretation! & Verification
  60. 60. Language Design Syntax! Definition Name ! Binding Type! Constraints Dynamic! Semantics Transform
  61. 61. rules Num(i) --> I(i) Ifz(e1, e2, e3) --> v where e1 --> I(i), i = 0, e2 --> v Ifz(e1, e2, e3) --> v where e1 --> I(i), i != 0, e3 --> v Add(e1, e2) --> I(addInt(i, j)) where e1 --> I(i), e2 --> I(j) Sub(e1, e2) --> I(subInt(i, j)) where e1 --> I(i), e2 --> I(j) Mul(e1, e2) --> I(mulInt(i, j)) where e1 --> I(i), e2 --> I(j) DynSem: Dynamic Semantics Specification module semantics ! rules ! E env |- Var(x) --> v where env[x] => T(e, env'), E env' |- e --> v E env |- Fun(Param(x, t), e) --> C(x, e, env) ! E env |- App(e1, e2) --> v where E env |- e1 --> C(x, e, env'), E {x |--> T(e2, env), env'} |- e --> v E env |- Fix(Param(x, t), e) --> v where E {x |--> T(Fix(Param(x,t),e),env), env} |- e --> v E env |- Let(x, t, e1, e2) --> v where E {x |--> T(e1, env), env} |- e2 --> v
  62. 62. Implicitly-Modular Structural Operational Semantics (I-MSOS)* rules ! E env |- Var(x) --> v where env[x] => T(e, env'), E env' |- e --> v ! Add(e1, e2) --> I(addInt(i, j)) where e1 --> I(i), e2 --> I(j) rules ! E env |- Var(x) --> v where env[x] => T(e, env'), E env' |- e --> v ! E env |- Add(e1, e2) --> I(addInt(i, j)) where E env |- e1 --> I(i), E env |- e2 --> I(j)explicate * P. D. Mosses. Modular structural operational semantics. JLP, 60-61:195–228, 2004. M. Churchill, P. D. Mosses, and P. Torrini. Reusable components of semantic specifications. In MODULARITY, April 2014.
  63. 63. rules Ifz(e1, e2, e3) --> v where e1 --> I(i), i = 0, e2 --> v Ifz(e1, e2, e3) --> v where e1 --> I(i), i != 0, e3 --> v Interpreter Generation rules E env |- Ifz(e1, e2, e3) --> v where E env |- e1 --> I(i), [i = 0, E env |- e2 --> v] + i != 0, E env |- e3 --> v] explicate & merge
  64. 64. module PCF sorts Exp Param Type templates Exp.Var = [[ID]] Exp.App = [[Exp] [Exp]] {left} Exp.Fun = [ fun [Param] ( [Exp] ) ] Exp.Fix = [ fix [Param] ( [Exp] ) ] Exp.Let = [ let [ID] : [Type] = [Exp] in [Exp] ] Exp.Num = [[INT]] Exp.Add = [[Exp] + [Exp]] {left} Exp.Sub = [[Exp] - [Exp]] {left} Exp.Mul = [[Exp] * [Exp]] {left} Exp = [([Exp])] {bracket} Exp.Ifz = [ ifz [Exp] then [Exp] else [Exp] ] Type.IntType = [int] Type.FunType = [[Type] -> [Type]] Param.Param = [[ID] : [Type]] context-free priorities ! Exp.App > Exp.Mul > {left: Exp.Add Exp.Sub} > Exp.Ifz module types type rules ! Var(x) : t where definition of x : t Param(x, t) : t Fun(p, e) : FunType(tp, te) where p : tp and e : te App(e1, e2) : tr where e1 : FunType(tf, tr) and e2 : ta and tf == ta else error "type mismatch" on e2 ! Fix(p, e) : tp where p : tp and e : te and tp == te else error "type mismatch" on p Let(x, tx, e1, e2) : t2 where e2 : t2 and e1 : t1 and t1 == tx else error "type mismatch" on e1 Num(i) : IntType() ! Ifz(e1, e2, e3) : t2 where e1 : IntType() and e2 : t2 and e3 : t3 and t2 == t3 else error "types not compatible" on e3 e@Add(e1, e2) + e@Sub(e1, e2) + e@Mul(e1, e2) : IntType() where e1 : IntType() else error "Int type expected" on e and e2 : IntType() else error "Int type expected" on e module semantics ! rules ! E env |- Var(x) --> v where env[x] => T(e, env'), E env' |- e --> v E env |- Fun(Param(x, t), e) --> C(x, e, env) ! E env |- App(e1, e2) --> v where E env |- e1 --> C(x, e, env'), E {x |--> T(e2, env), env'} |- e --> v E env |- Fix(Param(x, t), e) --> v where E {x |--> T(Fix(Param(x,t),e),env), env} |- e --> v E env |- Let(x, t, e1, e2) --> v where E {x |--> T(e1, env), env} |- e2 --> v rules Num(i) --> I(i) Ifz(e1, e2, e3) --> v where e1 --> I(i), i = 0, e2 --> v Ifz(e1, e2, e3) --> v where e1 --> I(i), i != 0, e3 --> v Add(e1, e2) --> I(addInt(i, j)) where e1 --> I(i), e2 --> I(j) Sub(e1, e2) --> I(subInt(i, j)) where e1 --> I(i), e2 --> I(j) Mul(e1, e2) --> I(mulInt(i, j)) where e1 --> I(i), e2 --> I(j) module names namespaces Variable binding rules ! Var(x) : refers to Variable x Param(x, t) : defines Variable x of type t Fun(p, e) : scopes Variable Fix(p, e) : scopes Variable Let(x, t, e1, e2) : defines Variable x of type t in e2 First Little (Big) Step: From PCF in Spoofax …
  65. 65. else [Exp] ] Type.IntType = [int] Type.FunType = [[Type] -> [Type]] Param.Param = [[ID] : [Type]] context-free priorities ! Exp.App > Exp.Mul > {left: Exp.Add Exp.Sub} > Exp.Ifz Ifz(e1, e2, e3) : t2 where e1 : IntType() and e2 : t2 and e3 : t3 and t2 == t3 else error "types not compatible" on e3 e@Add(e1, e2) + e@Sub(e1, e2) + e@Mul(e1, e2) : IntType() where e1 : IntType() else error "Int type expected" on e and e2 : IntType() else error "Int type expected" on e Ifz(e1, e2, e3) --> v where e1 --> I(i), i != 0, e3 --> v Add(e1, e2) --> I(addInt(i, j)) where e1 --> I(i), e2 --> I(j) Sub(e1, e2) --> I(subInt(i, j)) where e1 --> I(i), e2 --> I(j) Mul(e1, e2) --> I(mulInt(i, j)) where e1 --> I(i), e2 --> I(j) Param(x, t) : defines Variable x of type t Fun(p, e) : scopes Variable Fix(p, e) : scopes Variable Let(x, t, e1, e2) : defines Variable x of type t in e2 Inductive has_type (C: Context) : term -> term -> Prop := | VarC_ht ns k0 t x k1 : lookup C x ns k0 t -> has_type C (Co VarC [Id x k0] k1) t | ParamC_ht x t k0 : has_type C (Co ParamC [x;t] k0) t | FunC_ht k0 t_p t_e p e k1 : has_type C p t_p -> has_type C e t_e -> has_type C (Co FunC [p;e] k1) (Co FunTypeC [t_p;t_e] k0) | FixC_ht t_p t_e p e k0 : has_type C p t_p -> has_type C e t_e -> (t_p = t_e) -> has_type C (Co FixC [p;e] k0) t_p | AppC_ht t_r k0 t_f t_a e1 e2 k1 : has_type C e1 (Co FunTypeC [t_f;t_r] k0) -> has_type C e2 t_a -> (t_f = t_a) -> has_type C (Co AppC [e1;e2] k1) t_r | LetC_ht t2 t1 x t_x e1 e2 k0 : has_type C e2 t2 -> has_type C e1 t1 -> (t1 = t_x) -> has_type C (Co LetC [x;t_x;e1;e2] k0) t2 | NumC_ht k0 i k1 : has_type C (Co NumC [i] k1) (Co IntTypeC [] k0) | IfzC_ht k0 t2 t3 e1 e2 e3 k1 : has_type C e1 (Co IntTypeC [] k0) -> has_type C e2 t2 -> has_type C e3 t3 -> (t2 = t3) -> has_type C (Co IfzC [e1;e2;e3] k1) t2 | AddC_ht k2 k0 k1 e1 e2 k3 : has_type C e1 (Co IntTypeC [] k0) -> has_type C e2 (Co IntTypeC [] k1) -> has_type C (Co AddC [e1;e2] k3) (Co IntTypeC [] k2) | SubC_ht k2 k0 k1 e1 e2 k3 : has_type C e1 (Co IntTypeC [] k0) -> has_type C e2 (Co IntTypeC [] k1) -> has_type C (Co SubC [e1;e2] k3) (Co IntTypeC [] k2) | MulC_ht k2 k0 k1 e1 e2 k3 : has_type C e1 (Co IntTypeC [] k0) -> has_type C e2 (Co IntTypeC [] k1) -> has_type C (Co MulC [e1;e2] k3) (Co IntTypeC [] k2) | HT_eq e ty1 ty2 (hty1: has_type C e ty1) (tyeq: term_eq ty1 ty2) : has_type C e ty2 . Inductive semantics_cbn : Env -> term -> value -> Prop := | Var0C_sem env' e env x k0 v : get_env x env e env' -> semantics_cbn env' e v -> semantics_cbn env (Co VarC [x] k0) v | Fun0C_sem t k1 k0 x e env : semantics_cbn env (Co FunC [Co ParamC [x;t] k1;e] k0) (Clos x e env) | Fix0C_sem k1 k0 env x t k3 e k2 v : semantics_cbn { x |--> (Co FixC [Co ParamC [x;t] k1;e] k0,env), env } e v -> semantics_cbn env (Co FixC [Co ParamC [x;t] k3;e] k2) v | App0C_sem env' x e env e1 e2 k0 v : semantics_cbn env e1 (Clos x e env') -> semantics_cbn { x |--> (e2,env), env' } e v -> semantics_cbn env (Co AppC [e1;e2] k0) v | Let0C_sem env x t e1 e2 k0 v : semantics_cbn { x |--> (e1,env), env } e2 v -> semantics_cbn env (Co LetC [x;t;e1;e2] k0) v | Num0C_sem env k0 i : semantics_cbn env (Co NumC [i] k0) (Natval i) | Ifz0C_sem i env e1 e2 e3 k0 v : semantics_cbn env e1 (Natval i) -> (i = 0) -> semantics_cbn env e2 v -> semantics_cbn env (Co IfzC [e1;e2;e3] k0) v | Ifz1C_sem i env e1 e2 e3 k0 v : semantics_cbn env e1 (Natval i) -> (i <> 0) -> semantics_cbn env e3 v -> semantics_cbn env (Co IfzC [e1;e2;e3] k0) v | Add0C_sem env e1 e2 k0 i j : semantics_cbn env e1 (Natval i) -> semantics_cbn env e2 (Natval j) -> semantics_cbn env (Co AddC [e1;e2] k0) (plus i j) | Sub0C_sem env e1 e2 k0 i j : semantics_cbn env e1 (Natval i) -> semantics_cbn env e2 (Natval j) -> semantics_cbn env (Co SubC [e1;e2] k0) (minus i j) | Mul0C_sem env e1 e2 k0 i j : semantics_cbn env e1 (Natval i) -> semantics_cbn env e2 (Natval j) -> semantics_cbn env (Co MulC [e1;e2] k0) (mult i j) . Inductive ID_NS : Set := | VariableNS . !Definition NS := ID_NS . !Inductive scopesR : term -> NS -> Prop := | Fun_scopes_Variable p e k0 : scopesR (Co FunC [p;e] k0) VariableNS | Fix_scopes_Variable p e k0 : scopesR (Co FixC [p;e] k0) VariableNS . !Definition scopes_R := scopesR . !Inductive definesR : term -> Ident -> NS -> key -> Prop := | Param_defines_Variable x k1 t k0 : definesR (Co ParamC [Id x k1;t] k0) x VariableNS k1 . !Definition defines_R := definesR . !Inductive refers_toR : term -> Ident -> NS -> key -> Prop := | Var_refers_to_Variable x k1 k0 : refers_toR (Co VarC [Id x k1] k0) x VariableNS k1 . !Definition refers_to_R := refers_toR . !Inductive typed_definesR : term -> Ident -> NS -> term -> key -> Prop := | Param_typed_defines_Variable x t k1 t k0 : typed_definesR (Co ParamC [Id x k1;t] k0) x VariableNS t k1 . !Definition typed_defines_R := typed_definesR . Inductive sorts : Set := | Param_S | ID_S | INT_S | Exp_S | Type_S . !Parameter Ident : Set. !Definition sort := sorts . !Definition Ident_Sort := ID_S . !Inductive Constructors := | INTC (n: nat) | VarC | FunC | FixC | AppC | LetC | ParamC | NumC | AddC | SubC | MulC | DivC | IfzC | IntTypeC | FunTypeC . !Definition constructors := Constructors . !Fixpoint get_sig (x: constructors) : list sort * sort := match x with | INTC n => ([],INT_S) | VarC => ([ID_S],Exp_S) | FunC => ([Param_S;Exp_S],Exp_S) | FixC => ([Param_S;Exp_S],Exp_S) | AppC => ([Exp_S;Exp_S],Exp_S) | LetC => ([ID_S;Type_S;Exp_S;Exp_S],Exp_S) | ParamC => ([ID_S;Type_S],Param_S) | NumC => ([INT_S],Exp_S) | AddC => ([Exp_S;Exp_S],Exp_S) | SubC => ([Exp_S;Exp_S],Exp_S) | MulC => ([Exp_S;Exp_S],Exp_S) | DivC => ([Exp_S;Exp_S],Exp_S) | IfzC => ([Exp_S;Exp_S;Exp_S],Exp_S) | IntTypeC => ([],Type_S) | FunTypeC => ([Type_S;Type_S],Type_S) end. … to PCF in Coq (+ manual proof of type preservation)
  66. 66. Summary
  67. 67. parser type checker code generator interpreter parser error recovery syntax highlighting outline code completion navigation type checker debugger syntax definition static semantics dynamic semantics abstract syntax type system operational semantics type soundness proof
  68. 68. Declarative Multi-Purpose Language Definition Syntax Definition Name Binding Type Constraints Dynamic Semantics Transform
  69. 69. Declarative Multi-Purpose Language Definition SDF3: Syntax Definition NaBL: Name Binding TS: Type Constraints DynSem: Dynamic Semantics Stratego: Transform
  70. 70. Declarative Multi-Purpose Language Definition SDF3: Syntax Definition NaBL: Name Binding TS: Type Constraints DynSem: Dynamic Semantics Stratego: Transform Spoofax Language Workbench

×