diff --git a/src/error.hpp b/src/error.hpp index afc1144..d6f217d 100644 --- a/src/error.hpp +++ b/src/error.hpp @@ -20,6 +20,7 @@ enum class ErrorCode { AssertionFailed, DivisionByZero, SyntaxError, + RuntimeError, }; class Value; @@ -46,6 +47,13 @@ void reseterrobj(); ErrorCode::code; \ })) +#define ERROR_OBJ(code, obj) \ + (({ \ + TRY(seterrobj(obj)); \ + seterr("Error " STRINGIZE(code) " at " __FILE__ ":" STRINGIZE(__LINE__)); \ + ErrorCode::code; \ + })) + #define ERROR_FMT(code, ...) \ (({ \ auto name = TRY(Symbol::create(errname(ErrorCode::code))); \ diff --git a/src/stdlib.cpp b/src/stdlib.cpp index e111bd9..1bdf184 100644 --- a/src/stdlib.cpp +++ b/src/stdlib.cpp @@ -1,6 +1,7 @@ #include "stdlib.hpp" #include "common.hpp" +#include "error.hpp" #include "pod.hpp" #include "sourcerange.hpp" #include "writer.hpp" @@ -259,6 +260,39 @@ Result stdlib_map(const StackFrame& stack_param) { return res; } +Result stdlib_error(const StackFrame& stack) { + auto params = TRY(stack.get(0)); + auto size = TRY(params.size()); + if (size == 0 || size > 2) return ERROR(ArgumentCountMismatch); + + Value error_name; + Value error_message; + + if (size == 2) { + error_name = TRY(params.get(0)); + error_message = TRY(params.get(1)); + } else { + auto param = TRY(params.get(0)); + if (param.is()) { + error_name = std::move(param); + error_message = TRY(String::create("")); + } else if (param.is()) { + error_name = TRY(Symbol::create("error")); + error_message = std::move(param); + } else { + return ERROR(TypeMismatch); + } + } + + if (!error_name.is() || !error_message.is()) + return ERROR(TypeMismatch); + + auto val = Value(TRY( + Error::create(*error_name.to(), *error_message.to()))); + + return ERROR_OBJ(RuntimeError, val); +} + #define STDLIB_FUNCTION(name, id) \ [(uint64_t)StdlibFunctionId::id] = {#name, StdlibFunctionId::id, \ stdlib_##name} @@ -277,6 +311,7 @@ static StdlibFunctionEntry function_entries[] = { STDLIB_FUNCTION(srcloc, SrcLoc), STDLIB_FUNCTION(size, Size), STDLIB_FUNCTION(map, Map), + STDLIB_FUNCTION(error, Error), [(uint64_t)StdlibFunctionId::Max] = {0, StdlibFunctionId::Max, stdlib_unknown}, }; diff --git a/src/stdlib.hpp b/src/stdlib.hpp index 668efb3..d7dc4a1 100644 --- a/src/stdlib.hpp +++ b/src/stdlib.hpp @@ -18,6 +18,7 @@ enum class StdlibFunctionId : uint64_t { SrcLoc, Size, Map, + Error, Max, };