diff --git a/include/serene/exprs/error.h b/include/serene/exprs/error.h new file mode 100644 index 0000000..d6623b9 --- /dev/null +++ b/include/serene/exprs/error.h @@ -0,0 +1,73 @@ +/* -*- C++ -*- + * Serene programming language. + * + * Copyright (c) 2019-2021 Sameer Rahmani + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef EXPRS_ERROR_H +#define EXPRS_ERROR_H + +#include "serene/exprs/expression.h" +#include "llvm/ADT/StringRef.h" +#include + +namespace serene { + +namespace exprs { + +/// This enum represent the expression type and **not** the value type. +enum class ErrType { + Syntax, + Semantic, + Compile, +}; + +/// This data structure represent the Lisp error. This type of expression +/// doesn't show up in the AST but the compiler might rewrite the AST +/// to contains error expressions +class Error : public Expression { + +public: + ErrType errorType; + node target; + std::string message; + + Error(ErrType err, node &t, llvm::StringRef msg) + : Expression(t->location), errorType(err), target(t), message(msg){}; + + // Error(reader::LocationRange &loc, ErrType err, node &t, llvm::StringRef + // msg) + // : Expression(loc), errorType(err), target(t), message(msg) {}; + + ExprType getType() const; + std::string toString() const; + + static bool classof(const Expression *e); + + maybe_node analyze(reader::SemanticContext &); + + ~Error() = default; +}; + +} // namespace exprs +} // namespace serene + +#endif diff --git a/include/serene/exprs/expression.h b/include/serene/exprs/expression.h index f70844f..f08aa6f 100644 --- a/include/serene/exprs/expression.h +++ b/include/serene/exprs/expression.h @@ -45,6 +45,7 @@ enum class ExprType { List, Number, Def, + Error, }; class Expression; diff --git a/include/serene/exprs/symbol.h b/include/serene/exprs/symbol.h index fa5d0ce..17cf02c 100644 --- a/include/serene/exprs/symbol.h +++ b/include/serene/exprs/symbol.h @@ -37,9 +37,6 @@ namespace exprs { /// in the context of the AST and nothing else. class Symbol : public Expression { - // private: - // using Expression::analyze; - public: std::string name; diff --git a/src/serene/CMakeLists.txt b/src/serene/CMakeLists.txt index 0d6432a..1168f35 100644 --- a/src/serene/CMakeLists.txt +++ b/src/serene/CMakeLists.txt @@ -7,6 +7,7 @@ set(HEADER_LIST "${INCLUDE_DIR}/serene/exprs/list.h" "${INCLUDE_DIR}/serene/exprs/number.h" "${INCLUDE_DIR}/serene/exprs/def.h" + "${INCLUDE_DIR}/serene/exprs/error.h" # Reader "${INCLUDE_DIR}/serene/reader/reader.h" @@ -41,6 +42,7 @@ add_library(serene exprs/number.cpp exprs/expression.cpp exprs/def.cpp + exprs/error.cpp serene.cpp symbol.cpp diff --git a/src/serene/exprs/error.cpp b/src/serene/exprs/error.cpp new file mode 100644 index 0000000..a29f93a --- /dev/null +++ b/src/serene/exprs/error.cpp @@ -0,0 +1,48 @@ +/* + * Serene programming language. + * + * Copyright (c) 2019-2021 Sameer Rahmani + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "serene/exprs/error.h" +#include "llvm/Support/FormatVariadic.h" + +namespace serene { +namespace exprs { + +ExprType Error::getType() const { return ExprType::Error; }; + +std::string Error::toString() const { + return llvm::formatv("", + this->location.start.toString(), + this->location.end.toString(), this->message); +} + +maybe_node Error::analyze(reader::SemanticContext &ctx) { + return Result::Success(nullptr); +}; + +bool Error::classof(const Expression *e) { + return e->getType() == ExprType::Error; +}; + +} // namespace exprs +} // namespace serene diff --git a/src/tests/exprs/error_tests.cpp.inc b/src/tests/exprs/error_tests.cpp.inc new file mode 100644 index 0000000..122f7dd --- /dev/null +++ b/src/tests/exprs/error_tests.cpp.inc @@ -0,0 +1,49 @@ +/* -*- C++ -*- + * Serene programming language. + * + * Copyright (c) 2019-2021 Sameer Rahmani + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../test_helpers.cpp.inc" +#include "serene/exprs/symbol.h" +#include "serene/exprs/error.h" +#include "llvm/Support/Casting.h" +#include + +namespace serene { +namespace exprs { + +TEST_CASE("Error Expression", "[expression]") { + std::unique_ptr range(dummyLocation()); + + node sym = make(*range.get(), llvm::StringRef("example")); + node err = make(ErrType::Semantic, sym, "Something Failed"); + + REQUIRE(err->getType() == ExprType::Error); + CHECK(err->toString() == ""); + + auto error = llvm::dyn_cast(err.get()); + CHECK(error->errorType == ErrType::Semantic); + CHECK(error->target == sym); +}; + +} // namespace exprs +} // namespace serene diff --git a/src/tests/serenetests.cpp b/src/tests/serenetests.cpp index 4d1107a..7acedfa 100644 --- a/src/tests/serenetests.cpp +++ b/src/tests/serenetests.cpp @@ -23,6 +23,7 @@ */ #define CATCH_CONFIG_MAIN +#include "./exprs/error_tests.cpp.inc" #include "./exprs/expression_tests.cpp.inc" #include "./exprs/list_tests.cpp.inc" #include "./exprs/number_tests.cpp.inc"