160 lines
3.1 KiB
C
160 lines
3.1 KiB
C
////////////////////////////////////////////////////////////
|
|
//~ Blob types
|
|
|
|
Enum(JSON_Type)
|
|
{
|
|
JSON_Type_Null,
|
|
JSON_Type_Bool,
|
|
JSON_Type_Number,
|
|
JSON_Type_String,
|
|
JSON_Type_Array,
|
|
JSON_Type_Object
|
|
};
|
|
|
|
Struct(JSON_Blob)
|
|
{
|
|
JSON_Type type;
|
|
String key;
|
|
|
|
JSON_Blob *parent;
|
|
JSON_Blob *next;
|
|
JSON_Blob *child_first;
|
|
JSON_Blob *child_last;
|
|
|
|
union
|
|
{
|
|
String string;
|
|
f64 number;
|
|
b32 boolean;
|
|
} value;
|
|
};
|
|
|
|
Struct(JSON_Error)
|
|
{
|
|
String msg;
|
|
u64 start;
|
|
u64 end;
|
|
JSON_Error *next;
|
|
};
|
|
|
|
Struct(JSON_ErrorList)
|
|
{
|
|
u64 count;
|
|
JSON_Error *first;
|
|
JSON_Error *last;
|
|
};
|
|
|
|
Struct(JSON_Result)
|
|
{
|
|
JSON_Blob *root;
|
|
JSON_ErrorList errors;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Lexer types
|
|
|
|
#define JSON_Case_Newline \
|
|
0x0A: /* Line feed or New line */ \
|
|
case 0x0D /* Carriage return */
|
|
|
|
#define JSON_Case_Space \
|
|
0x20: /* Space */ \
|
|
case 0x09 /* Horizontal tab */
|
|
|
|
#define JSON_Case_Digit0Through9 \
|
|
'0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9'
|
|
|
|
#define JSON_Case_Digit1Through9 \
|
|
'1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9'
|
|
|
|
#define JSON_Case_Symbol \
|
|
',': case ':': case '[': case ']': case '{': case '}'
|
|
|
|
Enum(JSON_TokenKind)
|
|
{
|
|
JSON_TokenKind_Unknown,
|
|
|
|
JSON_TokenKind_Number,
|
|
JSON_TokenKind_String,
|
|
|
|
JSON_TokenKind_KeywordTrue,
|
|
JSON_TokenKind_KeywordFalse,
|
|
JSON_TokenKind_KeywordNull,
|
|
|
|
JSON_TokenKind_Comma,
|
|
JSON_TokenKind_Colon,
|
|
JSON_TokenKind_SquareBraceOpen,
|
|
JSON_TokenKind_SquareBraceClose,
|
|
JSON_TokenKind_CurlyBraceOpen,
|
|
JSON_TokenKind_CurlyBraceClose,
|
|
|
|
JSON_TokenKind_Bof,
|
|
JSON_TokenKind_Eof
|
|
};
|
|
|
|
Struct(JSON_Token)
|
|
{
|
|
JSON_TokenKind kind;
|
|
u64 start;
|
|
u64 end;
|
|
JSON_Token *next;
|
|
};
|
|
|
|
Struct(JSON_TokenList)
|
|
{
|
|
JSON_Token *token_first;
|
|
JSON_Token *token_last;
|
|
};
|
|
|
|
Enum(JSON_LexNumberState)
|
|
{
|
|
JSON_LexNumberState_Whole,
|
|
JSON_LexNumberState_Fraction,
|
|
JSON_LexNumberState_Exponent
|
|
};
|
|
|
|
Global Readonly String JSON_keyword_strings[] = {
|
|
['t'] = CompLit("true"),
|
|
['f'] = CompLit("false"),
|
|
['n'] = CompLit("null")
|
|
};
|
|
|
|
Global Readonly JSON_TokenKind JSON_keyword_types[] = {
|
|
['t'] = JSON_TokenKind_KeywordTrue,
|
|
['f'] = JSON_TokenKind_KeywordFalse,
|
|
['n'] = JSON_TokenKind_KeywordNull
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Parser types
|
|
|
|
Struct(JSON_Parser)
|
|
{
|
|
// Input
|
|
String src;
|
|
JSON_Token *at;
|
|
|
|
// Output
|
|
JSON_Blob *root;
|
|
JSON_ErrorList errors;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Lex
|
|
|
|
JSON_Token *JSON_PushToken(Arena *arena, JSON_TokenList *list);
|
|
JSON_TokenList JSON_TokensFromString(Arena *arena, String src);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Interpret
|
|
|
|
f64 interpret_number(String src);
|
|
String interpret_string(Arena *arena, String src, String *error);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Parse
|
|
|
|
void JSON_PushError(Arena *arena, JSON_Parser *p, JSON_Token *t, String msg);
|
|
void JSON_Parse(Arena *arena, JSON_Parser *p);
|
|
JSON_Result JSON_BlobFromString(Arena *arena, String src);
|