Postfixcode auch Umgekehrte Polnische Notation UPN genannt, wird häufig als Zwischencode erzeugt. Diese Darstellung läßt sich leicht direkt interpretieren oder auch weiter in Maschinencode transformieren. Wir ordnen jedem syntaktischen Objekt eine Übersetzungsfunktion zu, die die Postfixdarstellung ausgibt. Die Übersetzung findet nur statt, wenn die statischen Kontextbedingungen erfüllt sind. Zunächst betrachten wir die arithmetischen Ausdrücke:
void BinNode::Compile()
{if (l != NULL) l->Compile();
if (r != NULL) r->Compile();
PutString(CV(nodetype));
};
void UnNode::Compile()
{l->Compile();
PutString(CV(nodetype));
};
void IdNode::Compile()
{Entry *e;
e = myEnv->Search(str);
PutAddr(str, e->GetVal());
}
void IntNode::Compile()
{PutInt(i);};
Für die Übersetzung der Kontrollanweisungen erweitern wir den Code um Marken , sowie um bedingte und unbedingte Sprungbefehle . Wir betrachten zunächst die Zuweisung :
void AssNode::Compile()
{
l->Compile();
r->Compile();
PutString(CV(nodetype));
};
Das WHILE ist schon ein wenig komplizierter - aber wirklich nur ein wenig!!
void WhileNode::Compile()
{
Label lstart, lover;
NewLabel(); strcpy(lstart, lab);
NewLabel(); strcpy(lover, lab);
PutString2(lstart, ":");
if (l != NULL) l->Compile();
PutString2("BF", lover);
if (r != NULL) r->Compile();
PutString2("JMP", lstart);
PutString2(lover, ":");
};
Es wird eine Startmarke ausgegeben und die Kontrollbedingung übersetzt. Ist die Bedingung nicht erfüllt, wird zur Übersprungmarke verzweigt, sonst folgt der Schleifenrumpf und der Rücksprung zur Bedingung.
Die IF -Anweisung in OBERON-0 soll diese kleine Einführung abschließen:
void IfNode::Compile()
{
Label lelse, lover;
NewLabel();
strcpy(lelse, lab);
expr->Compile();
PutString2("BF", lelse);
if (stmt != NULL) stmt->Compile();
NewLabel();
strcpy(lover, lab);
PutString2("JMP", lover);
PutString2(lelse, ":");
if (eifp != NULL)
{
((ElseIfNode*)eifp)->DefineLabel(lover);
eifp->Compile();
}
if (elsp != NULL) elsp->Compile();
PutString2(lover, ":");
}
void ElseIfNode::Compile()
{
Label lelse;
NewLabel();
strcpy(lelse, lab);
expr->Compile();
PutString2("BF", lelse);
if (stmt != NULL) stmt->Compile();
PutString2("JMP", lover);
PutString2(lelse, ":");
if (eifp != NULL)
{
((ElseIfNode*)eifp)->DefineLabel(lover);
eifp->Compile();
}
}
Prof. Dr. Reinhard Völler