1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-24 09:17:17 +00:00

Add apply special form. TODO -

make into function.
This commit is contained in:
Calvin Rose 2017-04-19 09:43:49 -04:00
parent 01e8749f39
commit fb3abf5a31
2 changed files with 64 additions and 0 deletions

View File

@ -762,6 +762,59 @@ static Slot compile_var(GstCompiler *c, FormOptions opts, const GstValue *form)
return compile_assign(c, opts, form[1], form[2]);
}
/* Apply special */
static Slot compile_apply(GstCompiler *c, FormOptions opts, const GstValue *form) {
GstScope *scope = c->tail;
GstBuffer *buffer = c->buffer;
/* Empty forms evaluate to nil. */
if (gst_tuple_length(form) < 3)
c_error(c, "apply expects at least 2 arguments");
{
Slot ret, callee;
SlotTracker tracker;
FormOptions subOpts = form_options_default();
uint32_t i;
tracker_init(c, &tracker);
/* Compile function to be called */
callee = compiler_realize_slot(c, compile_value(c, subOpts, form[1]));
/* Compile all of the arguments */
for (i = 2; i < gst_tuple_length(form) - 1; ++i) {
Slot slot = compile_value(c, subOpts, form[i]);
compiler_tracker_push(c, &tracker, slot);
}
/* Write last item */
{
Slot slot = compile_value(c, subOpts, form[gst_tuple_length(form) - 1]);
slot = compiler_realize_slot(c, slot);
/* Free up some slots */
compiler_drop_slot(c, scope, callee);
compiler_drop_slot(c, scope, slot);
compiler_tracker_free(c, scope, &tracker);
/* Write first arguments */
gst_buffer_push_u16(c->vm, buffer, GST_OP_PSK);
gst_buffer_push_u16(c->vm, buffer, tracker.count);
/* Write the location of all of the arguments */
compiler_tracker_write(c, &tracker, 0);
/* Write last arguments */
gst_buffer_push_u16(c->vm, buffer, GST_OP_PAR);
gst_buffer_push_u16(c->vm, buffer, slot.index);
}
/* If this is in tail position do a tail call. */
if (opts.isTail) {
gst_buffer_push_u16(c->vm, buffer, GST_OP_TCL);
gst_buffer_push_u16(c->vm, buffer, callee.index);
ret.hasReturned = 1;
ret.isNil = 1;
} else {
ret = compiler_get_target(c, opts);
gst_buffer_push_u16(c->vm, buffer, GST_OP_CAL);
gst_buffer_push_u16(c->vm, buffer, callee.index);
gst_buffer_push_u16(c->vm, buffer, ret.index);
}
return ret;
}
}
/* Define a function type for Special Form helpers */
typedef Slot (*SpecialFormHelper) (GstCompiler *c, FormOptions opts, const GstValue *form);
@ -785,6 +838,16 @@ static SpecialFormHelper get_special(const GstValue *form) {
}
/* Multi character specials. Mostly control flow. */
switch (name[0]) {
case 'a':
{
if (gst_string_length(name) == 5 &&
name[1] == 'p' &&
name[2] == 'p' &&
name[3] == 'l' &&
name[4] == 'y') {
return compile_apply;
}
}
case 'd':
{
if (gst_string_length(name) == 2 &&

View File

@ -317,6 +317,7 @@ int gst_continue(Gst *vm) {
gst_assert(vm, v1.data.thread->status != GST_THREAD_DEAD, "cannot rejoin dead thread");
gst_frame_pc(stack) = pc + 3;
vm->thread = v1.data.thread;
vm->thread->status = GST_THREAD_ALIVE;
stack = vm->thread->data + vm->thread->count;
pc = gst_frame_pc(stack);
continue;