Program Listing for File exceptions.h¶
↰ Return to documentation for file (src/exceptions.h)
//
// Created by Zayd Hammoudeh on 11/7/18.
//
#ifndef PROJECT02_EXCEPTIONS_H
#define PROJECT02_EXCEPTIONS_H
#include <exception>
#include <string>
#include <sstream>
struct BaseCompilerException : public std::exception {
BaseCompilerException(const char *type, const char *error) {
std::stringstream ss;
ss << "(" << type << "): " << error;
msg_ = ss.str();
}
BaseCompilerException(const char *type, const std::string &error)
: BaseCompilerException(type, error.c_str()) {}
virtual const char * what() const throw () {
return msg_.c_str();
};
protected:
std::string msg_;
};
//=====================================================================================//
// Exceptions for the Different Compiler Stages //
//=====================================================================================//
struct ScannerException : public BaseCompilerException {
ScannerException(const char *error)
: BaseCompilerException("Scanner", error) {}
ScannerException(const std::string &error)
: ScannerException(error.c_str()) {}
};
struct ParserException : public BaseCompilerException {
ParserException(const char *error)
: BaseCompilerException("Parser", error) {}
ParserException(const std::string &error)
: ParserException(error.c_str()) {}
};
struct TypeCheckerException : public BaseCompilerException {
TypeCheckerException(const char *type, const char *error)
: BaseCompilerException(type, error) {}
TypeCheckerException(const char *type, const std::string &error)
: TypeCheckerException(type, error.c_str()) {}
};
//=====================================================================================//
// Three Primary Classes of Type Checker Exceptions //
//=====================================================================================//
struct ClassHierarchyException : public TypeCheckerException {
ClassHierarchyException(const char *type, const char *error)
: TypeCheckerException(type, error) {}
ClassHierarchyException(const char *type, const std::string &error)
: TypeCheckerException(type, error.c_str()) {}
};
struct InitializeBeforeUseException : public TypeCheckerException {
InitializeBeforeUseException(const char *type, const char *error)
: TypeCheckerException(type, error) {}
InitializeBeforeUseException(const char *type, const std::string &error)
: TypeCheckerException(type, error) {}
};
struct TypeInferenceException : TypeCheckerException {
explicit TypeInferenceException(const char* error_name, const char* msg)
: TypeCheckerException(error_name, msg) {}
explicit TypeInferenceException(const char* error_name, const std::string &msg)
: TypeCheckerException(error_name, msg.c_str()) {}
};
//=====================================================================================//
// Well Formed Hierarchy Exceptions //
//=====================================================================================//
struct CyclicInheritenceException : public ClassHierarchyException {
CyclicInheritenceException(const char *type, const char *error)
: ClassHierarchyException(type, error) {}
CyclicInheritenceException(const char *type, const std::string &error)
: CyclicInheritenceException(type, error.c_str()) {}
};
struct InheritedMethodReturnTypeException : public ClassHierarchyException {
InheritedMethodReturnTypeException(const std::string &class_name, const std::string &method_name)
: ClassHierarchyException("InheritedMethodType", build_error_msg(class_name, method_name)) {}
private:
static std::string build_error_msg(const std::string &class_name, const std::string &method_name){
return "Class \"" + class_name + "\" has method \"" + method_name + "\" whose return type "
+ "is not a subtype of its super class.";
}
};
struct InheritedMethodParamCountException : public ClassHierarchyException {
InheritedMethodParamCountException(const std::string &class_name, const std::string &method_name)
: ClassHierarchyException("InheritedMethodParam", build_error_msg(class_name, method_name)) {}
private:
static std::string build_error_msg(const std::string &class_name, const std::string &method_name){
return "Class \"" + class_name + "\" has method \"" + method_name + "\" whose parameter count "
+ "does not match its super class.";
}
};
struct InheritedMethodParamTypeException : public ClassHierarchyException {
InheritedMethodParamTypeException(const std::string &class_name, const std::string &method_name,
const std::string ¶m_name)
: ClassHierarchyException("InheritedMethodParam",
build_error_msg(class_name, method_name, param_name)) {}
private:
static std::string build_error_msg(const std::string &class_name, const std::string &method_name,
const std::string ¶m_name){
return "Class \"" + class_name + "\" has method \"" + method_name + "\" whose parameter \""
+ param_name + "\" does not match its super class parameter type.";
}
};
struct UnknownTypeException : public ClassHierarchyException {
explicit UnknownTypeException(const std::string &class_name)
: ClassHierarchyException("TypeError", build_error_msg(class_name)) {}
explicit UnknownTypeException(const char *type, const std::string &msg)
: ClassHierarchyException("TypeError", msg) {}
private:
static std::string build_error_msg(const std::string &class_name) {
return "Unknown class \"" + class_name + "\"";
}
};
class ReturnAllPathsException : public TypeCheckerException {
public:
explicit ReturnAllPathsException(const std::string &type_name, const std::string &method_name)
: TypeCheckerException("MissingReturnMismatch", build_error_msg(type_name, method_name)) {}
private:
static std::string build_error_msg(const std::string &type_name, const std::string &method_name) {
return "Method " + method_name + " for class " + type_name + " does not have a return on all "
+ " paths. Cannot append \"return none\" without causing a type errorr.";
}
};
class UnknownSymbolException : public TypeCheckerException {
public:
explicit UnknownSymbolException(const std::string &symbol_name)
: TypeCheckerException("SymbolError", build_error_msg(symbol_name)) {}
private:
static std::string build_error_msg(const std::string &symbol_name) {
return "Unknown symbol \"" + symbol_name + "\"";
}
};
struct AmbiguousInferenceException : TypeCheckerException {
AmbiguousInferenceException(const char *type, const char *error)
: TypeCheckerException(type, error) {}
};
struct UnitializedVarException : public InitializeBeforeUseException {
UnitializedVarException(const char *type, const std::string &var_name, bool is_field)
: InitializeBeforeUseException(type, build_error_msg(var_name, is_field)) { }
private:
static std::string build_error_msg(const std::string &var_name, bool is_field) {
std::stringstream ss;
ss << (is_field ? "Field v" : "V") << "ariable \"" << var_name
<< "\" is used before initialization.";
return ss.str();
}
};
struct DuplicateMemberException : InitializeBeforeUseException {
explicit DuplicateMemberException(const std::string &type_name, const std::string &field_name)
: InitializeBeforeUseException("ClassError",
"Class \"" + type_name + "\" has duplicate field and method "
+ field_name) {}
};
struct FieldClassMatchException : InitializeBeforeUseException {
explicit FieldClassMatchException(const std::string &field_name)
: InitializeBeforeUseException("ClassError",
"Class \"" + field_name + "\" has a field of the same name") {}
};
struct MissingSuperFieldsException : public TypeCheckerException {
explicit MissingSuperFieldsException(const std::string &class_name)
: TypeCheckerException("MissingField", build_error_msg(class_name)) { }
private:
static const std::string build_error_msg(const std::string &class_name) {
return "Class \"" + class_name + "\" missing fields from its super class.";
}
};
struct MethodClassNameCollisionException : public TypeCheckerException {
explicit MethodClassNameCollisionException(const std::string &name)
: TypeCheckerException("NameCollision", build_error_msg(name)) { }
private:
static const std::string build_error_msg(const std::string &name) {
return "\"" + name + "\" is both a class and method name.";
}
};
struct SubTypeFieldTypeException : public TypeCheckerException {
explicit SubTypeFieldTypeException(const std::string &class_name, const std::string &field_name)
: TypeCheckerException("SubtypeFieldType", build_error_msg(class_name, field_name)) { }
private:
static std::string build_error_msg(const std::string &class_name, const std::string &field_name) {
return "Class " + class_name + " field \"" + field_name + "\" type not subtype of super class.";
}
};
struct DuplicateParamException : public TypeCheckerException {
explicit DuplicateParamException(const std::string ¶m_name)
: TypeCheckerException("DuplicateParam",
"Duplicate parameter \"" + param_name + "\"") {}
};
//=====================================================================================//
// Type Inference Exceptions //
//=====================================================================================//
struct UnknownConstructorException : TypeInferenceException {
explicit UnknownConstructorException(const std::string &type_name)
: TypeInferenceException("ClassError",
"Unknown class for constructor \"" + type_name + "\"") {}
};
struct UnknownBinOpException : public TypeInferenceException {
explicit UnknownBinOpException(const std::string &op)
: TypeInferenceException("UnknownOp",
"(UnknownOp): Unknown binary operator \"" + op + "\"") {}
};
#endif //PROJECT02_EXCEPTIONS_H