Functions!

This commit is contained in:
Tor Andersson
2014-01-16 00:10:57 +01:00
parent ede0f888ce
commit 4a3fdcef74
4 changed files with 61 additions and 17 deletions

View File

@@ -11,7 +11,7 @@ static void cfunbody(JF, js_Ast *name, js_Ast *params, js_Ast *body);
static void cexp(JF, js_Ast *exp);
static void cstmlist(JF, js_Ast *list);
static int listlen(js_Ast *list)
static int paramlen(js_Ast *list)
{
int n = 0;
while (list) {
@@ -21,13 +21,23 @@ static int listlen(js_Ast *list)
return n;
}
static void makeparams(JF, js_Ast *list, const char **params)
{
while (list) {
*params++ = list->a->string;
list = list->b;
}
}
static js_Function *newfun(js_State *J, js_Ast *name, js_Ast *params, js_Ast *body)
{
js_Function *F = malloc(sizeof *F);
memset(F, 0, sizeof *F);
F->name = name ? name->string : "<anonymous>";
F->numparams = listlen(params);
F->numparams = paramlen(params);
F->params = malloc(F->numparams * sizeof *F->params);
makeparams(J, F, params, F->params);
F->codecap = 256;
F->codelen = 0;

View File

@@ -90,6 +90,7 @@ struct js_Function
{
const char *name;
int numparams;
const char **params;
short *code;
int codecap, codelen;

View File

@@ -595,7 +595,10 @@ void jsC_dumpfunction(js_State *J, js_Function *F)
short *end = F->code + F->codelen;
int i;
printf("function %p %s(%d)\n", F, F->name, F->numparams);
printf("function %p %s(", F, F->name);
for (i = 0; i < F->numparams; i++)
printf("%s%s", i > 0 ? ", " : "", F->params[i]);
printf(")\n");
for (i = 0; i < F->funlen; i++)
printf("\tfunction %p %s\n", F->funtab[i], F->funtab[i]->name);
for (i = 0; i < F->strlen; i++) {

58
jsrun.c
View File

@@ -8,7 +8,17 @@ static js_Value stack[256];
static int top = 0;
static int bot = 0;
static void js_call(js_State *J, js_Object *obj, int argc);
static void js_call(js_State *J, int argc);
static void js_dumpstack(js_State *J)
{
int i;
for (i = 0; i < top; i++) {
printf("stack %d: ", i);
js_dumpvalue(J, stack[i]);
putchar('\n');
}
}
static inline double tointeger(double n)
{
@@ -235,6 +245,7 @@ void js_dup1rot4(js_State *J)
void js_trap(js_State *J)
{
js_dumpstack(J);
}
static void runfun(js_State *J, js_Function *F, js_Environment *E)
@@ -250,7 +261,7 @@ static void runfun(js_State *J, js_Function *F, js_Environment *E)
js_Object *obj;
js_Property *ref;
double x, y;
int b, argc;
int b;
while (1) {
opcode = *pc++;
@@ -353,6 +364,10 @@ static void runfun(js_State *J, js_Function *F, js_Environment *E)
}
break;
case OP_CALL:
js_call(J, *pc++);
break;
/* Unary expressions */
case OP_POS:
@@ -533,9 +548,34 @@ static void runfun(js_State *J, js_Function *F, js_Environment *E)
}
}
void jsR_error(js_State *J, const char *message)
static void js_call(js_State *J, int argc)
{
fprintf(stderr, "runtime error: %s\n", message);
js_Environment *E;
js_Property *ref;
js_Function *F;
js_Object *obj;
int i;
int savebot = bot;
bot = top - argc;
obj = js_toobject(J, -argc - 1);
F = obj->function;
E = js_newenvironment(J, obj->scope, js_newobject(J, JS_COBJECT));
for (i = 0; i < F->numparams; i++) {
ref = js_decvar(J, E, F->params[i]);
if (i + 1 < argc)
ref->value = js_tovalue(J, i + 1);
}
js_pop(J, argc + 1);
runfun(J, F, E);
bot = savebot;
}
void jsR_error(js_State *J, const char *fmt, ...)
{
va_list ap;
@@ -549,16 +589,6 @@ void jsR_error(js_State *J, const char *fmt, ...)
longjmp(J->jb, 1);
}
static void js_dumpstack(js_State *J)
{
int i;
for (i = 0; i < top; i++) {
printf("stack %d: ", i);
js_dumpvalue(J, stack[i]);
putchar('\n');
}
}
void jsR_runfunction(js_State *J, js_Function *F)
{
if (setjmp(J->jb)) {