Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
185 lines (153 sloc) 3.43 KB
#include "compiler.h"
#include "demo.h"
#include "util.h"
#include "debug.h"
#include "object.h"
#include <stdlib.h>
static void solve_object_reference();
static void solve_object_reference_do(Data * d);
void compile()
{
objs = NEW(Link);
link_init(objs);
yyparse();
solve_object_reference();
#ifdef DEBUG
debug_print_objs();
printf("\n\n");
#endif
printf("// generated by demolino\n\n");
printf(
"#ifndef __DEMO__\n"
"#define __DEMO__\n"
"\n"
);
Object * o;
Data * d;
// find object `main'
if (!(o = object_get_by_name("main")))
yyerror("`main' object expected");
CHECK(o->type == OT_DEMO, "`main' must be typed of `demo'");
// process parameter `size'
d = object_get_param_data_by_name(o, "size");
int win_w = 640, win_h = 480;
if (d) { // `size' can be omitted
CHECK(d->type == DT_LIST, "invalid `size'");
CHECK(link_length(d->l) == 2, "invalid `size'");
d = (Data *)d->l->next;
CHECK(d->type == DT_NUM, "invalid `size'");
win_w = d->n;
d = d->next;
CHECK(d->type == DT_NUM, "invalid `size'");
win_h = d->n;
}
printf("int win_w = %d, win_h = %d;\n", win_w, win_h);
// compiler(declare) all the objects
{ TRAVERSE(objs, Object, o)
if (o->type != OT_DEMO)
object_decl(o);
}
// process parameter `timeline'
d = object_get_param_data_by_name(o, "timeline");
CHECK(d, "`timeline' expected");
printf(
"\nvoid render()\n"
"{\n"
"\tlong __t = get_ticks();\n"
);
compile_sequencer(d);
// process parameter `length'
d = object_get_param_data_by_name(o, "length");
CHECK(d, "`length' expected");
printf("\tif (__t > ");
compile_data(d);
printf(") exit(0);\n");
// end of `render'
printf("}\n\n");
// compiler(define) all the objects
{ TRAVERSE(objs, Object, o)
if (o->type != OT_DEMO)
object_def(o);
}
printf("\n#endif\n\n");
}
int yyerror(const char * err)
{
fprintf(stderr, "error: %s\n", err);
exit(1);
return 0;
}
static void solve_object_reference()
{
{ TRAVERSE(objs, Object, p)
{ TRAVERSE(p->param, Param, q)
solve_object_reference_do(q->data);
}
}
}
static void solve_object_reference_do(Data * d)
{
if (d->type == DT_OBJ) {
if (!(d->o.o = object_get_by_name(d->o.name)))
yyerror("undefined object");
}
else if (d->type == DT_LIST) {
TRAVERSE(d->l, Data, p)
solve_object_reference_do(p);
}
}
void compile_data(Data * d)
{
switch (d->type) {
case DT_NUM:
printf("%g", d->n);
break;
case DT_ANIM:
printf("lirp(__rt, ");
compile_data(d->a.ts);
printf(", ");
compile_data(d->a.te);
printf(", ");
compile_data(d->a.s);
printf(", ");
compile_data(d->a.e);
printf(")");
break;
default:
yyerror("invalid data type");
}
}
void compile_sequencer(Data * d)
{
CHECK(d->type == DT_LIST, "invalid sequencer: list expected");
CHECK(link_length(d->l) == 3, "invalid sequencer: 3 elements expected");
d = (Data *)d->l->next;
CHECK(d->type == DT_OBJ, "invalid sequencer: object expected");
Object * o = d->o.o;
d = d->next;
printf("\tif (__t >= ");
compile_data(d);
printf(" && __t <= ");
compile_data(d->next);
printf(") {\n"
"\t\tlong __rt = __t - ");
compile_data(d);
printf(";\n");
object_call(o);
printf("\t}\n");
}
void compile_vector(Data * d)
{
CHECK(d->type == DT_LIST,
"invalid vector: list expected");
CHECK(link_length(d->l) == 3,
"invalid vector: 3 elements expected");
d = (Data *)d->l->next;
compile_data(d);
printf(", ");
d = d->next;
compile_data(d);
printf(", ");
d = d->next;
compile_data(d);
}