/*
* emit.C
*/
#include <iostream.h>
#include "symtab.h"
extern bool debugFlag;
int SymtabCls :: emit() {
if (debugFlag) cout << "SymtabCls::emit()" << endl;
cerr << "Nothing to emit in symbol table!" << endl;
exit(1);
return 0;
}
#include "p_tree.h"
int PTreeCls :: emit() {
if (debugFlag) cout << "PTreeCls::emit() " << endl;
if (! root) {
cerr << "PTreeCls::emit - LOGIC ERROR" << endl;
return 0;
} else {
return root -> emit();
}
}
#ifdef MULT_ARR
int DataItemCls::emit()
{
typeEmit();
return 0;
}
PDataTypeCls DataItemCls::typeEmit()
{
if (debugFlag) cout << "DataItemCls::typeEmit()" << endl;
if (dynamic_cast<PIdentCls>(item) != NULL) { // basic type
PSymtabCls scp = ScopeCls::get_vista();
char *name = PIdentCls(item)->get_name();
PSymtabEntryCls found_it = scp -> lookup(name);
if (!found_it) {
cerr << "error: undeclared variable: " << name << endl;
exit(1);
}
PDataTypeCls type = PSymbolCls(found_it)->getDataType();
PAddressCls addr = PSymbolCls(found_it)->getAddress();
// Too many modifiers?
if (type == NULL || sub != NULL) {
cerr << "Type and reference mismatch" << endl;
exit(1);
}
cout << "push" << endl
<< addr->getAddr() << endl;
return type;
}
else { // array type
PDataTypeCls this_type = PDataItemCls(item)->typeEmit();
// Too many modifiers?
if (this_type == NULL || sub == NULL ||
dynamic_cast<PCompTypeCls>(this_type) == NULL) {
cerr << "Type and reference mismatch" << endl;
exit(1);
}
sub->emit();
cout << "push" << endl
<< PArrayTypeCls(this_type)->getRangeFrom()->get_value() << endl
<< "-" << endl;
cout << "push" << endl
<< PArrayTypeCls(this_type)->getItemSize() << endl
<< "*" << endl
<< "+" << endl;
return PArrayTypeCls(this_type)->getItemDataType();
}
}
#else /* !MULT_ARR */
int DataItemCls::emit()
{
if (debugFlag) cout << "DataItemCls::emit()" << endl;
PSymtabCls scp = ScopeCls::get_vista();
char *name = PIdentCls(item)->get_name();
PSymtabEntryCls found_it = scp -> lookup(name);
if (!found_it) {
cerr << "error: undeclared variable: " << name << endl;
exit(1);
}
PDataTypeCls type = PSymbolCls(found_it)->getDataType();
PAddressCls addr = PSymbolCls(found_it)->getAddress();
cout << "push" << endl
<< addr->getAddr() << endl;
if (sub) {
sub->emit();
cout << "push" << endl
<< PArrayTypeCls(type)->getRangeFrom()->get_value() << endl
<< "-" << endl;
cout << "push" << endl
<< PArrayTypeCls(type)->getItemSize() << endl
<< "*" << endl
<< "+" << endl;
}
return 0;
}
#endif /* MULT_ARR */
int StatementCls :: emit() {
if (debugFlag) cout << "! " << stmt_text << endl;
return 0;
}
int StatementSeqCls :: emit() {
if (debugFlag) cout << "StatementSeqCls::emit() " << endl;
PPTreeNodeCls p = this -> seq_head;
while (p) {
p -> emit();
p = PStatementCls(PStatementCls(p) -> get_next());
}
return 0;
}
int EmptyStmtCls :: emit() {
if (debugFlag) cout << "EmptyStmtCls::emit()" << endl;
return 0;
}
int WriteStmtCls :: emit() {
if (debugFlag) cout << "WriteStmtCls::emit()" << endl;
StatementCls::emit();
expr -> emit();
cout << "write" << endl;
return 0;
}
int AssignmentStmtCls :: emit() {
if (debugFlag) cout << "AssignmentStmtCls::emit()" << endl;
StatementCls::emit();
assign_seq->emit();
expr->emit();
for (int i=0; i<PAssignmentSeqCls(assign_seq)->getLength(); i++)
cout << ":=" << endl;
cout << "pop" << endl;
return 0;
}
int AssignmentSeqCls::emit() {
if (debugFlag) cout << "AssignmentSeqCls::emit() " << endl;
PPTreeNodeCls p = this->seq_head;
while (p) {
p -> emit();
p = PDataItemCls(PDataItemCls(p)->get_next());
}
return 0;
}
int LoopStmtCls::emit() {
if (debugFlag) cout << "LoopStmtCls::emit()" << endl;
cout << "loop" << endl;
statements->emit();
cout << "endloop" << endl;
return 0;
}
int ExitStmtCls::emit() {
if (debugFlag) cout << "ExitStmtCls::emit()" << endl;
cout << "exit" << endl;
return 0;
}
int IfStmtCls::emit()
{
if (debugFlag) cout << "IfStmtCls::emit()" << endl;
condition->emit();
cout << "test" << endl;
statements->emit();
elseStmts->emit();
cout << "endif" << endl;
return 0;
}
int ElseStmtCls::emit()
{
if (debugFlag) cout << "ElseStmtCls::emit()" << endl;
if (statements) {
cout << "else" << endl;
statements->emit();
}
return 0;
}
int RelOpCls::emit()
{
if (debugFlag) cout << "RelOpCls::emit()" << endl;
switch(op) {
case ltOp:
cout << "<" << endl;
break;
case leOp:
cout << "<=" << endl;
break;
case eqOp:
cout << "=" << endl;
break;
case neOp:
cout << "<>" << endl;
break;
case geOp:
cout << ">=" << endl;
break;
case gtOp:
cout << ">" << endl;
break;
default:
cerr << "error: unsupported relational operator: " << op << endl;
exit(1);
}
return 0;
}
int ConditionCls::emit()
{
if (debugFlag) cout << "ConditionCls::emit()" << endl;
expr1->emit();
expr2->emit();
relOp->emit();
return 0;
}
int NumFactorCls :: emit() {
if (debugFlag) cout << "NumFactorCls::emit()" << endl;
cout << "push" << endl
<< ExprCls::value << endl;
return 0;
}
int VarAccessFactorCls :: emit() {
if (debugFlag) cout << "VarAccessFactorCls::emit()" << endl;
item->emit();
cout << "getValue" << endl;
return 0;
}
int ArithmCls::emit()
{
left->emit();
right->emit();
switch (op) {
case PlusOp:
cout << "+" << endl;
break;
case MinusOp:
cout << "-" << endl;
break;
case MultOp:
cout << "*" << endl;
break;
case DivOp:
cout << "/" << endl;
break;
default:
cerr << "error: unsupported arithmetic operator: " << op << endl;
exit(1);
}
return 0;
}
int IdentSeqCls::emit()
{
return 0;
}
int DeclarationCls::emit()
{
return 0;
}
int DeclarationSeqCls::emit()
{
if (debugFlag) cout << "DeclarationSeqCls::emit()" << endl;
PDeclarationCls p = this -> seq_head;
while (p) {
p -> emit();
p = PDeclarationCls(p->get_next());
}
return 0;
}
int BlockCls :: emit() {
if (debugFlag) cout << "BlockCls::emit() " << endl;
return this -> stmt_seq -> emit();
}
int ProgramCls :: emit() {
if (debugFlag) cout << "ProgramCls::emit() " << endl;
if (block && std_table) {
this -> block -> emit();
cout << "finish" << endl;
return 0;
} else {
cerr << "ProgramCls::emit - LOGIC ERROR" << endl;
return 0;
}
}
|