void ExprCompiler::visit(DefClassExpr& expr, int dest) { // Evaluate the superclasses. int firstSuperclass = getNextTemp(); for (int i = 0; i < expr.superclasses().count(); i++) { int superclass = makeTemp(); compile(expr.superclasses()[i], superclass); } // Create the class. symbolId name = compiler_.addSymbol(expr.name()); write(expr, OP_CLASS, name, expr.fields().count(), dest); write(expr, OP_MOVE, firstSuperclass, expr.superclasses().count()); releaseTemps(expr.superclasses().count()); // Also store it in its named variable. compileAssignment(expr.pos(), expr.resolved(), dest, true); // Compile the synthesized stuff. for (int i = 0; i < expr.synthesizedMethods().count(); i++) { expr.synthesizedMethods()[i]->accept(*this, dest); } }
void ExprCompiler::visit(RecordExpr& expr, int dest) { // TODO(bob): Hack. This assumes that the fields in the expression are in // the same order that the type expects. Eventually, the type needs to sort // them so that it understands (x: 1, y: 2) and (y: 2, x: 1) are the same // shape. When that happens, this will need to take that into account. Array<int> names; // Compile the fields. int firstField = -1; for (int i = 0; i < expr.fields().count(); i++) { int fieldSlot = makeTemp(); if (i == 0) firstField = fieldSlot; compile(expr.fields()[i].value, fieldSlot); names.add(compiler_.addSymbol(expr.fields()[i].name)); } // TODO(bob): Need to sort field names. // Create the record type. int type = compiler_.addRecordType(names); // Create the record. write(expr, OP_RECORD, firstField, type, dest); releaseTemps(expr.fields().count()); }
imu_data_t* GladiatorIMU::translate(gladiator_rx_msg_t* input) { /* Translate device-specific message into the one specified by ICD */ imu_data_t* output = new imu_data_t; #if _POSIX_TIMERS_ > 0 //Systems that have clock_gettime struct timespec stamp; clock_gettime(CLOCK_REALTIME, &stamp); //On a 32-bit platform, struct timespec is a 8-byte structure; 64-bit is 16-byte //Promote as necessary output->tv_sec = stamp.tv_sec; output->tv_nsec = stamp.tv_nsec; #else //Mac branch: struct timeval tv; gettimeofday(&tv, 0); output->tv_sec = tv.tv_sec; output->tv_nsec = tv.tv_usec*1000; #endif //Once time is secure, deal with the status byte handleStatusByte(input); makeAccel(input->iAccX, &output->accel_x); makeAccel(input->iAccY, &output->accel_y); makeAccel(input->iAccZ, &output->accel_z); makeGyro(input->iGyrX, &output->gyro_x); makeGyro(input->iGyrY, &output->gyro_y); makeGyro(input->iGyrZ, &output->gyro_z); makeTemp(input->iTemp, &output->temp); return output; }
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. }
TAC *tacFunCall(AST_NODE *funCall) { AST_NODE *funDef = funCall->symbol->declaration; AST_NODE *largs = funDef->children[1]; AST_NODE *lexp = funCall->children[0]; TAC *tacArg = tacArgs(largs, lexp); TAC *tacCall = tacCreate(TAC_CALL, makeTemp(funCall->datatype), funCall->symbol, NULL); return tacMultiJoin(2, tacArg, tacCall); }
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 }
int ExprCompiler::compileArg(gc<Expr> arg) { // No arg so do nothing. if (arg.isNull()) return 0; RecordExpr* record = arg->asRecordExpr(); if (record != NULL) { // Compile each field. for (int i = 0; i < record->fields().count(); i++) { compile(record->fields()[i].value, makeTemp()); } return record->fields().count(); } // If we got here, the arg isn't a record, so its a single value. compile(arg, makeTemp()); return 1; }
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(ListExpr& expr, int dest) { // TODO(bob): Putting these all in registers and then copying them to the // list after creation may be slow. Another option to consider is to write // a start list bytecode first, and then have each element get pushed // directly to the new list. int firstElement = getNextTemp(); for (int i = 0; i < expr.elements().count(); i++) { int element = makeTemp(); compile(expr.elements()[i], element); } write(expr, OP_LIST, firstElement, expr.elements().count(), dest); releaseTemps(expr.elements().count()); }
TAC_NODE* createTacOperation(int type, TAC_NODE* code0, TAC_NODE* code1) { HASH_NODE* tempNode = makeTemp(); if (code0 != NULL) { if (code1 != NULL) { return joinTacs(joinTacs(code0, code1), createTacNode(type, tempNode, code0->result, code1->result)); } else { return joinTacs(joinTacs(code0, code1), createTacNode(type, tempNode, code0->result, NULL)); } } else { if (code1 != NULL) { return joinTacs(joinTacs(code0, code1), createTacNode(type, tempNode, NULL, code1->result)); } else { return joinTacs(joinTacs(code0, code1), createTacNode(type, tempNode, NULL, NULL)); } } }
void moveCR2(Context* con, unsigned size, lir::Constant* src, lir::Register* dst, Promise* callOffset) { if (isFpr(dst)) { // floating-point lir::Register tmp = size > 4 ? makeTemp64(con) : makeTemp(con); moveCR(con, size, src, size, &tmp); moveRR(con, size, &tmp, size, dst); freeTemp(con, tmp); } else if (size > 4) { uint64_t value = (uint64_t)src->value->value(); ResolvedPromise loBits(value & MASK_LO32); lir::Constant srcLo(&loBits); ResolvedPromise hiBits(value >> 32); lir::Constant srcHi(&hiBits); lir::Register dstHi(dst->high); moveCR(con, 4, &srcLo, 4, dst); moveCR(con, 4, &srcHi, 4, &dstHi); } else if (src->value->resolved() and isOfWidth(getValue(src), 8)) {
TAC_NODE* createFunctionCall(HASH_NODE* result, TAC_NODE* code) { TAC_NODE* aux = NULL; TAC_NODE* list = NULL; TAC_NODE* push = NULL; TAC_NODE* pop = NULL; for(aux=revertTac(code);aux;aux=aux->next) { pop = createTacNode(TAC_POP_PARAMETRO, aux->result, NULL, NULL); list = joinTacs(pop, list); } HASH_NODE* tempNode = makeTemp(); list = joinTacs(createTacNode(TAC_FUNCTION_CALL, tempNode, result, NULL), list); for(aux=code; aux; aux=aux->previous) { push = createTacNode(TAC_PUSH_PARAMETRO, aux->result, NULL, NULL); list = joinTacs(push, list); } return list; }
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); }
TAC *tacReadArr(HASH_NODE* vec, TAC **code) { TAC *newTac = tacCreate(TAC_READARR, makeTemp(vec->datatype), vec, code[0]?code[0]->res:NULL); return tacMultiJoin(2, code[0], newTac); }
TAC *tacUnaryOp(int type, int datatype, TAC **code) { TAC *newTac = tacCreate(type, makeTemp(datatype), code[0]?code[0]->res:NULL, NULL); return tacMultiJoin(2, code[0], newTac); }
TAC_NODE* createVectorRead(HASH_NODE* simbolo, TAC_NODE* indice) { HASH_NODE* temp = makeTemp(); return joinTacs(indice, createTacNode(TAC_VECTOR_READ, temp, simbolo, indice->result)); }