// step 5 // we'll assume all variables are global for a while // suppose you have a sequence of statements such as // x=3; y=7; y=(y+1)*x; or whatever. // how do you convert the whole sequence to assembly? // Easy- just convert each of the statements in the // sequence in turn. // // if you find an assignment statement like x=(x+2)*y // how do you convert that? // there are two steps. First produce assembly code that // would result in the value of the expression getting // into register 1, then STORE R1, [x] // // How do you produce code that would get the value // of XXXX + YYYY into register (a), keeping in mind that // XXXX and YYYY could both be big complicated expressions // themselves? // Three steps. produce code that would get the value // of XXXX into register (a). Then produce code that would // get the value of YYYY into register (a+1). Then just // say ADD R(a), R(a+1) // // How do you produce code that would get the value // of variable X into register (a)? LOAD R(a), [X] // // codegen(node *) is for things like statements // codegen(node *, int) is for expressions. The int is // which register you want the final value to end up in. #include #include #include struct node { string kind, detail; vector ptr; node(string a, string b="") { kind=a; detail=b; } node * add(node * p) { ptr.push_back(p); return this; } void print(int indent) { for (int i=0; iprint(indent+1); } } }; node * nn(string a, string b="") { return new node(a, b); } void codegen(node * p, int reg); void codegen(node * p) { if (p->kind=="sequence") { for (int i=0; iptr.size(); i+=1) codegen(p->ptr[i]); } else if (p->kind=="assign") { codegen(p->ptr[1], 1); // store r1, [var] node * var = p->ptr[0]; if (var->kind=="variable") cout << " STORE R1, [" << var->detail << "]\n"; else cout << "assignemnt not to variable\n"; } else cout << "bad statement kind " << p->kind << "\n"; } void codegen(node * p, int reg) { if (p->kind=="variable") cout << " LOAD R" << reg << ", [" << p->detail << "]\n"; else if (p->kind=="number") cout << " LOAD R" << reg << ", " << p->detail << "\n"; else if (p->kind=="operation") { if (p->detail=="+") { codegen(p->ptr[0], reg); codegen(p->ptr[1], reg+1); cout << " ADD R" << reg << ", R" << reg+1 << "\n"; } else if (p->detail=="*") { codegen(p->ptr[0], reg); codegen(p->ptr[1], reg+1); cout << " MUL R" << reg << ", R" << reg+1 << "\n"; } else cout << "bad operator " << p->detail << "\n"; } else cout << "bad expression kind " << p->kind << "\n"; } void main() { node * p = nn("sequence") ->add(nn("assign") ->add(nn("variable", "x")) ->add(nn("number", "3"))) ->add(nn("assign") ->add(nn("variable", "y")) ->add(nn("number", "7"))) ->add(nn("assign") ->add(nn("variable", "y")) ->add(nn("operation", "*") ->add(nn("operation", "+") ->add(nn("variable", "y")) ->add(nn("number", "1"))) ->add(nn("variable", "x")))); p->print(0); cout << "\n"; codegen(p); }