This presentation is an HTML5 website
Press → key to advance.
Jeremy Voorhis
Domain Specific Languages are programming languages biased towards a particular problem domain.
The embedded language technique dates back to 1966, in Peter Landin's The Next 700 Programming Languages
Interpreted or compiled?
External DSLs define a custom syntax and semantics.
Embedded DSLs reuse the syntax and semantics of their host language.
instr 1
asig oscil 10000, 440, 1
out asig
endin
f1 0 256 10 1 ; a sine wave function table
; a pentatonic scale
i1 0 .5 0 8.01
i1 .5 . . 8.03
i1 1.0 . . 8.06
i1 1.5 . . 8.08
i1 2.0 . . 8.10
e
// patch
adc => DelayL delay => dac;
// set delay parameters
.75::second => delay.max => delay.delay;
// infinite time loop
while( true ) 1::second => now;
random = +(12345)~*(1103515245);
noise = random/2147483647.0;
process = noise * vslider("vol", 0, 0, 1, 0.1);
reusable code for doing compilery thingsChris Lattner
IR language as linguistic switchbox connecting all stages of compilationWesley Smith, Graham Wakefield (2009) Augmenting Computer Music With Just-In-Time Compilation
; ModuleID = 'Factorial'
define i64 @fac(i64) {
; <label>:1
%2 = icmp eq i64 %0, 1 ; <i1> [#uses=1]
br i1 %2, label %7, label %3
; <label>:3 ; preds = %1
%4 = sub i64 %0, 1 ; <i64> [#uses=1]
%5 = call i64 @fac(i64 %4) ; <i64> [#uses=1]
%6 = mul i64 %0, %5 ; <i64> [#uses=1]
br label %7
; <label>:7 ; preds = %3, %1
%8 = phi i64 [ 1, %1 ], [ %6, %3 ] ; <i64> [#uses=1]
ret i64 %8
}
mod = LLVM::Module.create("Factorial")
mod.functions.add(
"fac",
[LLVM::Int], LLVM::Int
) do |fac, p0|
entry = fac.basic_blocks.append
recur = fac.basic_blocks.append
result = fac.basic_blocks.append
# continued →
end
builder = LLVM::Builder.create
builder.position_at_end(entry)
builder.cond(
builder.icmp(:eq, p0, LLVM::Int(1)),
result, recur)
builder.position_at_end(recur)
fac_call = builder.call(fac,
builder.sub(p0, LLVM::Int(1)))
fac_result = builder.mul(p0, fac_call)
builder.br(result)
builder.position_at_end(result)
builder.ret(
builder.phi(LLVM::Int,
LLVM::Int(1), entry,
fac_result, recur))
; ModuleID = 'Factorial'
define i64 @fac(i64) {
; <label>:1
%2 = icmp eq i64 %0, 1 ; <i1> [#uses=1]
br i1 %2, label %7, label %3
; <label>:3 ; preds = %1
%4 = sub i64 %0, 1 ; <i64> [#uses=1]
%5 = call i64 @fac(i64 %4) ; <i64> [#uses=1]
%6 = mul i64 %0, %5 ; <i64> [#uses=1]
br label %7
; <label>:7 ; preds = %3, %1
%8 = phi i64 [ 1, %1 ], [ %6, %3 ] ; <i64> [#uses=1]
ret i64 %8
}
Event = Rest duration
| Note duration params
| Seq Event Event
| Par Event Event
rest(1) & note(1, fs5) & note(1, a5) &
note(1, g5) & note(1, fs5) & note(1, cs5) &
note(1, b4) & note(1, cs5) & note(1, d5) &
note(3, a4)
Time = ℝ
Amplitude = ℝ
Sound = Time → Amplitude
Time = Float
Amplitude = Float
Sound = Time → Amplitude
class Oscil < Siren::Voice
param :freq, :float, 0.0
param :amp, :float, 0.5
def render(gt, vt, c)
cos(2 * PI * freq * vt)
end
end
AST = FloatLit Float
| FAdd AST AST
| ...
| Cos AST
| ...
| IntLit Int
| ...
E = Int z | E + E
〚Int z〛= z
〚x + y〛=〚x〛+〚y〛
Hutton (1998) Fold and Unfold for Program Semantics
An embedded DSL's user interface