mirror of
https://github.com/ccxvii/mujs.git
synced 2026-09-22 07:03:36 +08:00
Add callable CFunctions and a print() function.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user