ref: f3ea55fc6440ca9bf08e472f2d5e1f14ee0f4273
parent: 32c0c6c4103e8753ac8ad8ca581bec9c87362ca0
author: Tor Andersson <[email protected]>
date: Sun Jan 19 10:06:10 EST 2014
Implement String.prototype.charAt and charCodeAt.
--- a/jsbstring.c
+++ b/jsbstring.c
@@ -32,6 +32,54 @@
return 1;
}
+static inline const char *utfindex(const char *s, int i)
+{
+ Rune rune;
+ int c, n = 0;
+ for (n = 0; n < i; ++n) {
+ c = *(unsigned char*)s;
+ if (c < Runeself) {
+ if (c == 0)
+ return NULL;
+ ++s;
+ } else
+ s += chartorune(&rune, s);
+ }
+ return s;
+}
+
+static int Sp_charAt(js_State *J, int n)
+{
+ char buf[UTFmax + 1];
+ const char *s = js_tostring(J, 0);
+ int pos = js_tointeger(J, 1);
+ s = utfindex(s, pos);
+ if (s) {
+ Rune rune;
+ chartorune(&rune, s);
+ buf[runetochar(buf, &rune)] = 0;
+ js_pushstring(J, buf);
+ } else {
+ js_pushliteral(J, "");
+ }
+ return 1;
+}
+
+static int Sp_charCodeAt(js_State *J, int n)
+{
+ const char *s = js_tostring(J, 0);
+ int pos = js_tointeger(J, 1);
+ s = utfindex(s, pos);
+ if (s) {
+ Rune rune;
+ chartorune(&rune, s);
+ js_pushnumber(J, rune);
+ } else {
+ js_pushnumber(J, NAN);
+ }
+ return 1;
+}
+
static int S_fromCharCode(js_State *J, int n)
{
int i;
@@ -39,7 +87,7 @@
char *s = malloc(n * UTFmax + 1), *p = s;
// TODO: guard malloc with try/catch
for (i = 0; i < n; i++) {
- c = js_tonumber(J, i + 1); // TODO: ToUInt16()
+ c = js_tointeger(J, i + 1); // TODO: ToUInt16()
p += runetochar(p, &c);
}
*p = 0;
@@ -62,6 +110,8 @@
js_setproperty(J, -2, "constructor");
jsB_propf(J, "toString", Sp_toString, 0);
jsB_propf(J, "valueOf", Sp_valueOf, 0);
+ jsB_propf(J, "charAt", Sp_charAt, 1);
+ jsB_propf(J, "charCodeAt", Sp_charCodeAt, 1);
}
js_setproperty(J, -2, "prototype");
--- a/jsobject.c
+++ b/jsobject.c
@@ -3,6 +3,7 @@
#include "jsobject.h"
#include "jsrun.h"
#include "jsstate.h"
+#include "jsutf.h"
static js_Object *jsR_newfunction(js_State *J, js_Function *function, js_Environment *scope)
{
@@ -58,7 +59,7 @@
js_Property *ref;
ref = jsR_setproperty(J, obj, "length");
ref->value.type = JS_TNUMBER;
- ref->value.u.number = strlen(v);
+ ref->value.u.number = utflen(v);
ref->readonly = 1;
ref->dontenum = 1;
ref->dontconf = 1;
--- a/jsrun.c
+++ b/jsrun.c
@@ -801,8 +801,6 @@
jsP_optimize(J, P);
F = jsC_compile(J, P);
- jsP_dumpsyntax(J, P);
-
jsP_freeparse(J);
if (!F) return 1;