Skip to content

Commit c410fe7

Browse files
redo schema functions with templates
1 parent b8b96db commit c410fe7

File tree

6 files changed

+63
-70
lines changed

6 files changed

+63
-70
lines changed

pickle.cpp

+20-35
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,19 @@ bool needs_escape(char c) {
4040
return strchr("{}\b\t\n\v\f\r\a\\\"", c) != NULL;
4141
}
4242

43-
static void init_metadata(object* self, va_list args) {
44-
self->cells = new cell[4];
45-
self->cells[0].as_obj = va_arg(args, object*); // line
46-
self->cells[1].as_obj = va_arg(args, object*); // column
47-
self->cells[2].as_obj = va_arg(args, object*); // file
48-
self->cells[3].as_obj = va_arg(args, object*); // prototypes list
43+
template <int n> void initmulti(object* self, va_list args) {
44+
self->cells = new cell[n];
45+
DBG("creating %s (%i cells)", self->schema->name, n);
46+
for (int i = 0; i < n; i++) self->cells[i].as_obj = va_arg(args, object*);
47+
4948
}
5049

51-
static void mark4(object* self) {
52-
for (int i = 0; i < 3; i++) self->cells[i].as_obj->mark();
50+
template <int n> void markmulti(object* self) {
51+
for (int i = 0; i < n; i++) self->cells[i].as_obj->mark();
5352
}
5453

54+
#define freemulti tinobsy::schema_functions::finalize_cons
55+
5556
static void init_c_function(object* self, va_list args) {
5657
self->as_ptr = (void*)va_arg(args, func_ptr);
5758
DBG("Function is eval(): %s", self->as_ptr == funcs::eval ? "true" : "false");
@@ -62,19 +63,6 @@ static int cmp_c_function(object* a, object* b) {
6263
return (uintptr_t)a->as_ptr - (uintptr_t)b->as_ptr;
6364
}
6465

65-
static void init_function_partial(object* self, va_list args) {
66-
self->cells = new cell[5];
67-
self->cells[0].as_obj = va_arg(args, object*); // function
68-
self->cells[1].as_obj = va_arg(args, object*); // args
69-
self->cells[2].as_obj = va_arg(args, object*); // env
70-
self->cells[3].as_obj = va_arg(args, object*); // cont
71-
self->cells[4].as_obj = va_arg(args, object*); // failcont
72-
}
73-
74-
static void mark_function_partial(object* self) {
75-
for (int i = 0; i < 5; i++) self->cells[i].as_obj->mark();
76-
}
77-
7866
static void init_string(object* self, va_list args) {
7967
self->cells = new cell[2];
8068
self->cells[0].as_ptr = (void*)strdup(va_arg(args, char*));
@@ -95,14 +83,6 @@ static void del_string(object* self) {
9583
delete[] self->cells;
9684
}
9785

98-
static void init_error(object* self, va_list args) {
99-
DBG("Creating an error");
100-
self->cells = new cell[3];
101-
self->cells[0].as_obj = va_arg(args, object*);
102-
self->cells[1].as_obj = va_arg(args, object*);
103-
self->cells[2].as_obj = va_arg(args, object*);
104-
}
105-
10686
static void init_int(object* self, va_list args) {
10787
self->as_big_int = va_arg(args, int64_t);
10888
}
@@ -119,13 +99,17 @@ static int cmp_float(object* a, object* b) {
11999
return (int)(a->as_double - b->as_double);
120100
}
121101

122-
const object_schema metadata_type("object_metadata", init_metadata, NULL, mark4, tinobsy::schema_functions::finalize_cons);
123-
const object_schema cons_type("cons", tinobsy::schema_functions::init_cons, NULL, tinobsy::schema_functions::mark_cons, tinobsy::schema_functions::finalize_cons);
124-
const object_schema partial_type("function_partial", init_function_partial, NULL, NULL, tinobsy::schema_functions::finalize_cons);
102+
// metadata = line, column, file, prototypes
103+
const object_schema metadata_type("object_metadata", initmulti<4>, NULL, markmulti<4>, freemulti);
104+
// cons = car, cdr
105+
const object_schema cons_type("cons", tinobsy::schema_functions::init_cons, NULL, tinobsy::schema_functions::mark_cons, freemulti);
106+
// partial = function, args, env, then, catch
107+
const object_schema partial_type("function_partial", initmulti<5>, NULL, markmulti<5>, freemulti);
108+
// error = type, message, detail, then
109+
const object_schema error_type("error", initmulti<4>, NULL, markmulti<4>, freemulti);
125110
const object_schema string_type("string", init_string, cmp_string, mark_string, del_string);
126111
const object_schema symbol_type("symbol", tinobsy::schema_functions::init_str, tinobsy::schema_functions::cmp_str, NULL, tinobsy::schema_functions::finalize_str);
127112
const object_schema c_function_type("c_function", init_c_function, cmp_c_function, NULL, NULL);
128-
const object_schema error_type("error", init_error, NULL, mark4, tinobsy::schema_functions::finalize_cons);
129113
const object_schema integer_type("int", init_int, cmp_int, NULL, NULL);
130114
const object_schema float_type("float", init_float, cmp_float, NULL, NULL);
131115

@@ -217,6 +201,7 @@ void pickle::run_next_thunk() {
217201
void pickle::mark_globals() {
218202
this->queue_head->mark();
219203
this->queue_tail->mark(); // in case queue gets detached
204+
this->globals->mark();
220205
}
221206

222207
// Can be called by the program
@@ -225,12 +210,12 @@ void funcs::parse(pickle* runner, object* args, object* env, object* cont, objec
225210
object* s = car(args);
226211
const char* str = (const char*)(s->cells[0].as_chars);
227212
object* result = s->cells[1].as_obj;
228-
if (result != NULL) { // Saved preparse
213+
if (result) { // Saved preparse
229214
if (result->schema == &error_type) goto failure;
230215
else goto success;
231216
}
232217
TODO;
233-
// result = runner->wrap_error(runner->wrap_symbol("SyntaxError"), runner->list(1, result), cont)
218+
// result = runner->wrap_error(runner->wrap_symbol("SyntaxError"), runner->wrap_string(message), runner->list(1, result), cont)
234219
success:
235220
runner->set_retval(runner->list(1, result), env, cont, fail_cont);
236221
s->cells[1].as_obj = result; // Save parse for later if constantly reparsing string (i.e. a loop)

pickle_test.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ void start_catch_segfault() {
2121
int main() {
2222
start_catch_segfault();
2323
auto vm = new pickle::pickle();
24-
auto foo = vm->with_metadata(vm->wrap_string("thisWillCauseASyntaxError"), 1, 1, "foo.pickle", vm->list(3, NULL, NULL, NULL));
24+
auto foo = vm->with_metadata(vm->wrap_string("foo\n bar\n syntax error"), 1, 1, "foo.pickle", vm->list(3, NULL, NULL, NULL));
2525
vm->run_next_thunk();
2626
vm->gc();
2727
printf("hello world\n");

test/out32.txt

+7-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
[tinobsy/tinobsy.cpp:110-init_cons]
1010
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
1111
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a string
12-
[pickle.cpp:81-init_string] init_string: thisWillCauseASyntaxError
12+
[pickle.cpp:69-init_string] init_string: foo
13+
bar
14+
syntax error
1315
[tinobsy/tinobsy.cpp:38-allocate] Trying to intern a string
1416
[tinobsy/tinobsy.cpp:47-allocate] New string not interned
1517
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
1618
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a string
17-
[pickle.cpp:81-init_string] init_string: foo.pickle
19+
[pickle.cpp:69-init_string] init_string: foo.pickle
1820
[tinobsy/tinobsy.cpp:38-allocate] Trying to intern a string
1921
[tinobsy/tinobsy.cpp:47-allocate] New string not interned
2022
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
@@ -30,10 +32,12 @@
3032
[tinobsy/tinobsy.cpp:27-~object] }
3133
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
3234
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a object_metadata
33-
[pickle.cpp:189-run_next_thunk] run_next_thunk
35+
[pickle.cpp:45-initmulti] creating object_metadata (4 cells)
36+
[pickle.cpp:173-run_next_thunk] run_next_thunk
3437
[tinobsy/tinobsy.cpp:79-gc] vm::gc() begin, 7 objects {
3538
[tinobsy/tinobsy.cpp:59-mark] NULL::mark()
3639
[tinobsy/tinobsy.cpp:59-mark] NULL::mark()
40+
[tinobsy/tinobsy.cpp:59-mark] NULL::mark()
3741
[tinobsy/tinobsy.cpp:82-gc] garbage collect sweeping
3842
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a object_metadata begin {
3943
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL

test/out64.txt

+7-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
[tinobsy/tinobsy.cpp:110-init_cons]
1010
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
1111
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a string
12-
[pickle.cpp:81-init_string] init_string: thisWillCauseASyntaxError
12+
[pickle.cpp:69-init_string] init_string: foo
13+
bar
14+
syntax error
1315
[tinobsy/tinobsy.cpp:38-allocate] Trying to intern a string
1416
[tinobsy/tinobsy.cpp:47-allocate] New string not interned
1517
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
1618
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a string
17-
[pickle.cpp:81-init_string] init_string: foo.pickle
19+
[pickle.cpp:69-init_string] init_string: foo.pickle
1820
[tinobsy/tinobsy.cpp:38-allocate] Trying to intern a string
1921
[tinobsy/tinobsy.cpp:47-allocate] New string not interned
2022
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
@@ -30,10 +32,12 @@
3032
[tinobsy/tinobsy.cpp:27-~object] }
3133
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
3234
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a object_metadata
33-
[pickle.cpp:189-run_next_thunk] run_next_thunk
35+
[pickle.cpp:45-initmulti] creating object_metadata (4 cells)
36+
[pickle.cpp:173-run_next_thunk] run_next_thunk
3437
[tinobsy/tinobsy.cpp:79-gc] vm::gc() begin, 7 objects {
3538
[tinobsy/tinobsy.cpp:59-mark] NULL::mark()
3639
[tinobsy/tinobsy.cpp:59-mark] NULL::mark()
40+
[tinobsy/tinobsy.cpp:59-mark] NULL::mark()
3741
[tinobsy/tinobsy.cpp:82-gc] garbage collect sweeping
3842
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a object_metadata begin {
3943
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL

test/valgrind32.txt

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
==22550== Memcheck, a memory error detector
2-
==22550== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
3-
==22550== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
4-
==22550== Command: ./pickletest32
5-
==22550==
6-
==22550==
7-
==22550== HEAP SUMMARY:
8-
==22550== in use at exit: 0 bytes in 0 blocks
9-
==22550== total heap usage: 19 allocs, 19 frees, 23,349 bytes allocated
10-
==22550==
11-
==22550== All heap blocks were freed -- no leaks are possible
12-
==22550==
13-
==22550== For lists of detected and suppressed errors, rerun with: -s
14-
==22550== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
1+
==30231== Memcheck, a memory error detector
2+
==30231== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
3+
==30231== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
4+
==30231== Command: ./pickletest32
5+
==30231==
6+
==30231==
7+
==30231== HEAP SUMMARY:
8+
==30231== in use at exit: 0 bytes in 0 blocks
9+
==30231== total heap usage: 19 allocs, 19 frees, 23,350 bytes allocated
10+
==30231==
11+
==30231== All heap blocks were freed -- no leaks are possible
12+
==30231==
13+
==30231== For lists of detected and suppressed errors, rerun with: -s
14+
==30231== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

test/valgrind64.txt

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
==22530== Memcheck, a memory error detector
2-
==22530== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
3-
==22530== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
4-
==22530== Command: ./pickletest64
5-
==22530==
6-
==22530==
7-
==22530== HEAP SUMMARY:
8-
==22530== in use at exit: 0 bytes in 0 blocks
9-
==22530== total heap usage: 19 allocs, 19 frees, 77,317 bytes allocated
10-
==22530==
11-
==22530== All heap blocks were freed -- no leaks are possible
12-
==22530==
13-
==22530== For lists of detected and suppressed errors, rerun with: -s
14-
==22530== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
1+
==30205== Memcheck, a memory error detector
2+
==30205== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
3+
==30205== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
4+
==30205== Command: ./pickletest64
5+
==30205==
6+
==30205==
7+
==30205== HEAP SUMMARY:
8+
==30205== in use at exit: 0 bytes in 0 blocks
9+
==30205== total heap usage: 19 allocs, 19 frees, 77,318 bytes allocated
10+
==30205==
11+
==30205== All heap blocks were freed -- no leaks are possible
12+
==30205==
13+
==30205== For lists of detected and suppressed errors, rerun with: -s
14+
==30205== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

0 commit comments

Comments
 (0)