-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy patherrors.cpp
More file actions
114 lines (100 loc) · 3.81 KB
/
Copy patherrors.cpp
File metadata and controls
114 lines (100 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "errors.h"
#include "../engine.h"
#include "../format.h"
#include "function.h"
#define ERRORTYPE(x, name) \
x *x::create(const String2 &m) { \
x *re = Gc::alloc<x>(); \
re->message = m; \
return re; \
} \
Value x::sete(const String2 &m) { \
ExecutionEngine::setPendingException(create(m)); \
return ValueNil; \
} \
Value x::sete(const char *m) { return sete(String::from(m)); } \
Value next_##x##_construct_1(const Value *args, int numargs) { \
(void)numargs; \
EXPECT(name, "new(_)", 1, String); \
return x::create(args[1].toString()); \
} \
void x::init(Class *x##Class) { \
x##Class->derive(Classes::get<Error>()); \
x##Class->add_builtin_fn("(_)", 1, next_##x##_construct_1); \
}
#include "error_types.h"
Class *Error::ErrorObjectClass = nullptr;
Error *Error::create(const String2 &m) {
Error *re = Gc::alloc<Error>();
re->message = m;
return re;
}
Value Error::sete(const String2 &m) {
ExecutionEngine::setPendingException(create(m));
return ValueNil;
}
Value Error::sete(const char *m) {
return sete(String::from(m));
}
Value Error::setIndexError(const char *m, int64_t h, int64_t l, int64_t r) {
return IndexError::sete(
Formatter::fmt("{} (expected {} <= index <= {}, received {})", m, l, h,
r)
.toString());
}
Value Error::setTypeError(const String2 &o, const String2 &m, const String2 &e,
Value r, int arg) {
return TypeError::sete(
Formatter::fmt(
"Expected argument {} of {}.{} to be '{}', received '{}'!",
Value(arg), Value(o), Value(m), Value(e), Value(r.getClass()->name))
.toString());
}
Value Error::setTypeError(const char *o, const char *m, const char *e, Value r,
int arg) {
return setTypeError(String::from(o), String::from(m), String::from(e), r,
arg);
}
Value next_error_str(const Value *args, int numargs) {
(void)numargs;
return Value(args[0].toError()->message);
}
Value next_error_construct_1(const Value *args, int numargs) {
(void)numargs;
EXPECT(error, "(_)", 1, String);
return Error::create(args[1].toString());
}
Function2 ErrorObjectClassConstructor(Class *c) {
Function2 f = Function::create(String::from("new"), 1);
f->code = Bytecode::create();
// new(x) { message = x }
f->code->insertSlot(); // this
f->code->insertSlot(); // x
f->code->construct(c);
f->code->load_slot_1();
f->code->store_object_slot(0);
f->code->pop();
f->code->load_slot_0();
f->code->ret();
return f;
}
Function2 ErrorObjectClassStr() {
Function2 f = Function::create(String::from("str"), 0);
f->code = Bytecode::create();
// str() { ret message }
f->code->insertSlot(); // this
f->code->load_object_slot(0);
f->code->ret();
return f;
}
void Error::init(Class *ErrorClass) {
ErrorClass->add_builtin_fn("(_)", 1, next_error_construct_1);
ErrorClass->add_builtin_fn("str()", 0, next_error_str);
// allocate the error object class
ErrorObjectClass = Class::create();
ErrorObjectClass->init_class("error", Class::ClassType::NORMAL);
ErrorObjectClass->numSlots = 1; // message
ErrorObjectClass->add_fn("(_)",
ErrorObjectClassConstructor(ErrorObjectClass));
ErrorObjectClass->add_fn("str()", ErrorObjectClassStr());
}