sicp.io
5.5.3 · 조합식 컴파일하기

연산자를 먼저 컴파일하고 인자 순서를 보존한 뒤 apply 경계를 한 번 건넌다.

중첩 조합식의 정확한 명령 순서를 살펴보고 상태로 피연산자 평가를 드러내며 원시·해석·컴파일 프로시저를 하나의 호출 규약으로 연결합니다.

생각해 볼 질문

컴파일된 적용 코드가 보존해야 할 순서와 표현 계약은 무엇일까요?

  • 피연산자 식보다 연산자를 먼저 컴파일하기
  • 인자 순서를 보존하며 피연산자를 왼쪽부터 컴파일하기
  • 완전한 조합 상태가 준비된 뒤 call 명령 하나 내보내기
  • 불명확한 일정에 의존하지 않고 소스 순서의 효과 관찰하기
  • 프로시저 표현 사이에 하나의 어휘 환경과 인자 규약 공유하기
  • primitive·interpreted·compiled 디스패치 구분하기

수업용 컴파일러는 뺄셈 연산자의 load를 먼저 내보내고 왼쪽 record 호출 전체, 오른쪽 record 호출 전체, 마지막 바깥 call을 차례로 내보냅니다. record가 observations에 레이블을 덧붙이므로 (left right)가 실행도 방출된 소스 순서를 따른다는 사실을 보여 줍니다.

두 번째 프로그램에서는 평가기가 compiled add-three를 호출하고 compiled 코드가 interpreted double을 호출합니다. 두 경로 모두 정렬된 인자 목록을 apply-any에 넘기며 dispatch-log는 실제 primitive·interpreted·compiled 태그를 남깁니다. 이 실행은 수업에서 사용하는 호출 규약을 기록합니다.

SICP 코드UTF-8 11,199 / 1,048,576바이트
예제
결과
출력
진단
실행 추적0 / 0 개 이벤트
    실행은 브라우저 안에서 이루어지며 프로그램 결과와 실행 추적을 보여줍니다.
    예상 결과

    순서 프로그램은 ((17 (left right)) (load load literal literal call load literal literal call call))을 반환합니다. 인터페이스 프로그램은 ((evaluator-to-compiled 8 (compiled primitive)) (compiled-to-evaluator 14 (interpreted primitive) #t) (representations #t #t))를 반환합니다.

    실행 추적에서 볼 점

    첫 실행에서 바깥 연산자 load와 왼쪽 record 호출의 모든 명령과 오른쪽 호출의 모든 명령과 마지막 subtraction call을 차례로 따라가세요. 인터페이스 실행에서는 인자 준비와 apply-any 표현 디스패치를 분리하고 각 본문이 선언한 매개변수 순서로 인자를 받는지 확인하세요.

    직접 해보기

    프로그램을 수정하고 결과를 비교해 보세요.

    서로 다른 레이블을 기록하는 피연산자 세 개의 list 호출을 컴파일하고 한 피연산자를 compiled closure 호출로 감싸세요. 명령 태그와 시간순 dispatch-log를 예상하세요.

    힌트 보기

    연산자 코드를 먼저 끝내고 각 피연산자의 완전한 코드를 소스 순서대로 붙입니다. 마지막 call은 완성된 정렬 인자 목록을 사용합니다.

    이 수업 완료하기

    이 장의 총 23개 수업 중 0개 완료0%