mirror of
https://github.com/janet-lang/janet
synced 2025-10-14 07:17:40 +00:00
Add apply special form. TODO -
make into function.
This commit is contained in:
@@ -762,6 +762,59 @@ static Slot compile_var(GstCompiler *c, FormOptions opts, const GstValue *form)
|
|||||||
return compile_assign(c, opts, form[1], form[2]);
|
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 */
|
/* Define a function type for Special Form helpers */
|
||||||
typedef Slot (*SpecialFormHelper) (GstCompiler *c, FormOptions opts, const GstValue *form);
|
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. */
|
/* Multi character specials. Mostly control flow. */
|
||||||
switch (name[0]) {
|
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':
|
case 'd':
|
||||||
{
|
{
|
||||||
if (gst_string_length(name) == 2 &&
|
if (gst_string_length(name) == 2 &&
|
||||||
|
@@ -317,6 +317,7 @@ int gst_continue(Gst *vm) {
|
|||||||
gst_assert(vm, v1.data.thread->status != GST_THREAD_DEAD, "cannot rejoin dead thread");
|
gst_assert(vm, v1.data.thread->status != GST_THREAD_DEAD, "cannot rejoin dead thread");
|
||||||
gst_frame_pc(stack) = pc + 3;
|
gst_frame_pc(stack) = pc + 3;
|
||||||
vm->thread = v1.data.thread;
|
vm->thread = v1.data.thread;
|
||||||
|
vm->thread->status = GST_THREAD_ALIVE;
|
||||||
stack = vm->thread->data + vm->thread->count;
|
stack = vm->thread->data + vm->thread->count;
|
||||||
pc = gst_frame_pc(stack);
|
pc = gst_frame_pc(stack);
|
||||||
continue;
|
continue;
|
||||||
|
Reference in New Issue
Block a user