지금까지의 내용을 가지고 다음의 코드가 어떤 결과를 표시할 지 생각해보자.
var a = "global"; { fun showA() { print a; } showA(); var a = "block"; showA(); }
결과는 다음과 같다.global
block
뭐가 문제일까?
앞장에서 함수에 Environment를 적용할 때 함수가 실행될 때마다 Environment를 새로 생성했다. 그리고, 함수안에서 사용하는 변수의 값을 찾을 때 현재 Environment로부터 부모 Environment로 점차로 찾아가는 형태로 구현을 했다.
여기의 어떤 점이 문제였을까?
위의 코드에서 showA()를 선언했을 때의 Environment를 살펴보자.
global environment(a="global") <- block environment() <- showA environment()
따라서, 처음 showA(); 를 호출할 때는 global environment의 a가 찾아진다. 그런데 두번째 a인 var a = "block"; 가 실행되면서 block environment에 a="block" 가 추가된다. 이 다음에 showA() 를 호출하면 앞에서처럼 점진적으로 Environment를 찾아갈 텐데 block environment에 a가 추가되었기 때문에 여기의 a를 찾게 되고 이 a 의 값이 출력되게 된다.
위의 문제를 해결하려면?
아래와 같은 코드가 있을 때 1과 2에서의 scope가 실제로는 같지 않아야 함을 의미한다.
{ var a; // 1. var b; // 2. }
그렇다면, 이 문제를 어떻게 해결할 수 있을까?
첫번째로는 변수 선언이나 함수 선언의 경우마다 새로운 scope를 생성하는 것이다.(이전에는 기존의 Environment에 새로운 선언을 바로 추가했다.)
두번째로는 Semantic Analysis를 사용하는 것이다.
이 방법은 block과 function의 경우 새로운 scope를 생성하고, variable이나 assignment가 있는 경우 어떤 scope에 있는 값이 사용되어야 하는지를 미리 설정해 놓고 나중에 이 값을 사용한다.
우리는 두번째 방법으로 구현을 변경해 볼 것이다.
-> parser를 통해 나온 결과를 바로 interpreter에 보내지 않고 이 사이에 Resolver를 통해 Semantic Analysis를 한 후 interpreter에서 변수를 사용할 때 이 정보를 사용한다.
댓글 없음:
댓글 쓰기