void ErrorReporter::error(gc<SourcePos> pos, const char* format, ...) { // If we're just waiting for more input, don't show any errors. if (needMoreLines_) return; numErrors_++; // TODO(bob): Hackish. Need to figure out if we want C-style, C++-style or // Magpie GC strings. char message[512]; va_list args; va_start(args, format); vsprintf(message, format, args); va_end(args); // If we don't have any position information, just show the message. if (pos.isNull()) { std::cerr << "Error: " << message << std::endl; return; } std::cerr << "[" << pos->file()->path() << "] Error: " << message << std::endl; if (pos->startLine() == pos->endLine()) { // Show the line and highlight the error. std::cerr << pos->startLine() << ": " << pos->file()->getLine(pos->startLine()) << std::endl; // TODO(bob): Lame hack! int line = pos->startLine(); while (line > 0) { std::cerr << " "; line /= 10; } std::cerr << " "; for (int i = 1; i < pos->endCol(); i++) { std::cerr << (i < pos->startCol() ? " " : "^"); } std::cerr << std::endl; } else { // Show all of the lines. for (int i = pos->startLine(); i <= pos->endLine(); i++) { // TODO(bob): Should pad line number so they all line up. std::cerr << i << ": " << pos->file()->getLine(i) << std::endl; } } }
void Resolver::allocateSlotsForParam(gc<Pattern> pattern) { // No parameter so do nothing. if (pattern.isNull()) return; RecordPattern* record = pattern->asRecordPattern(); if (record != NULL) { // Allocate each field. for (int i = 0; i < record->fields().count(); i++) { makeParamSlot(record->fields()[i].value); } } else { // If we got here, the pattern isn't a record, so it's a single slot. makeParamSlot(pattern); } }
void Resolver::destructureParam(gc<Pattern> pattern) { // No parameter so do nothing. if (pattern.isNull()) return; RecordPattern* record = pattern->asRecordPattern(); if (record != NULL) { // Resolve each field. for (int i = 0; i < record->fields().count(); i++) { resolveParam(record->fields()[i].value); } } else { // If we got here, the pattern isn't a record, so its a single slot. resolveParam(pattern); } }
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::compileParam(PatternCompiler& compiler, gc<Pattern> param, int& slot) { // No parameter so do nothing. if (param.isNull()) return; RecordPattern* record = param->asRecordPattern(); if (record != NULL) { // Compile each field. for (int i = 0; i < record->fields().count(); i++) { compileParamField(compiler, record->fields()[i].value, slot++); } } else { // If we got here, the pattern isn't a record, so it's a single slot. compileParamField(compiler, param, slot++); } }
void PatternCompiler::compile(gc<Pattern> pattern, int slot) { if (pattern.isNull()) return; pattern->accept(*this, slot); }