기계 중심의 언어dreameye/pl/slide/pl3-print.pdf · 2011-03-17 · 기계 중심의 언어...
TRANSCRIPT
기계 중심의 언어•제어 흐름 control flow
•명령문 statement
•기계상태 memory + cpu + keyboard + monitor
집합(타입)을 만드는 방법
M � E ⇓ vM � S ⇓ M �
E and S are syntactic objects
v and M are semantic objects
v ∈ Val = Z + B
M ∈ Memory = Addr → Val
A+B separated sum {a, b, ...}
A×B cartesian product {�a, b�, ...}
A → B finite functions {f, g, ..}
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
x := 0;y := 0;while x < 11 doy := y + x;x := x + 1;
write y
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
1
M � E ⇓ vM � S ⇓ M �
E and S are syntactic objects
v and M are semantic objects
v ∈ Val = Z + B
M ∈ Memory = Addr → Val
A+B separated sum {a, b, ...}
A×B cartesian product {�a, b�, ...}
A → B finite functions {f, g, ..}
f ∈ A → B iff dom(f) is a finite subset of A.
f [b/a](x) =
�b if x = a
f(x) otherwise
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
x := 0;y := 0;while x < 11 doy := y + x;x := x + 1;
write y
1
Imperative Language: SyntaxProgram
P → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
Γ � n : Int (constant)
Γ(x) = τ
Γ � x : τ (variable)
Γ � E1 : τ1 Γ, x : τ1 � E2 : τ2Γ � let x := E1 in E2 : τ2 (letin)
Γ � E : IntΓ � −E : Int
Γ � E1 : Int Γ � E2 : IntΓ � E1 + E2 : Int
[[ n ]]σ = n[[ x ]]σ = σ(x)
[[ let x := E1 in E2 ]]σ = [[ E2 ]]σ{x �→ [[ E1 ]]σ}[[ −E ]]σ = −[[ E ]]σ
[[ E1 + E2 ]]σ = [[ E1 ]]σ + [[ E2 ]]σ
[[ E1 = E2 ]] = [[ E1 ]]∅eq[[ E2 ]]∅[[ E1 ≤ E2 ]] = [[ E1 ]]∅le[[ E2 ]]∅
1
•Statement S: 프로그램 명령문은 기계의 상태 / 메모리를 변화시킴
•Expression E: 프로그램식은 값을 계산
Imperative Language: Semantics
M � E ⇓ v
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
x := 0;y := 0;while x < 11 doy := y + x;x := x + 1;
write y
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
Γ � n : Int (constant)
Γ(x) = τ
Γ � x : τ (variable)
Γ � E1 : τ1 Γ, x : τ1 � E2 : τ2Γ � let x := E1 in E2 : τ2 (letin)
Γ � E : IntΓ � −E : Int
Γ � E1 : Int Γ � E2 : IntΓ � E1 + E2 : Int
1
M � E ⇓ vM � S ⇓ M �
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
x := 0;y := 0;while x < 11 do
y := y + x;x := x + 1;
write y
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
Γ � n : Int (constant)
Γ(x) = τ
Γ � x : τ (variable)
Γ � E1 : τ1 Γ, x : τ1 � E2 : τ2Γ � let x := E1 in E2 : τ2 (letin)
Γ � E : IntΓ � −E : Int
Γ � E1 : Int Γ � E2 : IntΓ � E1 + E2 : Int
1
의미 표현Semantic Objects
값
메모리
M � E ⇓ vM � S ⇓ M �
E and S are syntactic objects
v and M are semantic objects
v ∈ Val = Z + B
M ∈ Memory = Addr → Val
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
x := 0;y := 0;while x < 11 doy := y + x;x := x + 1;
write y
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
1
이것들이 돌아다니는 공간을 정의
M � E ⇓ vM � S ⇓ M �
E and S are syntactic objects
v and M are semantic objects
v ∈ Val = Z + B
M ∈ Memory = Addr → Val
n ∈ Z
b ∈ B = {T, F}
x ∈ Addr = Id
A+B separated sum {a, b, ...}
A×B cartesian product {�a, b�, ...}
A → B finite functions {f, g, ..}
f ∈ A → B iff dom(f) is a finite subset of A.
f [b/a](x) =
�b if x = a
f(x) otherwise
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
1
주소
프로그램식의 의미M � E ⇓ v
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
x := 0;y := 0;while x < 11 doy := y + x;x := x + 1;
write y
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
Γ � n : Int (constant)
Γ(x) = τ
Γ � x : τ (variable)
Γ � E1 : τ1 Γ, x : τ1 � E2 : τ2Γ � let x := E1 in E2 : τ2 (letin)
Γ � E : IntΓ � −E : Int
Γ � E1 : Int Γ � E2 : IntΓ � E1 + E2 : Int
1
M � n ⇓ n
M � true ⇓ T
M � false ⇓ F
M(x) = v
M � x ⇓ v
M � E1 ⇓ v1 M � E2 ⇓ v2 v = v1 + v2M � E1 + E2 ⇓ v
M � E1 ⇓ v M � E2 ⇓ vM � E1 = E2 ⇓ T
M � E1 ⇓ v1 M � E2 ⇓ v2 v1 �= v2M � E1 = E2 ⇓ F
M � E ⇓ vM � S ⇓ M �
E and S are syntactic objects
v and M are semantic objects
v ∈ Val = Z + B
M ∈ Memory = Addr → Val
n ∈ Z
b ∈ B = {T, F}
x ∈ Addr = Id
1
명령문의 의미
M � n ⇓ n
M � true ⇓ T
M � false ⇓ F
M(x) = v
M � x ⇓ v
M � E1 ⇓ v1 M � E2 ⇓ v2 v = v1 + v2M � E1 + E2 ⇓ v
M � E1 ⇓ v M � E2 ⇓ vM � E1 = E2 ⇓ T
M � E1 ⇓ v1 M � E2 ⇓ v2 v1 �= v2M � E1 = E2 ⇓ F
M � E ⇓ v
M � x := E ⇓ M [v/x]
M � S1 ⇓ M1 M1 � S2 ⇓ M2
M � S1;S2 ⇓ M2
Read nM � read x ⇓ M [n/x]
Read n
M � E ⇓ v Write vM � write E ⇓ M
Write v
n ∈ Z
b ∈ B = {T, F}
x ∈ Addr = Id
1
M � E ⇓ vM � S ⇓ M �
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
x := 0;y := 0;while x < 11 do
y := y + x;x := x + 1;
write y
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
Γ � n : Int (constant)
Γ(x) = τ
Γ � x : τ (variable)
Γ � E1 : τ1 Γ, x : τ1 � E2 : τ2Γ � let x := E1 in E2 : τ2 (letin)
Γ � E : IntΓ � −E : Int
Γ � E1 : Int Γ � E2 : IntΓ � E1 + E2 : Int
1
명령문의 의미
M � E ⇓ T M � S1 ⇓ M1
M � if E then S1 else S2 ⇓ M1
M � E ⇓ F M � S2 ⇓ M2
M � if E then S1 else S2 ⇓ M2
M � E ⇓ FM � while E do S ⇓ M
M � E ⇓ T M � S ⇓ M1 M1 � while E do S ⇓ M2
M � while E do S ⇓ M2
M � E1 ⇓ v1 M � E2 ⇓ v2 v1 > v2M � for x := E1 to E2 do S ⇓ M
n ∈ Z
b ∈ B = {T, F}
x ∈ Addr = Id
A+B separated sum {a, b, ...}
A×B cartesian product {�a, b�, ...}
A → B finite functions {f, g, ..}
f ∈ A → B iff dom(f) is a finite subset of A.
f [b/a](x) =
�b if x = a
f(x) otherwise
2
M � E ⇓ vM � S ⇓ M �
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
x := 0;y := 0;while x < 11 do
y := y + x;x := x + 1;
write y
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
Γ � n : Int (constant)
Γ(x) = τ
Γ � x : τ (variable)
Γ � E1 : τ1 Γ, x : τ1 � E2 : τ2Γ � let x := E1 in E2 : τ2 (letin)
Γ � E : IntΓ � −E : Int
Γ � E1 : Int Γ � E2 : IntΓ � E1 + E2 : Int
1
명령문의 의미
M � E ⇓ T M � S1 ⇓ M1
M � if E then S1 else S2 ⇓ M1
M � E ⇓ F M � S2 ⇓ M2
M � if E then S1 else S2 ⇓ M2
M � E ⇓ FM � while E do S ⇓ M
M � E ⇓ T M � S ⇓ M1 M1 � while E do S ⇓ M2
M � while E do S ⇓ M2
M � E1 ⇓ v1 M � E2 ⇓ v2 v1 > v2M � for x := E1 to E2 do S ⇓ M
M � E1 ⇓ v1 M � E2 ⇓ v2 v1 ≤ v2 k = v2 − v1M [v1/x] � S ⇓ M1
M1[v1 + 1/x] � S ⇓ M2...
Mk[v1 + k/x] � S ⇓ Mk+1
M � for x := E1 to E2 do S ⇓ Mk+1
n ∈ Z
b ∈ B = {T, F}
x ∈ Addr = Id
A+B separated sum {a, b, ...}
A×B cartesian product {�a, b�, ...}
A → B finite functions {f, g, ..}
f ∈ A → B iff dom(f) is a finite subset of A.
f [b/a](x) =
�b if x = a
f(x) otherwise
2
M � E ⇓ vM � S ⇓ M �
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
x := 0;y := 0;while x < 11 do
y := y + x;x := x + 1;
write y
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
Γ � n : Int (constant)
Γ(x) = τ
Γ � x : τ (variable)
Γ � E1 : τ1 Γ, x : τ1 � E2 : τ2Γ � let x := E1 in E2 : τ2 (letin)
Γ � E : IntΓ � −E : Int
Γ � E1 : Int Γ � E2 : IntΓ � E1 + E2 : Int
1
설탕 구문Syntactic Sugar
•for문은 while문을 가지고 정의할 수 있다.
•필요는 없지만 편의상 제공될 뿐.
for x := E1 to E2 do S
M � n ⇓ n
M � true ⇓ T
M � false ⇓ F
M(x) = v
M � x ⇓ v
M � E1 ⇓ v1 M � E2 ⇓ v2 v = v1 + v2M � E1 + E2 ⇓ v
M � E1 ⇓ v M � E2 ⇓ vM � E1 = E2 ⇓ T
M � E1 ⇓ v1 M � E2 ⇓ v2 v1 �= v2M � E1 = E2 ⇓ F
M � E ⇓ v
M � x := E ⇓ M [v/x]
M � S1 ⇓ M1 M1 � S2 ⇓ M2
M � S1;S2 ⇓ M2
Read nM � read x ⇓ M [n/x]
Read n
M � E ⇓ v Write vM � write E ⇓ M
Write v
1
≈for x := E1 to E2 do Slow := E − 1;high := E − 2;while not(high < low) do
x := low;S;low := low + 1
M � n ⇓ n
M � true ⇓ T
M � false ⇓ F
M(x) = v
M � x ⇓ v
M � E1 ⇓ v1 M � E2 ⇓ v2 v = v1 + v2M � E1 + E2 ⇓ v
M � E1 ⇓ v M � E2 ⇓ vM � E1 = E2 ⇓ T
M � E1 ⇓ v1 M � E2 ⇓ v2 v1 �= v2M � E1 = E2 ⇓ F
M � E ⇓ v
M � x := E ⇓ M [v/x]
M � S1 ⇓ M1 M1 � S2 ⇓ M2
M � S1;S2 ⇓ M2
Read nM � read x ⇓ M [n/x]
Read n
M � E ⇓ v Write vM � write E ⇓ M
Write v
1
≈for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
The variable high does not appear in E2, and S.
1
변수 이름 짓기변수는 하나의
메모리 셀을 나타낸다.
x는 1번 주소,y는 2번 주소,
....n은 10번 주소,
....mother는 97,563번 주소
....
내가 father라는 이름을 썼던가??
M � E ⇓ vM � S ⇓ M �
E and S are syntactic objects
v and M are semantic objects
v ∈ Val = Z + B
M ∈ Memory = Addr → Val
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
x := 0;y := 0;while x < 11 doy := y + x;x := x + 1;
write y
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
1
M � E ⇓ vM � S ⇓ M �
E and S are syntactic objects
v and M are semantic objects
v ∈ Val = Z + B
M ∈ Memory = Addr → Val
n ∈ Z
b ∈ B = {T, F}
x ∈ Addr = Id
A+B separated sum {a, b, ...}
A×B cartesian product {�a, b�, ...}
A → B finite functions {f, g, ..}
f ∈ A → B iff dom(f) is a finite subset of A.
f [b/a](x) =
�b if x = a
f(x) otherwise
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
1
변수가 의미하는 바는?
•x가 왼쪽에 나올때랑 오른쪽에 나올때가 다르네?
•변수의 유효범위는 프로그램 전체!
•하나의 변수는 오직 하나의 주소를 나타내는구나!
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
The variable high should not appear in S.
1
M � n ⇓ n
M � true ⇓ T
M � false ⇓ F
M(x) = v
M � x ⇓ v
M � E1 ⇓ v1 M � E2 ⇓ v2 v = v1 + v2M � E1 + E2 ⇓ v
M � E1 ⇓ v M � E2 ⇓ vM � E1 = E2 ⇓ T
M � E1 ⇓ v1 M � E2 ⇓ v2 v1 �= v2M � E1 = E2 ⇓ F
M � E ⇓ v
M � x := E ⇓ M [v/x]
M � S1 ⇓ M1 M1 � S2 ⇓ M2
M � S1;S2 ⇓ M2
Read nM � read x ⇓ M [n/x]
Read n
M � E ⇓ v Write vM � write E ⇓ M
Write v
2
M � n ⇓ n
M � true ⇓ T
M � false ⇓ F
M(x) = v
M � x ⇓ v
M � E1 ⇓ v1 M � E2 ⇓ v2 v = v1 + v2M � E1 + E2 ⇓ v
M � E1 ⇓ v M � E2 ⇓ vM � E1 = E2 ⇓ T
M � E1 ⇓ v1 M � E2 ⇓ v2 v1 �= v2M � E1 = E2 ⇓ F
M � E ⇓ v
M � x := E ⇓ M [v/x]
M � S1 ⇓ M1 M1 � S2 ⇓ M2
M � S1;S2 ⇓ M2
Read nM � read x ⇓ M [n/x]
Read n
M � E ⇓ v Write vM � write E ⇓ M
Write v
2
L-value R-value
변수의 유효범위 Scope
•변수의 유효범위를 정할 수 있다면 굳이 하나의 변수가 하나의 주소를 가질 필요는 없다.
x1 2
3 4 5
x1
32
45
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
The variable high should not appear in S.
1
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
The variable high should not appear in S.
1
그래서, 나온게...
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
The variable high should not appear in S.
1
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
The variable high should not appear in S.
1
새로운 주소를 만들어서 x라 칭하고, 초기값은 E로한다.
이 주소는 S에서만 유효하리라!
M � E ⇓ vM � S ⇓ M �
E and S are syntactic objects
v and M are semantic objects
v ∈ Val = Z + B
M ∈ Memory = Addr → Val
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
x := 0;y := 0;while x < 11 doy := y + x;x := x + 1;
write y
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
1
M � E ⇓ vM � S ⇓ M �
E and S are syntactic objects
v and M are semantic objects
v ∈ Val = Z + B
M ∈ Memory = Addr → Val
n ∈ Z
b ∈ B = {T, F}
x ∈ Addr = Id
A+B separated sum {a, b, ...}
A×B cartesian product {�a, b�, ...}
A → B finite functions {f, g, ..}
f ∈ A → B iff dom(f) is a finite subset of A.
f [b/a](x) =
�b if x = a
f(x) otherwise
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
The variable high should not appear in S.
1
모양 의미
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
The variable high should not appear in S.
1
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � S ⇓ M
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
The variable high should not appear in S.
1
환경과 메모리
묶인 변수와 자유 변수Bound and Free Variable
•주어진 유효 범위에서 변수가 묶였는지 자유로운지 알수 있다.
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
let x := 1 inlet y := 2
in x + y
let x := 1 inx + y
x := 0;y := 0;while x < 11 doy := y + x;x := x + 1;
write y
for x:= 0 to 10 doy := y + x;
write y
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
4
똑같은 일을 여러번 할 때•똑같은 일에 이름을 정하고, 여러번 사용하
자.
•어떤 프로그램 명령문으로 돌아가자.
goto L; L: S
procedure f(x) = S f(E)
함수의 이름
명령문의 이름
Procedure
•기계 중심의 프로그래밍 언어에서 procedure란 명령문들에 이름을 붙여 놓은 것
•인자를 가지고 어느 정도 일반화 시킨 것
procedure f(x) = S f(E)
Procedure 선언은 프로그램의 어디서 하도록 할까?
Procedure에 있는 자유로운 변수들은 어떻게 하나?
재사용가독성
문제 쪼개기
Syntax
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
StatementS → ...
| let procedure f(x) = S in S| call f(E)
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
let x := 1 inlet y := 2
in x + y
let x := 1 inx + y
x := 0;y := 0;while x < 11 do
y := y + x;x := x + 1;
write y
for x:= 0 to 10 doy := y + x;
write y
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
4
원하는 결과는?
let x := 1 inlet procedure addx(y) = x := x + y in...addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
The variable high should not appear in S.
1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
The variable high should not appear in S.
1
Semantics (A)
•프로그램에서 이름은 이제 메모리 주소나 procedure를 지칭한다.
σ ∈ Env = Id → Addr + Procedure
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
1
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × Sa
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
1
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S
σ[�x, S1�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
1
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S
σ[�x, S1�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1� σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
1
Semantics (A)let x := 1 inlet procedure addx(y) = x := x + y in...addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
The variable high should not appear in S.
1
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S
σ[�x, S1�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1� σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
1
결과는 5
Dynamic Scoping 이름의 실체가 실행 중에 결정됨!
Semantics (B)
•프로그램에서 이름은 이제 메모리 주소나 procedure를 지칭한다.
σ ∈ Env = Id → Addr + Procedure
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
1
let x := 1 inlet procedure addx(y) = x := x + y in...addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
for x := E1 to E2 do Sx := E1;high := E2;while not(high < x) do
S;x := x+ 1
The variable high should not appear in S.
1
원하는 결과는 4
어떻게 만들까요?
Semantics (B)
Procedure가 정의될 때의 환경을 같이 저장한다!
Static Scoping 이름의 실체가 실행 전에 결정됨!
위험한Dynamic Scoping
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ[�x, S1,σ�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1,σ1� σ,M � E ⇓ v � /∈ dom(M) σ1[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S
σ[�x, S1�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1� σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
1
code producer프로그램 제작
code consumer프로그램 실행
프로그램이 실행될때는 x가 정수여야 된다고 가정
그런 가정을 모르는 상태에서 실행
Dynamic scoping was a historical non-sense!
Old FortranOld Lisp
1960-70sThey didn’t know how to
implement the static scoping
No modern languages use dynamic scoping.
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ[�x, S1,σ�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1,σ1� σ,M � E ⇓ v � /∈ dom(M) σ1[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S
σ[�x, S1�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1� σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
1
closureclosed over its free variables
인자 넘기는 방법Parameter Passingσ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ[�x, S1,σ�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1,σ1� σ,M � E ⇓ v � /∈ dom(M) σ1[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S
σ[�x, S1�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1� σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
1
call-by-value값을 넘기고 있다!
인자 넘기는 방법Parameter Passing
call-by-reference어떨 땐 주소를 넘겨주고 싶은데?
let procedure reset(x) = x := 0in
let y := 1 in...; call reset(y);
let z := 2 in...; call reset(z);
...
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ[�x, S1,σ�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1,σ1� σ,M � E ⇓ v � /∈ dom(M) σ1[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S
σ[�x, S1�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1� σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
1
좋아! 우리 언어에 추가하자!
인자의 주소를 넘기자call-by-reference
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
StatementS → ...
| let procedure f(x) = S in S| call f(E)| call f�x�
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
let x := 1 inlet y := 2
in x + y
let x := 1 inx + y
x := 0;y := 0;while x < 11 do
y := y + x;x := x + 1;
write y
for x:= 0 to 10 doy := y + x;
write y
Γ ∈ TypeEnv = Id → Type
Type → τ | Int | Bool | Type → Type
5
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ[�x, S1,σ�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1,σ1� σ,M � E ⇓ v � /∈ dom(M) σ1[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
σ(f) = �y, S1,σ1� σ1[σ(x)/y],M � S1 ⇓ M1
σ,M � call f�x� ⇓ M1
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S
σ[�x, S1�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1� σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
1
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ[�x, S1,σ�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1,σ1� σ,M � E ⇓ v � /∈ dom(M) σ1[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
σ(f) = �y, S1,σ1� σ1[σ(x)/y],M � S1 ⇓ M1
σ,M � call f�x� ⇓ M1
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S
σ[�x, S1�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1� σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
1
함수가 돌려주는 값은?
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ[�x, S1,σ�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1,σ1� σ,M � E ⇓ v � /∈ dom(M) σ1[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
σ(f) = �y, S1,σ1� σ1[σ(x)/y],M � S1 ⇓ M1
σ,M � call f�x� ⇓ M1
1
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ[�x, S1,σ�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1,σ1� σ,M � E ⇓ v � /∈ dom(M) σ1[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
σ(f) = �y, S1,σ1� σ1[σ(x)/y],M � S1 ⇓ M1
σ,M � call f�x� ⇓ M1
1
call f(E)나 call f<x>가 값을 돌려주도록 하자!
명령문이 값을 돌려주면?
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S
σ[�x, S1�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1� σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
let x := Ein S
{int x = E;S
}
Ids1−1←→ Addr ←→ Val
2
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ,M � S ⇓ M �
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ[�x, S1,σ�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1,σ1� σ,M � E ⇓ v � /∈ dom(M) σ1[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
σ(f) = �y, S1,σ1� σ1[σ(x)/y],M � S1 ⇓ M1
σ,M � call f�x� ⇓ M1
1
에잇 합체! fusion!
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ,M � E ⇓ v,M �
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ[�x, S1,σ�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1,σ1� σ,M � E ⇓ v � /∈ dom(M) σ1[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
σ(f) = �y, S1,σ1� σ1[σ(x)/y],M � S1 ⇓ M1
σ,M � call f�x� ⇓ M1
1
통일된 의미 구조
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ,M � E ⇓ v,M �
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ[�x, S1,σ�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1,σ1� σ,M � E ⇓ v � /∈ dom(M) σ1[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
σ(f) = �y, S1,σ1� σ1[σ(x)/y],M � S1 ⇓ M1
σ,M � call f�x� ⇓ M1
1
•값을 돌려주던 프로그램식은 받은 메모리를 그대로 값과 같이 돌려주면 되겠다.
•메모리를 돌려주던 명령문들은 어떤 값을 계산해 낸다고 정의 할까?
void/텅 빈 값으로 하자.
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S
σ[�x, S1�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1� σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
σ,M � E ⇓ v
σ,M � x := E ⇓ M [v/σ(x)]
σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S ⇓ M1
σ,M � let x := E in S ⇓ M1
σ ∈ Env = Id → AddrM ∈ Mem = Addr → Val
v ∈ Val = Z + B + {·}
let x := Ein S
{int x = E;S
}
2
혹시 텅 빈 값을 만들고 싶으면 ()를 쓰자.
통일된 SyntaxProgram
P → E
ExpressionE → x := E
| E;E| if E then E else E| while E do E| for x := E to E do E| read x| write E| skip| let procedure f(x) = E in E| call f(E)| call f�x�| n | true | false | x| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
StatementS → ...
| let procedure f(x) = S in S| call f(E)| call f�x�
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
let x := 1 inlet y := 2
in x + y
6
통일된 Semantics
의미 공간semantic domain
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ,M � E ⇓ v,M �
σ ∈ Env = Id → Addr + Procedure
1
주소는 인데스로 쓸 수만 있으면 어떤 것이든 상관없다.
통일된 SemanticsProcedure = Id × S × Env
σ,M � E ⇓ v,M �
σ,M � x := E ⇓ ·,M �[v/σ(x)]
σ,M � E ⇓1 v,M1 � /∈ dom(M1) σ[�/x],M1[v/�] � E2 ⇓ v2,M2
σ,M � let x := E1 in E2 ⇓ v2,M2
σ[�x,E1,σ�/f ],M � E2 ⇓ v,M1
σ,M � let procedure f(x) = E1 in E2 ⇓ v,M1
σ(f) = �x,E1,σ1� σ,M � E ⇓ v,M1 � /∈ dom(M) σ1[�/x],M1[v/�] � E1 ⇓ v�,M2
σ,M � call f(E) ⇓ v�,M2
σ(f) = �y, E1,σ1� σ1[σ(x)/y],M � E1 ⇓ v,M �
σ,M � call f�x� ⇓ v,M �
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S
σ[�x, S1�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1� σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
σ,M � E ⇓ v
M(σ(x)) = v
σ,M � x ⇓ v
2
재귀 호출Recursive Call
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := true
1
incall inc(2)
σ,M � E ⇓ v,M �
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ,M � E ⇓ v,M �
σ,M � x := E ⇓ ·,M �[v/σ(x)]
σ,M � E ⇓1 v,M1 � /∈ dom(M1) σ[�/x],M1[v/�] � E2 ⇓ v2,M2
σ,M � let x := E1 in E2 ⇓ v2,M2
σ[�x,E1,σ�/f ],M � E2 ⇓ v,M1
σ,M � let procedure f(x) = E1 in E2 ⇓ v,M1
σ(f) = �x,E1,σ1� σ,M � E ⇓ v,M1 � /∈ dom(M) σ1[�/x],M1[v/�] � E1 ⇓ v�,M2
σ,M � call f(E) ⇓ v�,M2
σ(f) = �y, E1,σ1� σ1[σ(x)/y],M � E1 ⇓ v,M �
σ,M � call f�x� ⇓ v,M �
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S
σ[�x, S1�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1� σ,M � E ⇓ v � /∈ dom(M) σ[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
let x := 1 inlet procedure addx(y) = x := x + yin
addx(3)
let x := 1 inlet procedure addx(y) = x := x + y in
let x := 2in
addx(3);x := x + 1;
2
동작하지 않는다. 이유는?어디에 넣지?
메모리 생존 기간Memory Cell’s Lifetime
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
1
}}}
resety
z
생존기간은 scope와 일치
우리 언어가 커지면 일치하지 않을수도!
우리가 만든 언어Program
P → E
ExpressionE → x := E
| E;E| if E then E else E| while E do E| for x := E to E do E| read x| write E| skip| let procedure f(x) = E in E| call f(E)| call f�x�| n | true | false | x| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
StatementS → ...
| let procedure f(x) = S in S| call f(E)| call f�x�
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
let x := 1 inlet y := 2
in x + y
6
지원하는 feature들• for loop and while loop
•name memory cells
•name program codes
•names with scopes
• recursive calls
•call-by-value, call-by-reference
• integer I/O
하지만, 자료 구조는?tree, sets, lists ...
Record•기계 중심의 프로그래밍 언어에서 “레코
드”란 메모리 뭉치 + 뭉치에 있는 주소에 이름을 붙인 것
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{age �→ �1, name �→ �2}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
age name
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
age name
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
메모리
Record 추가
ProgramP → E
ExpressionE → x := E
| E;E| if E then E else E| while E do E| for x := E to E do E| read x| write E| skip| let procedure f(x) = E in E| call f(E)| call f�x�| n | true | false | x| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
ExpressionE → ...
| {xi := E1, ..., xn := En}| E.x| E.x := E
6
만들기
사용하기
r ∈ Record = Field → Addrn ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}+ Recordσ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = Nf ∈ Field = Id
Record = Field → Addr
age name
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let x := {height:= 176, weight = 89}in
x.height + x.weight
let tree := {left := {}, v := 0, right := {}}in
tree.left := 1;tree.right := {left := {}, v := 2, right := 3}
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
1
Record 의미
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ,M � E ⇓ v,M �
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ[�x, S1,σ�/f ],M � S2 ⇓ M1
σ,M � let procedure f(x) = S1 in S2 ⇓ M1
σ(f) = �x, S1,σ1� σ,M � E ⇓ v � /∈ dom(M) σ1[�/x],M [v/�] � S1 ⇓ M1
σ,M � call f(E) ⇓ M1
σ(f) = �y, S1,σ1� σ1[σ(x)/y],M � S1 ⇓ M1
σ,M � call f�x� ⇓ M1
1
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ,M � E ⇓ v,M �
σ,M � E1 ⇓ v1,M1
σ,M1 � E2 ⇓ v2,M2...
σ,Mn � En ⇓ vn,Mn
�1, ..., �n /∈ dom(Mn) ∀i, j ≤ n. i �= j ⇒ �i �= �j
σ,M � {x1 := E1, ..., xn := En} ⇓ {x1 �→ �1, ..., xn �→ �n},Mn[v1/�1]...[vn/�n]
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ,M � E ⇓ v,M �
σ,M � x := E ⇓ ·,M �[v/σ(x)]
σ,M � E ⇓1 v,M1 � /∈ dom(M1) σ[�/x],M1[v/�] � E2 ⇓ v2,M2
σ,M � let x := E1 in E2 ⇓ v2,M2
σ[�x,E1,σ�/f ],M � E2 ⇓ v,M1
σ,M � let procedure f(x) = E1 in E2 ⇓ v,M1
σ(f) = �x,E1,σ1� σ,M � E ⇓ v,M1 � /∈ dom(M) σ1[�/x],M1[v/�] � E1 ⇓ v�,M2
σ,M � call f(E) ⇓ v�,M2
σ(f) = �x,E1,σ1� σ,M � E ⇓ v,M1 � /∈ dom(M)σ1[�x,E1,σ1�/f ][�/x],M1[v/�] � E1 ⇓ v�,M2
σ,M � call f(E) ⇓ v�,M2
σ(f) = �y, E1,σ1� σ1[σ(x)/y],M � E1 ⇓ v,M �
σ,M � call f�x� ⇓ v,M �
σ ∈ Env = Id → Addr + Procedure
2
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ,M � E ⇓ v,M �
σ,M � E1 ⇓ v1,M1
σ,M1 � E2 ⇓ v2,M2...
σ,Mn � En ⇓ vn,Mn
�1, ..., �n /∈ dom(Mn) ∀i, j ≤ n. i �= j ⇒ �i �= �j
σ,M � {x1 := E1, ..., xn := En} ⇓ {x1 �→ �1, ..., xn �→ �n},Mn[v1/�1]...[vn/�n]
σ,M � E ⇓ r,M �
σ,M � E.x ⇓ M �(r(x)),M �
σ ∈ Env = Id → Addr + Procedure
Procedure = Id × S × Env
σ,M � E ⇓ v,M �
σ,M � x := E ⇓ ·,M �[v/σ(x)]
σ,M � E ⇓1 v,M1 � /∈ dom(M1) σ[�/x],M1[v/�] � E2 ⇓ v2,M2
σ,M � let x := E1 in E2 ⇓ v2,M2
σ[�x,E1,σ�/f ],M � E2 ⇓ v,M1
σ,M � let procedure f(x) = E1 in E2 ⇓ v,M1
σ(f) = �x,E1,σ1� σ,M � E ⇓ v,M1 � /∈ dom(M) σ1[�/x],M1[v/�] � E1 ⇓ v�,M2
σ,M � call f(E) ⇓ v�,M2
σ(f) = �x,E1,σ1� σ,M � E ⇓ v,M1 � /∈ dom(M)σ1[�x,E1,σ1�/f ][�/x],M1[v/�] � E1 ⇓ v�,M2
σ,M � call f(E) ⇓ v�,M2
σ(f) = �y, E1,σ1� σ1[σ(x)/y],M � E1 ⇓ v,M �
σ,M � call f�x� ⇓ v,M �
σ ∈ Env = Id → Addr + Procedure
2
let x := 0 inlet procedure inc(n) = x:= x + n in
call inc(1);let x := truein
call inc(2)
σ,M � E ⇓ v,M �
σ,M � E1 ⇓ v1,M1
σ,M1 � E2 ⇓ v2,M2...
σ,Mn � En ⇓ vn,Mn
�1, ..., �n /∈ dom(Mn) ∀i, j ≤ n. i �= j ⇒ �i �= �j
σ,M � {x1 := E1, ..., xn := En} ⇓ {x1 �→ �1, ..., xn �→ �n},Mn[v1/�1]...[vn/�n]
σ,M � E ⇓ r,M �
σ,M � E.x ⇓ M �(r(x)),M �
σ,M � E1 ⇓ r,M1 σ,M1 � E2 ⇓ v,M2
σ,M � E1.x := E2 ⇓ ·,M2[v/r(x)]
σ ∈ Env = Id → Addr + Procedure
2
Record 예
r ∈ Record = Field → Addrn ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = Nf ∈ Field = Id
Record = Field → Addr
age name
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let x := {height:= 176, weight = 89}in
x.height + x.weight
let tree := {left := {}, v := 0, right := {}}in
tree.left := 1;tree.right := {left := {}, v := 2, right := 3}
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
176
89
x heightweight
tree left
rightv
1
0
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
n ∈ Zb ∈ B = {T, F}v ∈ Val = Z + B + {·}σ ∈ Env = Id → Addr + ProcedureM ∈ Mem = Addr → Val
Procedure = Id × E × Env� ∈ Addr = N
Record = Field → Addr
{left �→ �1, content �→ �2, right �→ �3}
let x := 0in
let procedure sum(n) =for i := 1 to n do
x := x + iin
call sum(10);write x+1;
let procedure sum(n) =let x := 0 in
for i := 1 to n dox := x + i;
return xin
write (call sum(10)) + 1
let procedure fac(n) =if n <= 0 then 1else n * call fac (n-1)
incall fac(2)
let procedure reset(x) = x := 0in
let y := 1 in...; call reset <y>;
let z := 2 in...; call reset <z>;
...
1
{}
2
3
left
rightv
구현에 혼동되지는 말자.
우리가 만든 언어지원하는 feature들• for loop and while loop•name memory cells•name program codes•names with scopes• recursive calls•call-by-value, call-by-reference• integer I/O•primitive values: integers, booleans•compound values: records
하지만, 메모리 주소에 꼭 이름을 주어야 하나요?그냥 주소도 값으로 생각하죠!
ProgramP → E
ExpressionE → x := E
| E;E| if E then E else E| while E do E| for x := E to E do E| read x| write E| skip| let procedure f(x) = E in E| call f(E)| call f�x�| n | true | false | x| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E| {xi := E1, ..., xn := En}| E.x| E.x := E
ProgramP → S
StatementS → x := E
| S;S| if E then S else S| while E do S| for x := E to E do S| read x| write E| skip
StatementS → ...
| let procedure f(x) = S in S| call f(E)| call f�x�
ExpressionE → n | true | false | x
| E + E | E − E | E ∗ E | E/E| E = E | E < E | not E
let x := 1 in
7