void ExprCompiler::visit(ForExpr& expr, int dest) { // TODO(bob): Hackish. An actual intermediate representation would help // here. int iterateMethod = compiler_.findMethod(String::create("0:iterate")); ASSERT(iterateMethod != -1, "Should have 'iterate' method in core."); int advanceMethod = compiler_.findMethod(String::create("0:advance")); ASSERT(advanceMethod != -1, "Should have 'advance' method in core."); // Evaluate the iteratable expression. int iterator = makeTemp(); compile(expr.iterator(), iterator); // Then call "iterate" on it to get an iterator. // TODO(bob): Hackish. An actual intermediate representation would help // here. write(expr, OP_CALL, iterateMethod, iterator, iterator); int loopStart = startJumpBack(); // Call "advance" on the iterator. write(expr, OP_CALL, advanceMethod, iterator, dest); // If done, jump to exit. int doneSlot = makeTemp(); write(expr, OP_BUILT_IN, BUILT_IN_DONE, doneSlot); write(expr, OP_EQUAL, dest, doneSlot, doneSlot); int loopExit = startJump(expr); releaseTemp(); // doneSlot. // Match on the loop pattern. compile(expr.pattern(), dest); // Compile the body. Loop loop(this); compile(expr.body(), dest); endJumpBack(expr, loopStart); endJump(loopExit, OP_JUMP_IF_TRUE, doneSlot); loop.end(); releaseTemp(); // iterator. // TODO(bob): Need to figure out what the result value should be. }
void ExprCompiler::visit(IsExpr& expr, int dest) { compile(expr.value(), dest); int type = makeTemp(); compile(expr.type(), type); write(expr, OP_IS, dest, type, dest); releaseTemp(); // type }
string AssignmentStatement::GenerateCode(){ stringstream varCode; ResultValue lvalue_r = lvalue->GenerateCode(); ResultValue rvalue_r = expr->GenerateCode(); LValueExpression* n = (LValueExpression*)lvalue; cout << " 1: " << lvalue_r.code << " 2: " << rvalue_r.code << endl; if (!ExistVarGlobal(n->variable_name) && !ExistVarTemp(n->variable_name)){ cout << "("<<line<<","<<column<<"): Variable \'" << n->variable_name << "\' no ha sido declarada."<<endl; } else if (lvalue_r.type == rvalue_r.type){ if (ExistVarGlobal(n->variable_name)){ if (rvalue_r.isConstant){ string p = newTemp(); varCode << rvalue_r.code; varCode << " li " << p << ", " << rvalue_r.value.int_value << endl; // VALIDAR los demas tipos (bool, string) varCode << " sw " << p << ", " << n->variable_name << endl; releaseTemp(p); } else { string p = newTemp(); varCode << rvalue_r.code; varCode << " sw " << rvalue_r.place << ", " << n->variable_name << endl; releaseTemp(p); } } if (ExistVarTemp(n->variable_name)){ if (rvalue_r.isConstant) varCode << " li " << varsTemp[n->variable_name].place << ", " << rvalue_r.value.int_value << endl; else varCode << " move " << varsTemp[n->variable_name].place << ", " << rvalue_r.place << endl; } } else cout << " ERROR en Statement ("<<line<<","<<column<<"): Variable \'"<< n->variable_name << "\' No se puede convertir \'" << TypeToString(rvalue_r.type) << "\' a \'" << TypeToString(lvalue_r.type) << "\'"<<endl; return varCode.str(); }
void ExprCompiler::visit(WhileExpr& expr, int dest) { int loopStart = startJumpBack(); // Compile the condition. int condition = makeTemp(); compile(expr.condition(), condition); int loopExit = startJump(expr); releaseTemp(); // condition Loop loop(this); compile(expr.body(), dest); endJumpBack(expr, loopStart); endJump(loopExit, OP_JUMP_IF_FALSE, condition); loop.end(); }
void ExprCompiler::visit(RecordLValue& lvalue, int value) { // TODO(bob): Lot of copy/paste between this and RecordPattern. // Recurse into the fields. for (int i = 0; i < lvalue.fields().count(); i++) { // TODO(bob): Could be faster and skip this if the field is a wildcard. // Test and destructure the field. This takes two instructions to encode // all of the operands. int field = makeTemp(); int symbol = compiler_.addSymbol(lvalue.fields()[i].name); write(lvalue.fields()[i].value->pos(), OP_GET_FIELD, value, symbol, field); // Recurse into the record, using that field. lvalue.fields()[i].value->accept(*this, field); releaseTemp(); // field. } }
void ExprCompiler::compileCall(const CallExpr& call, int dest, int valueSlot) { ASSERT(call.resolved() != -1, "Method should be resolved before compiling."); // Compile the method arguments. int firstArg = getNextTemp(); int numTemps = 0; numTemps += compileArg(call.leftArg()); numTemps += compileArg(call.rightArg()); // Then add the value as the last argument. if (valueSlot != -1) { int valueArg = makeTemp(); write(call, OP_MOVE, valueSlot, valueArg); } write(call, OP_CALL, call.resolved(), firstArg, dest); if (valueSlot != -1) releaseTemp(); // valueArg. releaseTemps(numTemps); }