Add callable CFunctions and a print() function.

This commit is contained in:
Tor Andersson
2014-01-16 02:14:07 +01:00
parent 18b192b8aa
commit 0f87d01184
3 changed files with 72 additions and 10 deletions
+27 -2
View File
@@ -11,7 +11,6 @@
typedef struct js_State js_State;
typedef int (*js_CFunction)(js_State *J, int argc);
#define JS_REGEXP_G 1
#define JS_REGEXP_I 2
@@ -25,12 +24,38 @@ int js_error(js_State *J, const char *fmt, ...);
int js_loadstring(js_State *J, const char *s);
int js_loadfile(js_State *J, const char *filename);
/* binding API */
typedef int (*js_CFunction)(js_State *J, int argc);
typedef struct js_Object js_Object;
void js_pushundefined(js_State *J);
void js_pushnull(js_State *J);
void js_pushboolean(js_State *J, int v);
void js_pushnumber(js_State *J, double v);
void js_pushlstring(js_State *J, const char *v);
void js_pushstring(js_State *J, const char *v);
void js_pushobject(js_State *J, js_Object *v);
int js_isundefined(js_State *J, int idx);
int js_isstring(js_State *J, int idx);
int js_toboolean(js_State *J, int idx);
double js_tonumber(js_State *J, int idx);
double js_tointeger(js_State *J, int idx);
const char *js_tostring(js_State *J, int idx);
js_Object *js_toobject(js_State *J, int idx);
void js_pop(js_State *J, int n);
void js_dup(js_State *J);
void js_setglobal(js_State *J, const char *name);
/* private */
typedef struct js_Ast js_Ast;
typedef struct js_Environment js_Environment;
typedef struct js_Function js_Function;
typedef struct js_Object js_Object;
typedef struct js_StringNode js_StringNode;
const char *js_intern(js_State *J, const char *s);
+28 -8
View File
@@ -567,20 +567,40 @@ static void js_call(js_State *J, int argc)
obj = js_toobject(J, -argc - 1);
F = obj->function;
E = js_newenvironment(J, obj->scope, js_newobject(J, JS_COBJECT));
if (F) {
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);
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);
} else {
js_CFunction CF = obj->cfunction;
i = CF(J, argc);
if (i) {
js_Value v = js_tovalue(J, -1);
js_pop(J, top - bot + 1);
js_pushvalue(J, v);
} else {
js_pop(J, top - bot + 1);
js_pushundefined(J);
}
}
js_pop(J, argc + 1);
runfun(J, F, E);
bot = savebot;
}
void js_setglobal(js_State *J, const char *name)
{
js_Property *ref = js_setproperty(J, J->E->variables, name);
ref->value = js_tovalue(J, -1);
js_pop(J, 1);
}
void jsR_error(js_State *J, const char *fmt, ...)
{
va_list ap;
+17
View File
@@ -2,12 +2,29 @@
#include "jsobject.h"
#include "jsstate.h"
static int jsB_print(js_State *J, int argc)
{
int i;
for (i = 1; i < argc; ++i) {
const char *s = js_tostring(J, i);
if (i > 1) putchar(' ');
fputs(s, stdout);
}
putchar('\n');
return 0;
}
js_State *js_newstate(void)
{
js_State *J = malloc(sizeof *J);
memset(J, 0, sizeof(*J));
J->global = js_newobject(J, JS_COBJECT);
J->E = js_newenvironment(J, NULL, J->global);
js_pushobject(J, js_newcfunction(J, jsB_print));
js_setglobal(J, "print");
return J;
}