Commit 913fe8d0 authored by Niels Möller's avatar Niels Möller
Browse files

* src/command.c, src/command.h: Added collect_info_N and

collect_state_N (n=1, 2, 3, 4) to handle builtin functions that
need to collect some arguments before actually doing anything.

Rev: src/command.c:1.11
Rev: src/command.h:1.12
parent d1745144
......@@ -28,6 +28,8 @@
#include "werror.h"
#include "xalloc.h"
#include <assert.h>
#define GABA_DEFINE
#include "command.h.x"
#undef GABA_DEFINE
......@@ -75,158 +77,129 @@ int do_call_simple_command(struct command *s,
return COMMAND_RETURN(c, COMMAND_SIMPLE(self, arg));
}
/* Commands that need to collect some arguments before actually doing
* anything. */
/* GABA:
(class
(name collect_info_4)
(vars
(f pointer function "struct lsh_object *"
"struct lsh_object *" "struct lsh_object *"
"struct lsh_object *" "struct lsh_object *")
))
*/
/* Unimplemented command */
static int
do_command_unimplemented(struct command *s UNUSED,
struct lsh_object *o UNUSED,
struct command_continuation *c UNUSED)
{ fatal("command.c: Unimplemented command.\n"); }
/* GABA:
(class
(name collect_info_3)
(vars
(f method "struct lsh_object *"
"struct lsh_object *" "struct lsh_object *"
"struct lsh_object *")
(next object collect_info_3)))
*/
static struct lsh_object *
do_command_simple_unimplemented(struct command_simple *s UNUSED,
struct lsh_object *o UNUSED)
{ fatal("command.c: Unimplemented simple command.\n"); }
/* GABA:
(class
(name collect_info_3)
(vars
(f method "struct lsh_object *"
"struct lsh_object *" "struct lsh_object *")
(next object collect_info_2)))
*/
/* GABA:
(class
(name command_collect)
(inherit command_simple)
(vars
;; Is called with the argument count (for sanity checks)
;; followed by the arguments.
(f pointer function "struct lsh_object *" void)
;; The number of additional arguments to collect before calling f.
(left . unsigned)))
*/
struct command_simple command_unimplemented =
{ { STATIC_HEADER, do_command_unimplemented}, do_command_simple_unimplemented};
static struct lsh_object *
do_collect_1(struct command_simple *s, struct lsh_object *a)
{
CAST(collect_info_1, self, s);
return self->f(self, a);
}
/* GABA:
(class
(name command_simple_1)
(inherit command_collect)
(name collect_state_1)
(super command_simple)
(vars
(info object collect_info_2)
(a object lsh_object)))
*/
/* GABA:
(class
(name command_simple_2)
(inherit command_simple_0)
(name collect_state_2)
(super command_simple)
(vars
(info object collect_info_3)
(a object lsh_object)
(b object lsh_object)))
*/
/* GABA:
(class
(name command_collect_3)
(inherit command_collect_2)
(name collect_state_3)
(super command_simple)
(vars
(info object collect_info_4)
(a object lsh_object)
(b object lsh_object)
(c object lsh_object)))
*/
static void init_command_collect(struct command_collect *self,
unsigned left,
void * f))(unsigned n, ...))
static struct lsh_object *
do_collect_2(struct command_simple *s,
struct lsh_object *x)
{
self->f = f;
self->left = left;
self->super.super.call = do_call_simple_command;
CAST(collect_state_1, self, s);
return self->info->f(self->info, self->a, x);
}
static struct lsh_object *
do_command_collect_3(struct command_simple *s,
struct lsh_object *x)
struct lsh_object *
make_collect_state_1(struct collect_info_1 *info,
struct lsh_object *a)
{
CAST(command_collect_3, self, s);
unsigned left = self->left - 1;
NEW(collect_state_1, self);
self->info = info->next;
self->a = a;
self->super.call_simple = do_collect_2;
self->super.super.call = do_call_simple_command;
if (!left)
return self->f(3, self->super.a, self->b, x);
else
fatal("command.c: comand_collect_4 not implemented\n");
return &self->super.super.super;
}
static struct lsh_object *
do_command_collect_2(struct command_simple *s,
struct lsh_object *x)
do_collect_3(struct command_simple *s,
struct lsh_object *x)
{
CAST(command_collect_2, self, s);
unsigned left = self->left - 1;
if (!left)
return self->f(3, self->super.a, self->b, x);
else
{
NEW(command_collect_3, new);
init_command_simple(&new->super.super.super, self->f, self->left - 1);
new->super.a = self->a;
new->b = b;
new->super.super.super.call_simple = do_command_collect_3;
return (struct lsh_object *) new;
}
CAST(collect_state_2, self, s);
return self->info->f(self->info, self->a, self->b, x);
}
struct lsh_object *do_command_collect_1(struct command_simple *s,
struct lsh_object *x)
struct lsh_object *
make_collect_state_2(struct collect_info_2 *info,
struct lsh_object *a,
struct lsh_object *b)
{
CAST(command_collect_1, self, s);
unsigned left = self->left - 1;
NEW(collect_state_2, self);
self->info = info->next;
self->a = a;
self->b = b;
if (!left)
return self->f(2, self->a, x);
else
{
NEW(command_collect_2, new);
init_command_simple(&new->super.super, self->f, left);
new->super.a = self->a;
new->b = x;
new->super.super.call_simple = do_command_collect_2;
return (struct lsh_object *) new;
}
self->super.call_simple = do_collect_3;
self->super.super.call = do_call_simple_command;
return &self->super.super.super;
}
struct lsh_object *do_command_collect(struct command_simple *s,
struct lsh_object *x)
static struct lsh_object *
do_collect_4(struct command_simple *s,
struct lsh_object *x)
{
CAST(command_collect, self, s);
unsigned left = self->left - 1;
if (!left)
return self->f(1, x);
else
{
NEW(command_collect_1, new);
init_command_collect(&new->super, self->f, left);
f->a = x;
new->super.call_simple = do_command_collect_1;
CAST(collect_state_3, self, s);
return self->info->f(self->info, self->a, self->b, self->c, x);
}
return (struct lsh_object *) new;
}
struct lsh_object *
make_collect_state_3(struct collect_info_3 *info,
struct lsh_object *a,
struct lsh_object *b,
struct lsh_object *c)
{
NEW(collect_state_3, self);
self->info = info->next;
self->a = a;
self->b = b;
self->c = c;
self->super.call_simple = do_collect_4;
self->super.super.call = do_call_simple_command;
return &self->super.super.super;
}
/* Combinators */
......@@ -243,7 +216,44 @@ do_simple_command_I(struct command_simple *ignored UNUSED,
struct command_simple command_I =
STATIC_COMMAND_SIMPLE(do_simple_command_I);
static
/* ((K x) y) == x */
/* Represents (K x) */
/* GABA:
(class
(name command_K_1)
(super command_simple)
(vars
(x object lsh_object)))
*/
static struct lsh_object *
do_simple_command_K_1(struct command_simple *s,
struct lsh_object *ignored UNUSED)
{
CAST(command_K_1, self, s);
return self->x;
}
struct command *make_command_K_1(struct lsh_object *x)
{
NEW(command_K_1, res);
res->x = x;
res->super.super.call = do_call_simple_command;
res->super.call_simple = do_simple_command_K_1;
return &res->super.super;
}
static struct lsh_object *
do_simple_command_K(struct command_simple *ignored UNUSED,
struct lsh_object *a)
{
return &make_command_K_1(a)->super;
}
struct command_simple command_K = STATIC_COMMAND_SIMPLE(do_simple_command_K);
/* ((S f) g)x == (f x)(g x) */
/* Continuation called after evaluating (f x) */
......@@ -312,6 +322,24 @@ struct command *make_command_S_2(struct command *f,
return &res->super.super;
}
static struct lsh_object *collect_S_2(struct collect_info_2 *info,
struct lsh_object *f,
struct lsh_object *g)
{
CAST_SUBTYPE(command, cf, f);
CAST_SUBTYPE(command, cg, g);
assert(!info);
return &make_command_S_2(cf, cg)->super;
}
struct collect_info_2 collect_info_S_2 =
STATIC_COLLECT_2_FINAL(collect_S_2);
struct collect_info_1 command_S =
STATIC_COLLECT_1(&collect_info_S_2);
#if 0
/* Represents (S f) */
/* GABA:
(class
......@@ -356,52 +384,8 @@ struct lsh_object *gaba_apply_S_1(struct lsh_object *f)
CAST_SUBTYPE(command, cf, f);
return &make_command_S_1(cf)->super;
}
struct lsh_object *gaba_apply_S_2(struct lsh_object *f,
struct lsh_object *g)
{
CAST_SUBTYPE(command, cf, f);
CAST_SUBTYPE(command, cg, g);
return &make_command_S_2(cf, cg)->super;
}
/* ((K x) y) == x */
/* Represents (K x) */
/* GABA:
(class
(name command_K_1)
(super command_simple)
(vars
(x object lsh_object)))
*/
static struct lsh_object *
do_simple_command_K_1(struct command_simple *s,
struct lsh_object *ignored UNUSED)
{
CAST(command_K_1, self, s);
return self->x;
}
struct command *make_command_K_1(struct lsh_object *x)
{
NEW(command_K_1, res);
res->x = x;
res->super.super.call = do_call_simple_command;
res->super.call_simple = do_simple_command_K_1;
return &res->super.super;
}
static struct lsh_object *
do_simple_command_K(struct command_simple *ignored UNUSED,
struct lsh_object *a)
{
return &make_command_K_1(a)->super;
}
struct command_simple command_K = STATIC_COMMAND_SIMPLE(do_simple_command_K);
#endif
#if 0
/* ((B f) g) x == (f (g x)) */
......@@ -484,20 +468,6 @@ do_simple_command_B(struct command_simple *ignored UNUSED,
struct command_simple command_B = STATIC_COMMAND_SIMPLE(do_simple_command_B);
/* Unimplemented command */
static int
do_command_unimplemented(struct command *s UNUSED,
struct lsh_object *o UNUSED,
struct command_continuation *c UNUSED)
{ fatal("command.c: Unimplemented command.\n"); }
static struct lsh_object *
do_command_simple_unimplemented(struct command_simple *s UNUSED,
struct lsh_object *o UNUSED)
{ fatal("command.c: Unimplemented simple command.\n"); }
struct command_simple command_unimplemented =
{ { STATIC_HEADER, do_command_unimplemented}, do_command_simple_unimplemented};
/* Returned by listen */
/* GABA:
......@@ -584,7 +554,7 @@ struct command *make_listen_command(struct io_backend *backend,
return &self->super;
}
#endif
#if 0
/* xxCLASS:
(class
......
......@@ -74,6 +74,28 @@ int do_call_simple_command(struct command *s,
#define STATIC_COMMAND_SIMPLE(f) \
{ { STATIC_HEADER, do_call_simple_command }, f}
#define STATIC_COLLECT_1(next) \
{ { { STATIC_HEADER, do_call_simple_command }, do_collect_1}, \
make_collect_state_1, next }
#if 0
#define STATIC_COLLECT_1_FINAL(f) \
{ { { STATIC_HEADER, do_call_simple_command }, do_collect_1}, \
f, NULL }
#endif
#define STATIC_COLLECT_2(next) \
{ STATIC_HEADER, make_collect_state_2, next }
#define STATIC_COLLECT_2_FINAL(f) \
{ STATIC_HEADER, f, NULL }
#define STATIC_COLLECT_3(next) \
{ STATIC_HEADER, make_collect_state_3, next }
#define STATIC_COLLECT_3_FINAL(f) \
{ STATIC_HEADER, f, NULL }
/* GABA:
(class
(name command_frame)
......@@ -82,25 +104,81 @@ int do_call_simple_command(struct command *s,
(up object command_continuation)))
*/
/* Commands that need to collect some arguments before actually doing
* anything. */
/* The collect_info_n classes keeps track about what to do whith the
* next argument. As long as we collect arguments without doing
* anything, the f field in collect_info_n will point to the
* constructor make_collect_state_n. */
/* GABA:
(class
(name collect_info_4)
(vars
(f method "struct lsh_object *"
"struct lsh_object *" "struct lsh_object *"
"struct lsh_object *" "struct lsh_object *")
;; No next field
))
*/
/* GABA:
(class
(name collect_info_3)
(vars
(f method "struct lsh_object *"
"struct lsh_object *" "struct lsh_object *"
"struct lsh_object *")
(next object collect_info_4)))
*/
/* GABA:
(class
(name collect_info_2)
(vars
(f method "struct lsh_object *"
"struct lsh_object *" "struct lsh_object *")
(next object collect_info_3)))
*/
/* GABA:
(class
(name collect_info_1)
(super command_simple)
(vars
(f method "struct lsh_object *"
"struct lsh_object *")
(next object collect_info_2)))
*/
struct lsh_object *
make_collect_state_1(struct collect_info_1 *info,
struct lsh_object *a);
struct lsh_object *
make_collect_state_2(struct collect_info_2 *info,
struct lsh_object *a,
struct lsh_object *b);
struct lsh_object *
make_collect_state_3(struct collect_info_3 *info,
struct lsh_object *a,
struct lsh_object *b,
struct lsh_object *c);
extern struct command_simple command_unimplemented;
#define COMMAND_UNIMPLEMENTED (&command_unimplemented.super.super)
struct command_continuation *
make_apply(struct command *f, struct command_continuation *c);
struct lsh_object *gaba_apply(struct lsh_object *f,
struct lsh_object *x);
/* The macros are used by automatically generated evaluation code */
extern struct command_simple command_S;
struct command *make_command_S_2(struct command *f,
struct command *g);
struct command *make_command_S_1(struct command *f);
struct lsh_object *gaba_apply_S_1(struct lsh_object *f);
struct lsh_object *gaba_apply_S_2(struct lsh_object *f,
struct lsh_object *g);
#define GABA_APPLY gaba_apply
#define GABA_VALUE_S (&command_S.super.super)
#define GABA_APPLY_S_1 gaba_apply_S_1
#define GABA_APPLY_S_2 gaba_apply_S_2
extern struct command_simple command_I;
#define GABA_VALUE_I (&command_I.super.super)
#define GABA_APPLY_I_1(x) (x)
extern struct command_simple command_K;
struct command *make_command_K_1(struct lsh_object *x);
......@@ -108,20 +186,22 @@ struct command *make_command_K_1(struct lsh_object *x);
#define GABA_VALUE_K (&command_K.super.super)
#define GABA_APPLY_K_1(x) ((struct lsh_object *) make_command_K_1(x))
#define GABA_APPLY gaba_apply
/* The macros are used by automatically generated evaluation code */
extern struct collect_info_1 command_S;
struct command *make_command_S_2(struct command *f,
struct command *g);
extern struct command_simple command_I;
#define GABA_VALUE_I (&command_I.super.super)
#define GABA_APPLY_I_1(x) (x)
#define GABA_VALUE_S (&command_S.super.super)
#define GABA_APPLY_S_1(f) (make_collect_state_1(&collect_info_S_2, (f)))
#define GABA_APPLY_S_2(f, g) (make_collect_S_2(NULL, (f), (g)))
#if 0
extern struct command_simple command_B;
extern struct command_simple command_unimplemented;
#define COMMAND_UNIMPLEMENTED (&command_unimplemented.super.super)
struct command *make_listen_command(struct io_backend *backend,
struct lsh_string *interface,
UINT32 port);
#endif
#if 0
/* (lambda (x) (f (g x))) */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment