JSON.parse()

This commit is contained in:
Tor Andersson
2014-02-10 12:42:12 +01:00
parent b8aa34d919
commit 39dd0a36ba
3 changed files with 132 additions and 1 deletions

37
jslex.c
View File

@@ -663,3 +663,40 @@ int jsY_lex(js_State *J)
{
return J->lasttoken = jsY_lexx(J);
}
int jsY_lexjson(js_State *J)
{
while (1) {
J->lexline = J->line; /* save location of beginning of token */
while (iswhite(PEEK) || PEEK == '\n')
NEXT();
if (PEEK >= '0' && PEEK <= '9') {
return lexnumber(J);
}
switch (PEEK) {
case ',': NEXT(); return ',';
case ':': NEXT(); return ':';
case '[': NEXT(); return '[';
case ']': NEXT(); return ']';
case '{': NEXT(); return '{';
case '}': NEXT(); return '}';
case '\'':
case '"':
return lexstring(J);
case '.':
return lexnumber(J);
case 0:
return 0; /* EOF */
}
if (PEEK >= 0x20 && PEEK <= 0x7E)
jsY_error(J, "unexpected character: '%c'", PEEK);
jsY_error(J, "unexpected character: \\u%04X", PEEK);
}
}

View File

@@ -71,5 +71,6 @@ int jsY_findword(const char *s, const char **list, int num);
void jsY_initlex(js_State *J, const char *filename, const char *source);
int jsY_lex(js_State *J);
int jsY_lexjson(js_State *J);
#endif

95
json.c
View File

@@ -1,10 +1,103 @@
#include "jsi.h"
#include "jslex.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
static inline void jsonnext(js_State *J)
{
J->lookahead = jsY_lexjson(J);
}
static inline int jsonaccept(js_State *J, int t)
{
if (J->lookahead == t) {
jsonnext(J);
return 1;
}
return 0;
}
static inline void jsonexpect(js_State *J, int t)
{
if (!jsonaccept(J, t))
js_syntaxerror(J, "JSON: unexpected token: %s (expected %s)",
jsY_tokenstring(J->lookahead), jsY_tokenstring(t));
}
static void jsonvalue(js_State *J)
{
int i;
const char *name;
switch (J->lookahead) {
case TK_STRING:
js_pushliteral(J, J->text);
jsonnext(J);
break;
case TK_NUMBER:
js_pushnumber(J, J->number);
jsonnext(J);
break;
case '{':
js_newobject(J);
jsonnext(J);
if (J->lookahead == '}')
return;
do {
if (J->lookahead != TK_STRING)
js_syntaxerror(J, "JSON: unexpected token: %s (expected string)", jsY_tokenstring(J->lookahead));
name = J->text;
jsonnext(J);
jsonexpect(J, ':');
jsonvalue(J);
js_setproperty(J, -2, name);
} while (jsonaccept(J, ','));
jsonexpect(J, '}');
break;
case '[':
js_newarray(J);
jsonnext(J);
i = 0;
if (J->lookahead == ']')
return;
do {
jsonvalue(J);
js_setindex(J, -2, i++);
} while (jsonaccept(J, ','));
jsonexpect(J, ']');
break;
case TK_TRUE:
js_pushboolean(J, 1);
jsonnext(J);
break;
case TK_FALSE:
js_pushboolean(J, 0);
jsonnext(J);
break;
case TK_NULL:
js_pushnull(J);
jsonnext(J);
break;
default:
js_syntaxerror(J, "JSON: unexpected token: %s", jsY_tokenstring(J->lookahead));
}
}
static int JSON_parse(js_State *J, int argc)
{
return 0;
const char *source = js_tostring(J, 1);
jsY_initlex(J, "JSON", source);
jsonnext(J);
jsonvalue(J);
// TODO: reviver Walk()
return 1;
}
static int JSON_stringify(js_State *J, int argc)