shithub: libmujs

Download patch

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;
 }