SlideShare a Scribd company logo
Eelco Visser
CS4200 Compiler Construction
TU Delft
December 2018
Lecture 14: Interpreters
Reading Material
2
!3
Design and implementation of DynSem, a
domain-specific language for the definition
of the dynamic semantics of programming
languages.
DynSem provides facilities for implicitly
passing memory (environment, store).
DynSem specifications can be compiled to or
interpreted as interpreters for the languages
they define.
http://dx.doi.org/10.4230/LIPIcs.RTA.2015.365
RTA 2015
!4
This paper describes the partial evaluation
of the DynSem meta-interpreter with an object
program.
The implementation makes use of Truffle a
framework for run-time (online) partial
evaluation.
Truffle gets most of it benefit from Graal,
an implementation of the JVM with special
support for partial evaluation.
https://doi.org/10.1145/3237009.3237018
ManLang 2018
Semantics
5
What is the meaning of a program?
6
meaning(p) = what happens when executing the
generated (byte) code to which p is compiled
source
code
parse generate
machine
code
check
meaning(p) = behavior(p)
What is the meaning of a program?
7
Mapping input to output
What is behavior?
Changes to state of the system
How can we observe behavior?
meaning(p) = behavior(p)
Which behavior is essential, which accidental?
How can we define the semantics of a program?
8
Is there a more direct description of semanticsL1?
Compiler defines translational semantics
semanticsL1(p) = semanticsL2(translate(p))
Requires understanding translate and semanticsL2
How do we know that translate is correct?
source
code
machine
code
translate
value
value
equal
run
semanticsL1
run
semanticsL2
Verifying Compiler Correctness
10
Direct semantics of source language provides a specification
How to check correctness?
Testing: for many programs p (and inputs i) test that
run(p)(i) == run(translate(p))(i)
Verification: for all programs p (and inputs i) prove that
run(p)(i) == run(translate(p))(i)
Validating Semantics
11
Is this the right semantics?
Testing: for many programs p (and inputs i) test that
run(p)(i) == v
Requires specifying desired <p, i, v> combinations

(aka unit testing)
The CompCert C Compiler
12
http://compcert.inria.fr/compcert-C.html
Compiler Construction Courses of the Future
13
Language Specification
syntax definition
name binding
type system
dynamic semantics
translation
transformation
safety properties
Language Testing
test generation
Language Implementation
generating implementations
from specifications
parser generation
constraint resolution
partial evaluation
…
Language Verification
proving correctness
Operational Semantics
14
What is the result of execution of a program?
- How is that result achieved?

Natural Semantics
- How is overall result of execution obtained?

Structural Operational Semantics
- What are the individual steps of an execution?

