ref: 24f48308ce95e5d582c8b0ae23485140f62d233e
parent: 9650392e04a54e2e8fdf0e41f03b3bbd668f0239
author: Tor Andersson <[email protected]>
date: Sat Jan 18 12:38:40 EST 2014
Support 'typeof' operator.
--- a/jscompile.h
+++ b/jscompile.h
@@ -44,7 +44,6 @@
OP_CALL, /* <closure> <this> <args...> -(numargs)- <returnvalue> */
OP_NEW, /* <closure> <args...> -(numargs)- <returnvalue> */
- OP_VOID,
OP_TYPEOF,
OP_POS,
OP_NEG,
--- a/jsgc.c
+++ b/jsgc.c
@@ -1,7 +1,7 @@
#include "js.h"
#include "jscompile.h"
-#include "jsrun.h"
#include "jsobject.h"
+#include "jsrun.h"
#include "jsstate.h"
static void jsG_markobject(js_State *J, int mark, js_Object *obj);
--- a/jsobject.c
+++ b/jsobject.c
@@ -1,7 +1,7 @@
#include "js.h"
#include "jscompile.h"
-#include "jsrun.h"
#include "jsobject.h"
+#include "jsrun.h"
#include "jsstate.h"
static js_Object *jsR_newfunction(js_State *J, js_Function *function, js_Environment *scope)
--- a/jsrun.c
+++ b/jsrun.c
@@ -119,6 +119,19 @@
int js_isprimitive(js_State *J, int idx) { return stackidx(J, idx)->type != JS_TOBJECT; }
int js_isobject(js_State *J, int idx) { return stackidx(J, idx)->type == JS_TOBJECT; }
+const char *js_typeof(js_State *J, int idx)
+{
+ switch (stackidx(J, idx)->type) {
+ case JS_TUNDEFINED: return "undefined";
+ case JS_TNULL: return "object";
+ case JS_TBOOLEAN: return "boolean";
+ case JS_TNUMBER: return "number";
+ case JS_TSTRING: return "string";
+ case JS_TOBJECT: return "object";
+ }
+ return "object";
+}
+
js_Value js_tovalue(js_State *J, int idx)
{
return *stackidx(J, idx);
@@ -587,6 +600,12 @@
/* Unary expressions */
+ case OP_TYPEOF:
+ str = js_typeof(J, -1);
+ js_pop(J, 1);
+ js_pushliteral(J, str);
+ break;
+
case OP_POS:
x = js_tonumber(J, -1);
js_pop(J, 1);
@@ -614,25 +633,7 @@
/* Binary expressions */
case OP_ADD:
- {
- js_Value va = js_toprimitive(J, -2, JS_HNONE);
- js_Value vb = js_toprimitive(J, -1, JS_HNONE);
- if (va.type == JS_TSTRING || vb.type == JS_TSTRING) {
- const char *sa = jsR_tostring(J, &va);
- const char *sb = jsR_tostring(J, &vb);
- char *sab = malloc(strlen(sa) + strlen(sb) + 1);
- strcpy(sab, sa);
- strcat(sab, sb);
- js_pop(J, 2);
- js_pushstring(J, sab);
- free(sab);
- } else {
- x = jsR_tonumber(J, &va);
- y = jsR_tonumber(J, &vb);
- js_pop(J, 2);
- js_pushnumber(J, x + y);
- }
- }
+ jsR_concat(J);
break;
case OP_SUB:
@@ -795,6 +796,9 @@
if (!P) return 1;
jsP_optimize(J, P);
F = jsC_compile(J, P);
+
+ jsP_dumpsyntax(J, P);
+
jsP_freeparse(J);
if (!F) return 1;
--- a/jsrun.h
+++ b/jsrun.h
@@ -16,6 +16,8 @@
int jsR_loadscript(js_State *J, const char *filename, const char *source);
void jsR_error(js_State *J, const char *fmt, ...);
void js_pushobject(js_State *J, js_Object *v);
+js_Object *js_toobject(js_State *J, int idx);
+js_Value js_toprimitive(js_State *J, int idx, int hint);
/* public */
@@ -43,6 +45,7 @@
void js_newcfunction(js_State *J, js_CFunction fun);
void js_newcconstructor(js_State *J, js_CFunction fun, js_CFunction con);
+const char *js_typeof(js_State *J, int idx);
int js_isundefined(js_State *J, int idx);
int js_isnull(js_State *J, int idx);
int js_isboolean(js_State *J, int idx);
--- a/jsvalue.c
+++ b/jsvalue.c
@@ -1,5 +1,6 @@
#include "js.h"
#include "jsobject.h"
+#include "jsrun.h"
js_Value jsR_toprimitive(js_State *J, const js_Value *v, int preferred)
{
@@ -98,4 +99,30 @@
case JS_TOBJECT: return v->u.object;
}
jsR_error(J, "TypeError (ToObject)");
+}
+
+void jsR_concat(js_State *J)
+{
+ js_Value va = js_toprimitive(J, -2, JS_HNONE);
+ js_Value vb = js_toprimitive(J, -1, JS_HNONE);
+ if (va.type == JS_TSTRING || vb.type == JS_TSTRING) {
+ const char *sa = jsR_tostring(J, &va);
+ const char *sb = jsR_tostring(J, &vb);
+ char *sab = malloc(strlen(sa) + strlen(sb) + 1);
+ strcpy(sab, sa);
+ strcat(sab, sb);
+ js_pop(J, 2);
+ js_pushstring(J, sab);
+ free(sab);
+ } else {
+ double x = jsR_tonumber(J, &va);
+ double y = jsR_tonumber(J, &vb);
+ js_pop(J, 2);
+ js_pushnumber(J, x + y);
+ }
+}
+
+int jsR_compare(js_State *J)
+{
+ return 0;
}