Add a function for raising errors (first attempt)
This commit is contained in:
parent
4a7afa0626
commit
9298e5a65b
3 changed files with 44 additions and 0 deletions
|
@ -20,6 +20,7 @@ enum class ErrorCode {
|
||||||
AssertionFailed,
|
AssertionFailed,
|
||||||
DivisionByZero,
|
DivisionByZero,
|
||||||
SyntaxError,
|
SyntaxError,
|
||||||
|
RuntimeError,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Value;
|
class Value;
|
||||||
|
@ -46,6 +47,13 @@ void reseterrobj();
|
||||||
ErrorCode::code; \
|
ErrorCode::code; \
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
#define ERROR_OBJ(code, obj) \
|
||||||
|
(({ \
|
||||||
|
TRY(seterrobj(obj)); \
|
||||||
|
seterr("Error " STRINGIZE(code) " at " __FILE__ ":" STRINGIZE(__LINE__)); \
|
||||||
|
ErrorCode::code; \
|
||||||
|
}))
|
||||||
|
|
||||||
#define ERROR_FMT(code, ...) \
|
#define ERROR_FMT(code, ...) \
|
||||||
(({ \
|
(({ \
|
||||||
auto name = TRY(Symbol::create(errname(ErrorCode::code))); \
|
auto name = TRY(Symbol::create(errname(ErrorCode::code))); \
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "stdlib.hpp"
|
#include "stdlib.hpp"
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
#include "error.hpp"
|
||||||
#include "pod.hpp"
|
#include "pod.hpp"
|
||||||
#include "sourcerange.hpp"
|
#include "sourcerange.hpp"
|
||||||
#include "writer.hpp"
|
#include "writer.hpp"
|
||||||
|
@ -259,6 +260,39 @@ Result<StackFrame> stdlib_map(const StackFrame& stack_param) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<StackFrame> 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<Symbol>()) {
|
||||||
|
error_name = std::move(param);
|
||||||
|
error_message = TRY(String::create(""));
|
||||||
|
} else if (param.is<String>()) {
|
||||||
|
error_name = TRY(Symbol::create("error"));
|
||||||
|
error_message = std::move(param);
|
||||||
|
} else {
|
||||||
|
return ERROR(TypeMismatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error_name.is<Symbol>() || !error_message.is<String>())
|
||||||
|
return ERROR(TypeMismatch);
|
||||||
|
|
||||||
|
auto val = Value(TRY(
|
||||||
|
Error::create(*error_name.to<Symbol>(), *error_message.to<String>())));
|
||||||
|
|
||||||
|
return ERROR_OBJ(RuntimeError, val);
|
||||||
|
}
|
||||||
|
|
||||||
#define STDLIB_FUNCTION(name, id) \
|
#define STDLIB_FUNCTION(name, id) \
|
||||||
[(uint64_t)StdlibFunctionId::id] = {#name, StdlibFunctionId::id, \
|
[(uint64_t)StdlibFunctionId::id] = {#name, StdlibFunctionId::id, \
|
||||||
stdlib_##name}
|
stdlib_##name}
|
||||||
|
@ -277,6 +311,7 @@ static StdlibFunctionEntry function_entries[] = {
|
||||||
STDLIB_FUNCTION(srcloc, SrcLoc),
|
STDLIB_FUNCTION(srcloc, SrcLoc),
|
||||||
STDLIB_FUNCTION(size, Size),
|
STDLIB_FUNCTION(size, Size),
|
||||||
STDLIB_FUNCTION(map, Map),
|
STDLIB_FUNCTION(map, Map),
|
||||||
|
STDLIB_FUNCTION(error, Error),
|
||||||
[(uint64_t)StdlibFunctionId::Max] = {0, StdlibFunctionId::Max,
|
[(uint64_t)StdlibFunctionId::Max] = {0, StdlibFunctionId::Max,
|
||||||
stdlib_unknown},
|
stdlib_unknown},
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,7 @@ enum class StdlibFunctionId : uint64_t {
|
||||||
SrcLoc,
|
SrcLoc,
|
||||||
Size,
|
Size,
|
||||||
Map,
|
Map,
|
||||||
|
Error,
|
||||||
Max,
|
Max,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue