함수 호출의 인수 목록이 평가되면 코드 생성기는 목록을 기호 테이블에 저장된 함수 서명과 비교하여 누락 된 인수를 알 수 있습니다. 어떤 인수를 대체해야 하는지를 알게되면 인수 레지스터 (또는 스택 프레임)에 기본값을 던지는 것만 큼 문제가됩니다. OO 언어를 다루고 있으며 형식 매개 변수가 객체 인 경우 스택의 다음 단어에 0 (NULL)을 입력 할 수 있습니다. 매개 변수가 기본 제공 프리미티브이면 언어에서 지정하는 기본값을 그대로 사용합니다.
물론 컴파일러는 다양 할 수 있지만 단순한 것으로서 심볼 테이블에 기본값을 연결하는 것은 절대적으로 필요하지 않습니다. 먼저, 심볼 테이블이 모든 변수 선언을 기록한다는 것을 명확히 밝힙니다. 이러한 선언에 대한 정보 (예 : 클래스, 메서드, 유형, 라인, char 등)를 저장해야하지만, 몇 가지 유형 만있을 때 각 변수에 대한 기본값을 기록 할 필요가 없으므로 가능한 기본값.
일부 언어 (Java/C++)는 초기화되지 않은 객체 속성이있는 클래스의 기본값이 NULL임을 지정합니다. 이와 같이 구현할 때 코드 생성기가 클래스 생성자를 생성하면 해당 속성에 매핑 된 객체 메모리에 0을 배치하는 코드를 생성해야합니다 (모든 것이 포인터 기반이라고 가정). 생성자를 생성하고 클래스 속성 목록 (AST 노드)을 반복하면서 해당 속성에 대한 초기화 표현식이 없으면 기본값을 수행 할 메소드를 호출합니다.
private void genConstructor(int classId) {
//allocate new object
codeGen.write("li $a0, "+classId);
codeGen.write("jal Runtime.newObject");
//call parent constructor
codeGen.write("move $a0, $v0");
codeGen.write("jal ParentInit");
//initialize the attributes this class has declared
for(Attributes a: getAttributes(classId)) {
//provide default value
if(a.getInitExpr() == null)
doDefault(a.getType(), a.getNum());
else
doInit(a.getInitExpr(), a.getNum());
}
}
// An 'Int' default value is 1, everything else is 0 (Objects included)
// $t0 has the object address
// attributes start at the 5th word of each object
private void doDefault(String type, int attrNum) {
switch(type) {
case "Int": {
codeGen.write("sw $one, "+(5+attrNum)+"($t0)");
}
default: {
codeGen.write("sw $zero, "+(5+attrNum)+"($t0)");
}
}
}
업데이트 :
내가 컴파일러는 프로그래머 대신 "클래스"또는 "종류"를 "기본"으로 설정 한 기본 값을 처리하는 방법을 궁금해하고있다.
저는 C++ 생성자에서 기본 args와 비슷한 것을 말하고 있다고 가정합니다. 이 경우, Ira가 언급했듯이, 기호 테이블 레코드에서 필드를 만드는 것이 가장 간단한 방법입니다. 누락 된 인수에 대한 코드를 생성 할 때 테이블에서 기본값을 찾으십시오.
다시 한 번 감사드립니다. 당신이 내 다른 질문에 답한 것을 기억합니다. 컴파일러가 "클래스"또는 "유형"대신 "기본값"대신 프로그래머가 설정 한 기본값을 처리하는 방법에 대해 궁금합니다. 감사. –
@SimonGuo : 업데이트되었습니다. – blackcompe