@@ -99,6 +99,9 @@ static int cmp_float(object* a, object* b) {
99
99
return (int )(a->as_double - b->as_double );
100
100
}
101
101
102
+ // ------------------------ core types -----------------
103
+ // these will later be swapped for actual objects
104
+
102
105
// metadata = line, column, file, prototypes
103
106
const object_schema metadata_type (" object_metadata" , initmulti<4 >, NULL , markmulti<4 >, freemulti);
104
107
// cons = car, cdr
@@ -107,6 +110,9 @@ const object_schema cons_type("cons", tinobsy::schema_functions::init_cons, NULL
107
110
const object_schema partial_type (" function_partial" , initmulti<5 >, NULL , markmulti<5 >, freemulti);
108
111
// error = type, message, detail, then
109
112
const object_schema error_type (" error" , initmulti<4 >, NULL , markmulti<4 >, freemulti);
113
+ // list = items
114
+ const object_schema list_type (" list" , initmulti<1 >, NULL , markmulti<1 >, freemulti);
115
+ // --------- primitive/ish types ---------------
110
116
const object_schema string_type (" string" , init_string, cmp_string, mark_string, del_string);
111
117
const object_schema symbol_type (" symbol" , tinobsy::schema_functions::init_str, tinobsy::schema_functions::cmp_str, NULL , tinobsy::schema_functions::finalize_str);
112
118
const object_schema c_function_type (" c_function" , init_c_function, cmp_c_function, NULL , NULL );
@@ -146,6 +152,10 @@ object* pickle::append(object* l1, object* l2) {
146
152
147
153
void pickle::set_retval (object* args, object* env, object* cont, object* fail_cont) {
148
154
if (cont == NULL ) return ; // No next continuation -> drop the result
155
+ if (cont->schema == &c_function_type) {
156
+ // stupid waste of an object
157
+ cont = this ->make_partial (cont, args, env, NULL , fail_cont);
158
+ }
149
159
object* thunk = this ->make_partial (cont->cells [0 ].as_obj , this ->append (cont->cells [1 ].as_obj , args), env, cont->cells [3 ].as_obj , fail_cont);
150
160
this ->do_later (thunk);
151
161
}
@@ -204,50 +214,71 @@ void pickle::mark_globals() {
204
214
this ->globals ->mark ();
205
215
}
206
216
217
+ void getarg (pickle* vm, object* args, size_t nth, const object_schema* type, object* env, object* fail, object* then) {
218
+ auto oa = args;
219
+ for (size_t i = 0 ; i < nth; i++) {
220
+ if (cdr (args) == NULL ) {
221
+ vm->set_failure (vm->wrap_error (vm->wrap_symbol (" ValueError" ), vm->list (2 , oa, vm->wrap_integer (nth)), then), env, then, fail);
222
+ return ;
223
+ }
224
+ args = cdr (args);
225
+ }
226
+ auto val = car (args);
227
+ if (val == NULL || (val->schema != type))
228
+ vm->set_failure (vm->wrap_error (vm->wrap_symbol (" TypeError" ), vm->list (3 , oa, vm->wrap_integer (nth), val), then), env, then, fail);
229
+ else
230
+ vm->set_retval (vm->list (2 , car (args), oa), env, then, fail);
231
+ }
232
+
233
+ // --------------- PARSER --------------------------------------
234
+
207
235
// Can be called by the program
208
- void funcs::parse (pickle* runner , object* args, object* env, object* cont, object* fail_cont) {
236
+ void funcs::parse (pickle* vm , object* args, object* env, object* cont, object* fail_cont) {
209
237
DBG (" parsing" );
210
- object* s = car (args);
211
- const char * str = (const char *)(s->cells [0 ].as_chars );
212
- object* result = s->cells [1 ].as_obj ;
213
- if (result) { // Saved preparse
214
- if (result->schema == &error_type) goto failure;
215
- else goto success;
216
- }
217
- TODO;
218
- // result = runner->wrap_error(runner->wrap_symbol("SyntaxError"), runner->wrap_string(message), runner->list(1, result), cont)
219
- success:
220
- runner->set_retval (runner->list (1 , result), env, cont, fail_cont);
221
- s->cells [1 ].as_obj = result; // Save parse for later if constantly reparsing string (i.e. a loop)
222
- return ;
223
- failure:
224
- runner->set_failure (result, env, cont, fail_cont);
225
- // TODO: copy error as cached parse result
238
+ getarg (vm, args, 0 , &string_type, env, fail_cont, vm->wrap_func (PICKLE_INLINE_FUNC {
239
+ GOTTEN_ARG (s);
240
+ const char * str = (const char *)(s->cells [0 ].as_chars );
241
+ object* result = s->cells [1 ].as_obj ;
242
+ const char * message;
243
+ bool success = true ;
244
+ if (result) { // Saved preparse
245
+ if (result->schema == &error_type) success = false ;
246
+ goto done;
247
+ }
248
+ result = vm->wrap_string (" Hello, World! parse result i am." );
249
+ done:
250
+ if (success) vm->set_retval (vm->list (1 , result), env, cont, fail_cont);
251
+ else {
252
+ result = vm->wrap_error (vm->wrap_symbol (" SyntaxError" ), vm->list (1 , vm->wrap_string (message), result), cont);
253
+ vm->set_failure (result, env, cont, fail_cont);
254
+ }
255
+ s->cells [1 ].as_obj = result; // Save parse for later if constantly eval'ing string (i.e. a loop)
256
+ }));
226
257
}
227
258
228
- static object* get_best_match (pickle* runner , object* ast, object** env) {
229
- TODO;
259
+ static object* get_best_match (pickle* vm , object* ast, object** env) {
260
+ TODO (gbm) ;
230
261
return NULL ;
231
262
}
232
263
233
264
// Eval(list) ::= apply_first_pattern(list), then eval(remaining list), else list if no patterns match
234
- void funcs::eval (pickle* runner , object* args, object* env, object* cont, object* fail_cont) {
265
+ void funcs::eval (pickle* vm , object* args, object* env, object* cont, object* fail_cont) {
235
266
object* ast = car (args);
236
267
// returns Match object: 0=pattern, 1=handler body, 2=match details for splice; and updates env with bindings
237
268
object* oldenv = env;
238
- object* matched_pattern = get_best_match (runner , ast, &env);
269
+ object* matched_pattern = get_best_match (vm , ast, &env);
239
270
if (matched_pattern != NULL ) {
240
271
// do next is run body --> cont=apply match cont-> eval again -> original eval cont
241
- runner ->do_later (runner ->make_partial (
272
+ vm ->do_later (vm ->make_partial (
242
273
NULL ,// matched_pattern->body(),
243
274
NULL ,
244
275
env,
245
- runner ->make_partial (
246
- runner ->wrap_func (funcs::splice_match),
247
- runner ->list (2 , runner ->append (ast, NULL ), NULL /* matched_pattern->match_info()*/ ),
276
+ vm ->make_partial (
277
+ vm ->wrap_func (funcs::splice_match),
278
+ vm ->list (2 , vm ->append (ast, NULL ), NULL /* matched_pattern->match_info()*/ ),
248
279
oldenv,
249
- runner ->make_partial (
250
- runner ->wrap_func (funcs::eval),
280
+ vm ->make_partial (
281
+ vm ->wrap_func (funcs::eval),
251
282
NULL ,
252
283
oldenv,
253
284
cont,
@@ -259,12 +290,12 @@ void funcs::eval(pickle* runner, object* args, object* env, object* cont, object
259
290
));
260
291
} else {
261
292
// No matches so return unchanged
262
- runner ->set_retval (runner ->list (1 , ast), env, cont, fail_cont);
293
+ vm ->set_retval (vm ->list (1 , ast), env, cont, fail_cont);
263
294
}
264
295
}
265
296
266
- void funcs::splice_match (pickle* runner , object* args, object* env, object* cont, object* fail_cont) {
267
- TODO;
297
+ void funcs::splice_match (pickle* vm , object* args, object* env, object* cont, object* fail_cont) {
298
+ TODO (sm) ;
268
299
}
269
300
270
301
0 commit comments