L
luserXtrog
Me again. Back in black. This is a little experiment in
using stdarg to simulate functions that both receive and
return variable numbers of variables (determined by the
opcode). It seems to be working but strikes me as sufficiently
bizarre that I'd greatly appreciate even one other set of
eyes to glance over it.
It is halfway sensible and confusing due to the nature of the
problem? Or is it totally wacko-jacko?
575(1)09:40 PM:xpost 0> echo '//@@@@snip here@@@@'|cat oper.c -
object.h
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "object.h"
Object *Iadd(Object oa[]) {
oa[0].u.i += oa[1].u.i;
return oa;
}
Object *moveto(Object oa[]) {
printf("%d %d moveto\n", oa[0].u.i, oa[1].u.i);
return oa;
}
Object *stroke(Object oa[]) {
printf("stroke\n");
return oa;
}
#define OPERATORS \
X(Iadd, 2,1) \
X(moveto,2,0) \
X(stroke,0,0) \
#define X(op,in,out) OP_ ## op,
enum e_opnames { OPERATORS };
#undef X
struct s_operator {
Object * (*fp)(Object []);
int in, out;
} oplist[] =
#define X(op,in,out) { op, in, out },
{ OPERATORS };
#undef X
typedef struct s_operator Oper;
void opcall (int opcode, ...) {
Oper oper;
int n;
oper = oplist[opcode];
n = oper.out>oper.in? oper.out: oper.in;
{
va_list ap;
Object oa[n];
Object *op;
int i;
va_start(ap, opcode);
for (i=0; i<oper.in; i++)
oa = * va_arg(ap, Object *);
va_end(ap);
oper.fp(oa);
va_start(ap,opcode);
for (i=0; i<oper.out; i++) {
op = va_arg(ap, Object *);
*op = oa;
}
va_end(ap);
}
return ;
}
int main() {
Object x = { .type = integertype, .u.i = 72 };
Object y = { .type = integertype, .u.i = 72 };
opcall(OP_Iadd, &x, &y);
opcall(OP_moveto, &x, &y);
opcall(OP_stroke);
return 0;
}
//eof
//@@@@snip here@@@@
#define LIT 1<<7
//composite attributes
#define READ 1
#define WRITE 2
#define EXEC 4
#define Types \
X( mark, int m) \
X( null, int u) \
X( integer, int i) \
X( real, double r) \
X( boolean, unsigned char b) \
X( array, size_t a) \
X(packedarray, size_t pa) \
X( string, size_t s) \
X( name, size_t n) \
X( dict, size_t d) \
X( operator, int o) \
X( file, int * f) \
X( save, Save * v) \
X( font, int * t)
#define X(a,b) a ## type,
enum e_types{ Types };
#undef X
typedef struct s_array Array;
struct s_array {
unsigned char attr;
size_t a;
size_t n;
};
typedef struct s_string String;
struct s_string {
unsigned char attr;
size_t s;
size_t n;
};
typedef struct s_dict Dict;
struct s_dict {
unsigned char attr;
size_t d;
size_t n;
};
typedef struct s_save Save;
struct s_save {
unsigned char *vm;
unsigned int level;
size_t sz;
size_t pointer;
};
#define X(a,b) b;
typedef struct s_object Object;
struct s_object {
unsigned char type;
union { Types } u;
};
#undef X
Object integer (int i);
Object real (double r);
Object boolean (unsigned char b);
Object name (Object s);
extern Object mark;
extern Object null;
576(1)09:54 PM:xpost 0> !gc
gcc -g -o oper oper.c
577(1)09:55 PM:xpost 0> gcc -Wall -o oper oper.c
578(1)09:55 PM:xpost 0> oper
144 72 moveto
stroke
579(1)09:55 PM:xpost 0>
tia
Semolina Sensemilla
using stdarg to simulate functions that both receive and
return variable numbers of variables (determined by the
opcode). It seems to be working but strikes me as sufficiently
bizarre that I'd greatly appreciate even one other set of
eyes to glance over it.
It is halfway sensible and confusing due to the nature of the
problem? Or is it totally wacko-jacko?
575(1)09:40 PM:xpost 0> echo '//@@@@snip here@@@@'|cat oper.c -
object.h
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "object.h"
Object *Iadd(Object oa[]) {
oa[0].u.i += oa[1].u.i;
return oa;
}
Object *moveto(Object oa[]) {
printf("%d %d moveto\n", oa[0].u.i, oa[1].u.i);
return oa;
}
Object *stroke(Object oa[]) {
printf("stroke\n");
return oa;
}
#define OPERATORS \
X(Iadd, 2,1) \
X(moveto,2,0) \
X(stroke,0,0) \
#define X(op,in,out) OP_ ## op,
enum e_opnames { OPERATORS };
#undef X
struct s_operator {
Object * (*fp)(Object []);
int in, out;
} oplist[] =
#define X(op,in,out) { op, in, out },
{ OPERATORS };
#undef X
typedef struct s_operator Oper;
void opcall (int opcode, ...) {
Oper oper;
int n;
oper = oplist[opcode];
n = oper.out>oper.in? oper.out: oper.in;
{
va_list ap;
Object oa[n];
Object *op;
int i;
va_start(ap, opcode);
for (i=0; i<oper.in; i++)
oa = * va_arg(ap, Object *);
va_end(ap);
oper.fp(oa);
va_start(ap,opcode);
for (i=0; i<oper.out; i++) {
op = va_arg(ap, Object *);
*op = oa;
}
va_end(ap);
}
return ;
}
int main() {
Object x = { .type = integertype, .u.i = 72 };
Object y = { .type = integertype, .u.i = 72 };
opcall(OP_Iadd, &x, &y);
opcall(OP_moveto, &x, &y);
opcall(OP_stroke);
return 0;
}
//eof
//@@@@snip here@@@@
#define LIT 1<<7
//composite attributes
#define READ 1
#define WRITE 2
#define EXEC 4
#define Types \
X( mark, int m) \
X( null, int u) \
X( integer, int i) \
X( real, double r) \
X( boolean, unsigned char b) \
X( array, size_t a) \
X(packedarray, size_t pa) \
X( string, size_t s) \
X( name, size_t n) \
X( dict, size_t d) \
X( operator, int o) \
X( file, int * f) \
X( save, Save * v) \
X( font, int * t)
#define X(a,b) a ## type,
enum e_types{ Types };
#undef X
typedef struct s_array Array;
struct s_array {
unsigned char attr;
size_t a;
size_t n;
};
typedef struct s_string String;
struct s_string {
unsigned char attr;
size_t s;
size_t n;
};
typedef struct s_dict Dict;
struct s_dict {
unsigned char attr;
size_t d;
size_t n;
};
typedef struct s_save Save;
struct s_save {
unsigned char *vm;
unsigned int level;
size_t sz;
size_t pointer;
};
#define X(a,b) b;
typedef struct s_object Object;
struct s_object {
unsigned char type;
union { Types } u;
};
#undef X
Object integer (int i);
Object real (double r);
Object boolean (unsigned char b);
Object name (Object s);
extern Object mark;
extern Object null;
576(1)09:54 PM:xpost 0> !gc
gcc -g -o oper oper.c
577(1)09:55 PM:xpost 0> gcc -Wall -o oper oper.c
578(1)09:55 PM:xpost 0> oper
144 72 moveto
stroke
579(1)09:55 PM:xpost 0>
tia
Semolina Sensemilla