mirror of
https://github.com/ccxvii/mujs.git
synced 2026-02-06 01:41:37 +08:00
Functions!
This commit is contained in:
14
jscompile.c
14
jscompile.c
@@ -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;
|
||||
|
||||
@@ -90,6 +90,7 @@ struct js_Function
|
||||
{
|
||||
const char *name;
|
||||
int numparams;
|
||||
const char **params;
|
||||
|
||||
short *code;
|
||||
int codecap, codelen;
|
||||
|
||||
5
jsdump.c
5
jsdump.c
@@ -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
58
jsrun.c
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user