mirror of
https://github.com/ccxvii/mujs.git
synced 2026-02-06 01:41:37 +08:00
JSON.parse()
This commit is contained in:
37
jslex.c
37
jslex.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
1
jslex.h
1
jslex.h
@@ -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
95
json.c
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user