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()); }
void Resolver::visit(RecordExpr& expr, int dummy) { // Resolve the fields. for (int i = 0; i < expr.fields().count(); i++) { resolve(expr.fields()[i].value); } }
void SignatureBuilder::writeArg(gc<Expr> expr) { // If it's a record, destructure it into the signature. RecordExpr* record = expr->asRecordExpr(); if (record != NULL) { for (int i = 0; i < record->fields().count(); i++) { add(record->fields()[i].name); add(":"); } return; } // Right now, all other exprs mean "some arg goes here". add("0:"); }
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; }