//
// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
//
// The contents of this file are covered under the licence agreement in the
// file "LICENCE" distributed with Cforall.
//
// SemanticError.h --
//
// Author           : Richard C. Bilson
// Created On       : Mon May 18 07:44:20 2015
// Last Modified By : Peter A. Buhr
// Last Modified On : Tue Aug 29 22:03:36 2017
// Update Count     : 17
//

#pragma once

#include <exception>									// for exception
#include <iostream>										// for ostream
#include <list>											// for list
#include <string>										// for string
#include <unistd.h>										// for isatty

#include "CodeLocation.h"								// for CodeLocation, toString

struct error {
	std::string description;
	CodeLocation location;

	error() = default;
	error( const std::string & str ) : description( str ) {}

	void maybeSet( const CodeLocation & location ) {
		if( this->location.isUnset() ) {
			this->location = location;
		}
	}
};

class SemanticError : public std::exception {
  public:
	SemanticError();
	SemanticError( std::string error );
	template< typename T > SemanticError( const std::string & error, const T * obj );
	~SemanticError() throw() {}

	static inline const std::string & error_str() {
		static std::string str = isatty( STDERR_FILENO ) ? "\e[31merror:\e[39m " : "error: ";
		return str;
	}

	void append( SemanticError & other );
	void append( const std::string & );
	bool isEmpty() const;
	void print( std::ostream & os );

	void set_location( const CodeLocation & location );
	// constructs an exception using the given message and the printed representation of the obj (T must have a print
	// method)
  private:
	std::list< error > errors;
};

template< typename T >
SemanticError::SemanticError( const std::string & error, const T * obj ) {
	append( toString( error, obj ) );
}

// Local Variables: //
// tab-width: 4 //
// mode: c++ //
// compile-command: "make install" //
// End: //