Defined using a transition system
!15
Operational Semantics
DynSem
16
!17
Design and implementation of DynSem, a
domain-specific language for the definition
of the dynamic semantics of programming
languages.
DynSem provides facilities for implicitly
passing memory (environment, store).
DynSem specifications can be compiled to or
interpreted as interpreters for the languages
they define.
http://dx.doi.org/10.4230/LIPIcs.RTA.2015.365
RTA 2015
Interpreters for Spoofax Languages
18
Example: DynSem Semantics of PAPL-Box
19
let
fac = box(0)
in
let f = fun (n) {
if (n == 0)
1
else
n * (unbox(fac) (n - 1))
end
}
in
setbox(fac, f);
unbox(fac)(10)
end
end
Features
- Arithmetic
- Booleans
- Comparisons
- Mutable variables
- Functions
- Boxes
Components
- Syntax in SDF3
- Dynamic Semantics in DynSem
Abstract Syntax from Concrete Syntax
20
module Arithmetic
imports Expressions
imports Common
context-free syntax
Expr.Num = INT
Expr.Plus = [[Expr] + [Expr]] {left}
Expr.Minus = [[Expr] - [Expr]] {left}
Expr.Times = [[Expr] * [Expr]] {left}
Expr.Mod = [[Expr] % [Expr]] {left}
context-free priorities
{left: Expr.Times Expr.Mod }
> {left: Expr.Minus Expr.Plus }
module Arithmetic-sig
imports Expressions-sig
imports Common-sig
signature
sorts Expr
constructors
Num : INT -> Expr
Plus : Expr * Expr -> Expr
Minus : Expr * Expr -> Expr
Times : Expr * Expr -> Expr
Mod : Expr * Expr -> Expr
src-gen/ds-signatures/Arithmetic-sig
Values, Meta-Variables, and Arrows
21
module values
signature
sorts V Unit
constructors
U : Unit
variables
v: V
module expressions
imports values
imports Expressions-sig
signature
arrows
Expr --> V
variables
e : Expr
x : String
Term Reduction Rules
22
module arithmetic-explicit
imports expressions primitives Arithmetic-sig
signature
constructors
NumV: Int -> V
rules
Num(__String2INT__(n)) --> NumV(str2int(n)).
Plus(e1, e2) --> NumV(plusI(i1, i2))
where
e1 --> NumV(i1); e2 --> NumV(i2).
Minus(e1, e2) --> NumV(minusI(i1, i2))
where
e1 --> NumV(i1); e2 --> NumV(i2).
module expressions
imports values
imports Expressions-sig
signature
arrows
Expr --> V
variables
e : Expr
x : String
Native Operations
23
module arithmetic-explicit
imports expressions primitives Arithmetic-sig
signature
constructors
NumV: Int -> V
rules
Num(__String2INT__(n)) --> NumV(str2int(n)).
Plus(e1, e2) --> NumV(plusI(i1, i2))
where
e1 --> NumV(i1); e2 --> NumV(i2).
Minus(e1, e2) --> NumV(minusI(i1, i2))
where
e1 --> NumV(i1); e2 --> NumV(i2).
module primitives
signature
native operators
str2int : String -> Int
plusI : Int * Int -> Int
minusI : Int * Int -> Int
public class Natives {
public static int plusI_2(int i1, int i2) {
return i1 + i2;
}
public static int str2int_1(String s) {
return Integer.parseInt(s);
}
}
Arrows as Coercions
24
rules
Plus(e1, e2) --> NumV(plusI(i1, i2))
where
e1 --> NumV(i1);
e2 --> NumV(i2).
rules
Plus(NumV(i1), NumV(i2)) --> NumV(plusI(i1, i2)).
signature
constructors
Plus : Expr * Expr -> Expr
NumV : Int -> V
arrows
Expr --> V
Modular
25
module boolean
imports Booleans-sig expressions
signature
constructors
BoolV : Bool -> V
rules
True() --> BoolV(true).
False() --> BoolV(false).
Not(BoolV(false)) --> BoolV(true).
Not(BoolV(true)) --> BoolV(false).
Or(BoolV(true), _) --> BoolV(true).
Or(BoolV(false), e) --> e.
And(BoolV(false), _) --> BoolV(false).
And(BoolV(true), e) --> e.
module arithmetic
imports Arithmetic-sig
imports expressions
imports primitives
signature
constructors
NumV: Int -> V
rules
Num(str) --> NumV(str2int(str)).
Plus(NumV(i1), NumV(i2)) --> NumV(plusI(i1, i2)).
Minus(NumV(i1), NumV(i2)) --> NumV(minusI(i1, i2)).
Times(NumV(i1), NumV(i2)) --> NumV(timesI(i1, i2)).
Mod(NumV(i1), NumV(i2)) --> NumV(modI(i1, i2)).
module comparison
imports Comparisons-sig arithmetic boolean
rules
Gt(NumV(i1), NumV(i2)) --> BoolV(gtI(i1, i2)).
Eq(NumV(i1), NumV(i2)) --> BoolV(eqI(i1, i2)).
Eq(BoolV(b1), BoolV(b2)) --> BoolV(eqB(b1, b2)).
Interpreter is not defined as a single match over sort
Control-Flow
26
module controlflow
imports ControlFlow-sig
imports expressions
imports boolean
rules
Seq(v, e2) --> e2.
If(BoolV(true), e1, _) --> e1.
If(BoolV(false), _, e2) --> e2.
module controlflow
imports ControlFlow-sig
imports expressions
imports boolean
rules
Seq(e1, e2) --> v2
where
e1 --> v1;
e2 --> v2.
If(e1, e2, e3) --> v
where
e1 --> BoolV(true);
e2 --> v.
If(e1, e2, e3) --> v
where
e1 --> BoolV(false);
e3 --> v.
Immutable Variables: Environment Passing
27
constructors
Let : ID * Expr * Expr -> Expr
Var : ID -> Expr
module variables
imports Variables-sig environment
rules
E |- Let(x, v: V, e2) --> v2
where
Env {x |--> v, E} |- e2 --> v2.
E |- Var(x) --> E[x].
module environment
imports values
signature
sort aliases
Env = Map<String, V>
variables
E : Env
First-Class Functions: Environment in Closure
28
module unary-functions
imports expressions environment
signature
constructors
ClosV : String * Expr * Env -> V
rules
E |- Fun(x, e) --> ClosV(x, e, E).
E |- App(e1, e2) --> v
where
E |- e1 --> ClosV(x, e, E');
E |- e2 --> v2;
Env {x |--> v2, E'} |- e --> v.
constructors
Fun : ID * Expr -> Expr
App : Expr * Expr -> Expr
module environment
imports values
signature
sort aliases
Env = Map<String, V>
variables
E : Env
Implicit Propagation
29
rules
E |- Plus(e1, e2) --> NumV(plusI(i1, i2))
where
E |- e1 --> NumV(i1);
E |- e2 --> NumV(i2).
rules
Plus(e1, e2) --> NumV(plusI(i1, i2))
where
e1 --> NumV(i1);
e2 --> NumV(i2).
rules
Plus(NumV(i1), NumV(i2)) --> NumV(plusI(i1, i2)).
Mutable Boxes: Store
30
module box
imports store arithmetic
signature
constructors
Box : Expr -> Expr
Unbox : Expr -> Expr
SetBox : Expr * Expr -> Expr
constructors
BoxV: Int -> V
rules
Box(e) :: S --> BoxV(loc) :: Store {loc |--> v, S'}
where e :: S --> v :: S';
fresh => loc.
Unbox(BoxV(loc)) :: S --> S[loc].
SetBox(BoxV(loc), v) :: S --> v :: Store {loc |--> v, S}.
module store
imports values
signature
sort aliases
Store = Map<Int, V>
variables
S : Store
Mutable Variables: Environment + Store
31
constructors
Let : ID * Expr * Expr -> Expr
Var : ID -> Expr
Set : String * Expr -> Expr
module variables-mutable
imports Variables-sig store
rules
E |- Var(x) :: S --> v :: S
where E[x] => loc; S[loc] => v.
E |- Let(x, v, e2) :: S1 --> v2 :: S3
where
fresh => loc;
{loc |--> v, S1} => S2;
Env {x |--> loc, E} |- e2 :: S2 --> v2 :: S3.
E |- Set(x, v) :: S --> v :: Store {loc |--> v, S}
where E[x] => loc.
module store
imports values
signature
sort aliases
Env = Map<ID, Int>
Store = Map<Int, V>
variables
E : Env
S : Store
Implicit Store Threading
32
rules
E |- Plus(e1, e2) :: S1 --> NumV(plusI(i1, i2)) :: S3
where
E |- e1 :: S1 --> NumV(i1) :: S2;
E |- e2 :: S2 --> NumV(i2) :: S3.
rules
Plus(e1, e2) --> NumV(plusI(i1, i2))
where
e1 --> NumV(i1);
e2 --> NumV(i2).
rules
Plus(NumV(i1), NumV(i2)) --> NumV(plusI(i1, i2)).
Abstraction: Env/Store Meta Functions
33
module store
imports values
signature
sort aliases
Env = Map<String, Int>
Store = Map<Int, V>
variables
E : Env
S : Store
arrows
readVar : String --> V
bindVar : String * V --> Env
writeVar : String * V --> V
allocate : V --> Int
write : Int * V --> V
read : Int --> V
rules
allocate(v) --> loc
where
fresh => loc;
write(loc, v) --> _.
write(loc, v) :: S -->
v :: Store {loc |--> v, S}.
read(loc) :: S --> S[loc] :: S.
rules
bindVar(x, v) --> {x |--> loc}
where allocate(v) --> loc.
E |- readVar(x) --> read(E[x]).
E |- writeVar(x, v) --> write(E[x], v).
Boxes with Env/Store Meta Functions
34
module boxes
signature
constructors
Box : Expr -> Expr
Unbox : Expr -> Expr
SetBox : Expr * Expr -> Expr
constructors
BoxV: V -> V
rules
Box(v) --> BoxV(NumV(allocate(v))).
Unbox(BoxV(NumV(loc))) --> read(loc).
SetBox(BoxV(NumV(loc)), v) --> write(loc, v).
Mutable Variables with Env/Store Meta Functions
35
module variables
imports expressions store
rules
Var(x) --> readVar(x).
E |- Let(x, v1, e) --> v2
where
bindVar(x, v1) --> E';
Env {E', E} |- e --> v2.
Set(x, v) --> v
where
writeVar(x, v) --> _.
constructors
Let : String * Expr * Expr -> Expr
Var : String -> Expr
Set : String * Expr -> Expr
Functions with Multiple Arguments
36
module functions
imports Functions-sig
imports variables
signature
constructors
ClosV : List(ID) * Expr * Env -> V
bindArgs : List(ID) * List(Expr) --> Env
rules
E |- Fun(xs, e) --> ClosV(xs, e, E).
App(ClosV(xs, e_body, E_clos), es) --> v'
where
bindArgs(xs, es) --> E_params;
Env {E_params, E_clos} |- e_body --> v'.
bindArgs([], []) --> {}.
bindArgs([x | xs], [e | es]) --> {E, E'}
where
bindVar(x, e) --> E;
bindArgs(xs, es) --> E'.
Tiger in DynSem
37https://github.com/MetaBorgCube/metaborg-tiger
Interpreter Generation
38
Generating AST Interpreter from Dynamic Semantics
39
DynSem
Specification
AST Value
Interpreter
in Java
DynSem Meta-Interpreter
40
DynSem
Specification
AST
AST Rep. of
DynSem Rules
Value
Term Rep.
in Java
DynSem
Interpreter
Truffle: Partial Evaluation of AST Interpreters
41
Würthinger et al. One VM to rule them all. Onward! 2013
!42
This paper describes the partial evaluation
of the DynSem meta-interpreter with an object
program.
The implementation makes use of Truffle a
framework for run-time (online) partial
evaluation.
Truffle gets most of it benefit from Graal,
an implementation of the JVM with special
support for partial evaluation.
https://doi.org/10.1145/3237009.3237018
ManLang 2018
Partial Evaluation
43
!44
!45
!46
!47
!48
!49
!50
!51
!52
!53
!54
How is this relevant for compilers and interpreters?
!55
!56
!57
!58
!59
!60
!61
!62
Instance-specific program
- Can make very efficient

- Hard to maintain (performance interventions tangled with implementation)

- Hard to reuse for variants

Generic program
- Parametric in instances 

- Easy to maintain

- Easy to reuse for variants 

- Not efficient: overhead of parametricity 

Partial evaluation
- Specialize generic program to specific instances
!63
Partial Evaluation: Summary
Specializing a meta-interpreter
- Meta-interpreter: DynSem specifications executed using interpreter

- Partial evaluation: remove two stages of interpretation

- Encouraging results using Truffle/Graal

- How close to native speed can we get?

Generate byte code compiler
- Input: DynSem specification

- Output: compiler from source to (custom) byte code 

- Output: byte code interpreter
!64
Some Research Projects
Partial evaluation
- Offline vs online partial evaluation

- Binding-time analysis

Multi-stage programming
- Explicit binding time annotations

Just-in-time (JIT) compilation
- Interpreter selectively compiles code (fragments) to machine code

Techniques for partial evaluation
- Meta-tracing

- Run-time specialisation (Truffle/Graal)
!65
Further Study
!66
Except where otherwise noted, this work is licensed under

More Related Content

PDF
Compiler Construction | Lecture 2 | Declarative Syntax Definition
PDF
Declarative Type System Specification with Statix
PDF
CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
PDF
CS4200 2019 | Lecture 2 | syntax-definition
PDF
Compiler Construction | Lecture 8 | Type Constraints
PDF
CS4200 2019 | Lecture 4 | Syntactic Services
PDF
Compiler Construction | Lecture 9 | Constraint Resolution
PDF
Compiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 2 | Declarative Syntax Definition
Declarative Type System Specification with Statix
CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 2 | syntax-definition
Compiler Construction | Lecture 8 | Type Constraints
CS4200 2019 | Lecture 4 | Syntactic Services
Compiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 5 | Transformation by Term Rewriting

What's hot (20)

PDF
Compiler Construction | Lecture 12 | Virtual Machines
PDF
CS4200 2019 | Lecture 3 | Parsing
PPTX
Chapter 22. Lambda Expressions and LINQ
PPTX
07. Java Array, Set and Maps
PDF
Compiler Construction | Lecture 13 | Code Generation
PDF
Writing Parsers and Compilers with PLY
PDF
C++11 & C++14
PDF
Compiler Construction | Lecture 3 | Syntactic Editor Services
PDF
Declare Your Language: Syntax Definition
PPTX
PDF
Что нам готовит грядущий C#7?
PPTX
PPTX
06.Loops
PDF
C++11
PPTX
07. Arrays
PPTX
C Assignment Help
PPTX
More on Lex
PDF
Laziness, trampolines, monoids and other functional amenities: this is not yo...
PPTX
C++ 11 Features
Compiler Construction | Lecture 12 | Virtual Machines
CS4200 2019 | Lecture 3 | Parsing
Chapter 22. Lambda Expressions and LINQ
07. Java Array, Set and Maps
Compiler Construction | Lecture 13 | Code Generation
Writing Parsers and Compilers with PLY
C++11 & C++14
Compiler Construction | Lecture 3 | Syntactic Editor Services
Declare Your Language: Syntax Definition
Что нам готовит грядущий C#7?
06.Loops
C++11
07. Arrays
C Assignment Help
More on Lex
Laziness, trampolines, monoids and other functional amenities: this is not yo...
C++ 11 Features
Ad

Similar to Compiler Construction | Lecture 14 | Interpreters (20)

PDF
Dynamic Semantics Specification and Interpreter Generation
PDF
Dynamic Semantics
PDF
Declare Your Language: Dynamic Semantics
PDF
Term Rewriting
PDF
Static name resolution
PDF
Declare Your Language (at DLS)
PDF
Scope Graphs: A fresh look at name binding in programming languages
PDF
Compiling fµn language
PDF
Declare Your Language: Type Checking
PDF
Decaf language specification
PDF
Separation of Concerns in Language Definition
PPT
Ch6.ppt
DOC
Chapter 1 1
PPT
458237.-Compiler-Design-Intermediate-code-generation.ppt
PDF
Declare Your Language: Transformation by Strategic Term Rewriting
PPTX
Chapter 6 - Intermediate Languages.pptxjfjgj
PDF
Syntax Analysis.pdf
PDF
Grammarware Memes
PDF
Name binding with scope graphs
Dynamic Semantics Specification and Interpreter Generation
Dynamic Semantics
Declare Your Language: Dynamic Semantics
Term Rewriting
Static name resolution
Declare Your Language (at DLS)
Scope Graphs: A fresh look at name binding in programming languages
Compiling fµn language
Declare Your Language: Type Checking
Decaf language specification
Separation of Concerns in Language Definition
Ch6.ppt
Chapter 1 1
458237.-Compiler-Design-Intermediate-code-generation.ppt
Declare Your Language: Transformation by Strategic Term Rewriting
Chapter 6 - Intermediate Languages.pptxjfjgj
Syntax Analysis.pdf
Grammarware Memes
Name binding with scope graphs
Ad

More from Eelco Visser (15)

PDF
CS4200 2019 Lecture 1: Introduction
PDF
A Direct Semantics of Declarative Disambiguation Rules
PDF
Compiler Construction | Lecture 17 | Beyond Compiler Construction
PDF
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
PDF
Compiler Construction | Lecture 15 | Memory Management
PDF
Compiler Construction | Lecture 11 | Monotone Frameworks
PDF
Compiler Construction | Lecture 10 | Data-Flow Analysis
PDF
Compiler Construction | Lecture 7 | Type Checking
PDF
Compiler Construction | Lecture 6 | Introduction to Static Analysis
PDF
Compiler Construction | Lecture 4 | Parsing
PDF
Compiler Construction | Lecture 1 | What is a compiler?
PDF
Declare Your Language: Virtual Machines & Code Generation
PDF
Declare Your Language: Constraint Resolution 2
PDF
Declare Your Language: Constraint Resolution 1
PDF
Declare Your Language: Name Resolution
CS4200 2019 Lecture 1: Introduction
A Direct Semantics of Declarative Disambiguation Rules
Compiler Construction | Lecture 17 | Beyond Compiler Construction
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Compiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 4 | Parsing
Compiler Construction | Lecture 1 | What is a compiler?
Declare Your Language: Virtual Machines & Code Generation
Declare Your Language: Constraint Resolution 2
Declare Your Language: Constraint Resolution 1
Declare Your Language: Name Resolution

Recently uploaded (20)

PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PPTX
history of c programming in notes for students .pptx
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
How Creative Agencies Leverage Project Management Software.pdf
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
AI in Product Development-omnex systems
PPTX
L1 - Introduction to python Backend.pptx
PDF
Softaken Excel to vCard Converter Software.pdf
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
Digital Strategies for Manufacturing Companies
PDF
top salesforce developer skills in 2025.pdf
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
history of c programming in notes for students .pptx
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
How Creative Agencies Leverage Project Management Software.pdf
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
CHAPTER 2 - PM Management and IT Context
Upgrade and Innovation Strategies for SAP ERP Customers
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
2025 Textile ERP Trends: SAP, Odoo & Oracle
AI in Product Development-omnex systems
L1 - Introduction to python Backend.pptx
Softaken Excel to vCard Converter Software.pdf
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Wondershare Filmora 15 Crack With Activation Key [2025
Design an Analysis of Algorithms I-SECS-1021-03
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Digital Strategies for Manufacturing Companies
top salesforce developer skills in 2025.pdf

Compiler Construction | Lecture 14 | Interpreters

  • 1. Eelco Visser CS4200 Compiler Construction TU Delft December 2018 Lecture 14: Interpreters
  • 3. !3 Design and implementation of DynSem, a domain-specific language for the definition of the dynamic semantics of programming languages. DynSem provides facilities for implicitly passing memory (environment, store). DynSem specifications can be compiled to or interpreted as interpreters for the languages they define. http://dx.doi.org/10.4230/LIPIcs.RTA.2015.365 RTA 2015
  • 4. !4 This paper describes the partial evaluation of the DynSem meta-interpreter with an object program. The implementation makes use of Truffle a framework for run-time (online) partial evaluation. Truffle gets most of it benefit from Graal, an implementation of the JVM with special support for partial evaluation. https://doi.org/10.1145/3237009.3237018 ManLang 2018
  • 6. What is the meaning of a program? 6 meaning(p) = what happens when executing the generated (byte) code to which p is compiled source code parse generate machine code check meaning(p) = behavior(p)
  • 7. What is the meaning of a program? 7 Mapping input to output What is behavior? Changes to state of the system How can we observe behavior? meaning(p) = behavior(p) Which behavior is essential, which accidental?
  • 8. How can we define the semantics of a program? 8 Is there a more direct description of semanticsL1? Compiler defines translational semantics semanticsL1(p) = semanticsL2(translate(p)) Requires understanding translate and semanticsL2 How do we know that translate is correct?
  • 10. Verifying Compiler Correctness 10 Direct semantics of source language provides a specification How to check correctness? Testing: for many programs p (and inputs i) test that run(p)(i) == run(translate(p))(i) Verification: for all programs p (and inputs i) prove that run(p)(i) == run(translate(p))(i)
  • 11. Validating Semantics 11 Is this the right semantics? Testing: for many programs p (and inputs i) test that run(p)(i) == v Requires specifying desired <p, i, v> combinations
 (aka unit testing)
  • 12. The CompCert C Compiler 12 http://compcert.inria.fr/compcert-C.html
  • 13. Compiler Construction Courses of the Future 13 Language Specification syntax definition name binding type system dynamic semantics translation transformation safety properties Language Testing test generation Language Implementation generating implementations from specifications parser generation constraint resolution partial evaluation … Language Verification proving correctness
  • 15. What is the result of execution of a program? - How is that result achieved? Natural Semantics - How is overall result of execution obtained? Structural Operational Semantics - What are the individual steps of an execution? Defined using a transition system !15 Operational Semantics
  • 17. !17 Design and implementation of DynSem, a domain-specific language for the definition of the dynamic semantics of programming languages. DynSem provides facilities for implicitly passing memory (environment, store). DynSem specifications can be compiled to or interpreted as interpreters for the languages they define. http://dx.doi.org/10.4230/LIPIcs.RTA.2015.365 RTA 2015
  • 18. Interpreters for Spoofax Languages 18
  • 19. Example: DynSem Semantics of PAPL-Box 19 let fac = box(0) in let f = fun (n) { if (n == 0) 1 else n * (unbox(fac) (n - 1)) end } in setbox(fac, f); unbox(fac)(10) end end Features - Arithmetic - Booleans - Comparisons - Mutable variables - Functions - Boxes Components - Syntax in SDF3 - Dynamic Semantics in DynSem
  • 20. Abstract Syntax from Concrete Syntax 20 module Arithmetic imports Expressions imports Common context-free syntax Expr.Num = INT Expr.Plus = [[Expr] + [Expr]] {left} Expr.Minus = [[Expr] - [Expr]] {left} Expr.Times = [[Expr] * [Expr]] {left} Expr.Mod = [[Expr] % [Expr]] {left} context-free priorities {left: Expr.Times Expr.Mod } > {left: Expr.Minus Expr.Plus } module Arithmetic-sig imports Expressions-sig imports Common-sig signature sorts Expr constructors Num : INT -> Expr Plus : Expr * Expr -> Expr Minus : Expr * Expr -> Expr Times : Expr * Expr -> Expr Mod : Expr * Expr -> Expr src-gen/ds-signatures/Arithmetic-sig
  • 21. Values, Meta-Variables, and Arrows 21 module values signature sorts V Unit constructors U : Unit variables v: V module expressions imports values imports Expressions-sig signature arrows Expr --> V variables e : Expr x : String
  • 22. Term Reduction Rules 22 module arithmetic-explicit imports expressions primitives Arithmetic-sig signature constructors NumV: Int -> V rules Num(__String2INT__(n)) --> NumV(str2int(n)). Plus(e1, e2) --> NumV(plusI(i1, i2)) where e1 --> NumV(i1); e2 --> NumV(i2). Minus(e1, e2) --> NumV(minusI(i1, i2)) where e1 --> NumV(i1); e2 --> NumV(i2). module expressions imports values imports Expressions-sig signature arrows Expr --> V variables e : Expr x : String
  • 23. Native Operations 23 module arithmetic-explicit imports expressions primitives Arithmetic-sig signature constructors NumV: Int -> V rules Num(__String2INT__(n)) --> NumV(str2int(n)). Plus(e1, e2) --> NumV(plusI(i1, i2)) where e1 --> NumV(i1); e2 --> NumV(i2). Minus(e1, e2) --> NumV(minusI(i1, i2)) where e1 --> NumV(i1); e2 --> NumV(i2). module primitives signature native operators str2int : String -> Int plusI : Int * Int -> Int minusI : Int * Int -> Int public class Natives { public static int plusI_2(int i1, int i2) { return i1 + i2; } public static int str2int_1(String s) { return Integer.parseInt(s); } }
  • 24. Arrows as Coercions 24 rules Plus(e1, e2) --> NumV(plusI(i1, i2)) where e1 --> NumV(i1); e2 --> NumV(i2). rules Plus(NumV(i1), NumV(i2)) --> NumV(plusI(i1, i2)). signature constructors Plus : Expr * Expr -> Expr NumV : Int -> V arrows Expr --> V
  • 25. Modular 25 module boolean imports Booleans-sig expressions signature constructors BoolV : Bool -> V rules True() --> BoolV(true). False() --> BoolV(false). Not(BoolV(false)) --> BoolV(true). Not(BoolV(true)) --> BoolV(false). Or(BoolV(true), _) --> BoolV(true). Or(BoolV(false), e) --> e. And(BoolV(false), _) --> BoolV(false). And(BoolV(true), e) --> e. module arithmetic imports Arithmetic-sig imports expressions imports primitives signature constructors NumV: Int -> V rules Num(str) --> NumV(str2int(str)). Plus(NumV(i1), NumV(i2)) --> NumV(plusI(i1, i2)). Minus(NumV(i1), NumV(i2)) --> NumV(minusI(i1, i2)). Times(NumV(i1), NumV(i2)) --> NumV(timesI(i1, i2)). Mod(NumV(i1), NumV(i2)) --> NumV(modI(i1, i2)). module comparison imports Comparisons-sig arithmetic boolean rules Gt(NumV(i1), NumV(i2)) --> BoolV(gtI(i1, i2)). Eq(NumV(i1), NumV(i2)) --> BoolV(eqI(i1, i2)). Eq(BoolV(b1), BoolV(b2)) --> BoolV(eqB(b1, b2)). Interpreter is not defined as a single match over sort
  • 26. Control-Flow 26 module controlflow imports ControlFlow-sig imports expressions imports boolean rules Seq(v, e2) --> e2. If(BoolV(true), e1, _) --> e1. If(BoolV(false), _, e2) --> e2. module controlflow imports ControlFlow-sig imports expressions imports boolean rules Seq(e1, e2) --> v2 where e1 --> v1; e2 --> v2. If(e1, e2, e3) --> v where e1 --> BoolV(true); e2 --> v. If(e1, e2, e3) --> v where e1 --> BoolV(false); e3 --> v.
  • 27. Immutable Variables: Environment Passing 27 constructors Let : ID * Expr * Expr -> Expr Var : ID -> Expr module variables imports Variables-sig environment rules E |- Let(x, v: V, e2) --> v2 where Env {x |--> v, E} |- e2 --> v2. E |- Var(x) --> E[x]. module environment imports values signature sort aliases Env = Map<String, V> variables E : Env
  • 28. First-Class Functions: Environment in Closure 28 module unary-functions imports expressions environment signature constructors ClosV : String * Expr * Env -> V rules E |- Fun(x, e) --> ClosV(x, e, E). E |- App(e1, e2) --> v where E |- e1 --> ClosV(x, e, E'); E |- e2 --> v2; Env {x |--> v2, E'} |- e --> v. constructors Fun : ID * Expr -> Expr App : Expr * Expr -> Expr module environment imports values signature sort aliases Env = Map<String, V> variables E : Env
  • 29. Implicit Propagation 29 rules E |- Plus(e1, e2) --> NumV(plusI(i1, i2)) where E |- e1 --> NumV(i1); E |- e2 --> NumV(i2). rules Plus(e1, e2) --> NumV(plusI(i1, i2)) where e1 --> NumV(i1); e2 --> NumV(i2). rules Plus(NumV(i1), NumV(i2)) --> NumV(plusI(i1, i2)).
  • 30. Mutable Boxes: Store 30 module box imports store arithmetic signature constructors Box : Expr -> Expr Unbox : Expr -> Expr SetBox : Expr * Expr -> Expr constructors BoxV: Int -> V rules Box(e) :: S --> BoxV(loc) :: Store {loc |--> v, S'} where e :: S --> v :: S'; fresh => loc. Unbox(BoxV(loc)) :: S --> S[loc]. SetBox(BoxV(loc), v) :: S --> v :: Store {loc |--> v, S}. module store imports values signature sort aliases Store = Map<Int, V> variables S : Store
  • 31. Mutable Variables: Environment + Store 31 constructors Let : ID * Expr * Expr -> Expr Var : ID -> Expr Set : String * Expr -> Expr module variables-mutable imports Variables-sig store rules E |- Var(x) :: S --> v :: S where E[x] => loc; S[loc] => v. E |- Let(x, v, e2) :: S1 --> v2 :: S3 where fresh => loc; {loc |--> v, S1} => S2; Env {x |--> loc, E} |- e2 :: S2 --> v2 :: S3. E |- Set(x, v) :: S --> v :: Store {loc |--> v, S} where E[x] => loc. module store imports values signature sort aliases Env = Map<ID, Int> Store = Map<Int, V> variables E : Env S : Store
  • 32. Implicit Store Threading 32 rules E |- Plus(e1, e2) :: S1 --> NumV(plusI(i1, i2)) :: S3 where E |- e1 :: S1 --> NumV(i1) :: S2; E |- e2 :: S2 --> NumV(i2) :: S3. rules Plus(e1, e2) --> NumV(plusI(i1, i2)) where e1 --> NumV(i1); e2 --> NumV(i2). rules Plus(NumV(i1), NumV(i2)) --> NumV(plusI(i1, i2)).
  • 33. Abstraction: Env/Store Meta Functions 33 module store imports values signature sort aliases Env = Map<String, Int> Store = Map<Int, V> variables E : Env S : Store arrows readVar : String --> V bindVar : String * V --> Env writeVar : String * V --> V allocate : V --> Int write : Int * V --> V read : Int --> V rules allocate(v) --> loc where fresh => loc; write(loc, v) --> _. write(loc, v) :: S --> v :: Store {loc |--> v, S}. read(loc) :: S --> S[loc] :: S. rules bindVar(x, v) --> {x |--> loc} where allocate(v) --> loc. E |- readVar(x) --> read(E[x]). E |- writeVar(x, v) --> write(E[x], v).
  • 34. Boxes with Env/Store Meta Functions 34 module boxes signature constructors Box : Expr -> Expr Unbox : Expr -> Expr SetBox : Expr * Expr -> Expr constructors BoxV: V -> V rules Box(v) --> BoxV(NumV(allocate(v))). Unbox(BoxV(NumV(loc))) --> read(loc). SetBox(BoxV(NumV(loc)), v) --> write(loc, v).
  • 35. Mutable Variables with Env/Store Meta Functions 35 module variables imports expressions store rules Var(x) --> readVar(x). E |- Let(x, v1, e) --> v2 where bindVar(x, v1) --> E'; Env {E', E} |- e --> v2. Set(x, v) --> v where writeVar(x, v) --> _. constructors Let : String * Expr * Expr -> Expr Var : String -> Expr Set : String * Expr -> Expr
  • 36. Functions with Multiple Arguments 36 module functions imports Functions-sig imports variables signature constructors ClosV : List(ID) * Expr * Env -> V bindArgs : List(ID) * List(Expr) --> Env rules E |- Fun(xs, e) --> ClosV(xs, e, E). App(ClosV(xs, e_body, E_clos), es) --> v' where bindArgs(xs, es) --> E_params; Env {E_params, E_clos} |- e_body --> v'. bindArgs([], []) --> {}. bindArgs([x | xs], [e | es]) --> {E, E'} where bindVar(x, e) --> E; bindArgs(xs, es) --> E'.
  • 39. Generating AST Interpreter from Dynamic Semantics 39 DynSem Specification AST Value Interpreter in Java
  • 40. DynSem Meta-Interpreter 40 DynSem Specification AST AST Rep. of DynSem Rules Value Term Rep. in Java DynSem Interpreter
  • 41. Truffle: Partial Evaluation of AST Interpreters 41 Würthinger et al. One VM to rule them all. Onward! 2013
  • 42. !42 This paper describes the partial evaluation of the DynSem meta-interpreter with an object program. The implementation makes use of Truffle a framework for run-time (online) partial evaluation. Truffle gets most of it benefit from Graal, an implementation of the JVM with special support for partial evaluation. https://doi.org/10.1145/3237009.3237018 ManLang 2018
  • 44. !44
  • 45. !45
  • 46. !46
  • 47. !47
  • 48. !48
  • 49. !49
  • 50. !50
  • 51. !51
  • 52. !52
  • 53. !53
  • 54. !54 How is this relevant for compilers and interpreters?
  • 55. !55
  • 56. !56
  • 57. !57
  • 58. !58
  • 59. !59
  • 60. !60
  • 61. !61
  • 62. !62
  • 63. Instance-specific program - Can make very efficient - Hard to maintain (performance interventions tangled with implementation) - Hard to reuse for variants Generic program - Parametric in instances - Easy to maintain - Easy to reuse for variants - Not efficient: overhead of parametricity Partial evaluation - Specialize generic program to specific instances !63 Partial Evaluation: Summary
  • 64. Specializing a meta-interpreter - Meta-interpreter: DynSem specifications executed using interpreter - Partial evaluation: remove two stages of interpretation - Encouraging results using Truffle/Graal - How close to native speed can we get? Generate byte code compiler - Input: DynSem specification - Output: compiler from source to (custom) byte code - Output: byte code interpreter !64 Some Research Projects
  • 65. Partial evaluation - Offline vs online partial evaluation - Binding-time analysis Multi-stage programming - Explicit binding time annotations Just-in-time (JIT) compilation - Interpreter selectively compiles code (fragments) to machine code Techniques for partial evaluation - Meta-tracing - Run-time specialisation (Truffle/Graal) !65 Further Study
  • 66. !66 Except where otherwise noted, this work is licensed under