#include #include #include "messages.h" #include "Symbol.h" #include "types.h" using namespace std; Messages::Messages() /* Default settings */ : show_warnings(true), warnings(0), suppressed(0), errors(0) {} void Messages::EnableWarnings() { show_warnings = true; } void Messages::DisableWarnings() { show_warnings = false; } void Messages::Warning(int lineno, const char *msg, ...) { if (show_warnings) { ++warnings; fprintf(stderr, "Warning: %d: ", lineno); va_list args; va_start(args, msg); vfprintf(stderr, msg, args); va_end(args); } else { ++suppressed; } } void Messages::Error(int lineno, const char *msg, ...) { ++errors; fprintf(stderr, "Error: %d: ", lineno); va_list args; va_start(args, msg); vfprintf(stderr, msg, args); va_end(args); } void Messages::CoercionWarning(int lineno, ReturnType to, ReturnType from) { Warning(lineno, "Type coerced from %s to %s.\n", ReturnTypeToString(from), ReturnTypeToString(to)); } void Messages::ReturnValueError(int lineno, const string& id, ReturnType type) { Error(lineno, "Return value of type %s from function %s discarded.\n", ReturnTypeToString(type), id.c_str()); } void Messages::TypeError(int lineno, ReturnType expected, ReturnType received) { Error(lineno, "Expected type %s, got type %s.\n", ReturnTypeToString(expected), ReturnTypeToString(received)); } void Messages::UndeclaredIdError(int lineno, const string& id) { Error(lineno, "Identifier \'%s\' undeclared.\n", id.c_str()); } void Messages::DeclaredIdError(int lineno, const string& id, int prev_lineno) { Error(lineno, "Identifier \'%s\' was already previously declared on line %d.\n", id.c_str(), prev_lineno); } void Messages::LValueError(int lineno, const string& id) { Error(lineno, "Identifier \'%s\' is not a lvalue.\n", id.c_str()); } void Messages::RValueError(int lineno, const string& id, SymbolType symbol_type) { Error(lineno, "Identifier \'%s\' is a %s and can't be used here.\n", id.c_str(), SymbolTypeToString(symbol_type)); } void Messages::CallError(int lineno, const string& id, SymbolType symbol_type) { Error(lineno, "Identifier \'%s\' is a %s, was expecting a function or procedure.\n", id.c_str(), SymbolTypeToString(symbol_type)); } void Messages::ParamCountError(int lineno, int paramcount, Symbol *symbol) { Error(lineno, "%s parameters in call to %s.\n", ((paramcount > symbol->GetParameterCount())? "Too many" : "Too few"), SignatureString(symbol).c_str()); } void Messages::ShowNumbers() const { fprintf(stderr, "%d warning%s(%d suppressed) and %d error%s.\n", warnings, ((warnings == 1) ? "" : "s"), suppressed, errors, ((errors == 1) ? "" : "s")); } int Messages::GetErrors() const { return errors; } int Messages::GetWarnings() const { return warnings + suppressed; } string Messages::SignatureString(Symbol *symbol) { string signature = ""; signature += SymbolTypeToString(symbol->GetSymbolType()); signature += " "; signature += symbol->GetName(); signature += "("; const int parametercount = symbol->GetParameterCount(); for (int i = 0; i < parametercount; ++i) { Symbol *param = symbol->GetParameter(i); signature += param->GetName(); signature += ": "; signature += ReturnTypeToString(param->GetReturnType()); signature += ((i == parametercount) ? "): " : ", "); } signature += ReturnTypeToString(symbol->GetReturnType()); return signature; }