ref: 4a3fdcef74fe15a1b36ef1185d9b825ab7fba26d
parent: ede0f888ced2b7334e23a6a6ccf21c149712c116
author: Tor Andersson <tor@ccxvii.net>
date: Wed Jan 15 19:10:57 EST 2014
Functions!
--- a/jscompile.c
+++ b/jscompile.c
@@ -11,7 +11,7 @@
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,6 +21,14 @@
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);
@@ -27,7 +35,9 @@
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;
--- a/jscompile.h
+++ b/jscompile.h
@@ -90,6 +90,7 @@
{
const char *name;
int numparams;
+ const char **params;
short *code;
int codecap, codelen;
--- a/jsdump.c
+++ b/jsdump.c
@@ -595,7 +595,10 @@
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++) {
--- a/jsrun.c
+++ b/jsrun.c
@@ -8,8 +8,18 @@
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)
{
double sign = n < 0 ? -1 : 1;
@@ -235,6 +245,7 @@
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 @@
js_Object *obj;
js_Property *ref;
double x, y;
- int b, argc;
+ int b;
while (1) {
opcode = *pc++;
@@ -353,6 +364,10 @@
}
break;
+ case OP_CALL:
+ js_call(J, *pc++);
+ break;
+
/* Unary expressions */
case OP_POS:
@@ -533,9 +548,34 @@
}
}
-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;
@@ -547,16 +587,6 @@
fprintf(stderr, "\n");
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)