void jslGetTokenString(char *str, size_t len) { if (lex->tk == LEX_ID) { espruino_snprintf(str, len, "ID:%s", jslGetTokenValueAsString()); } else if (lex->tk == LEX_STR) { espruino_snprintf(str, len, "String:'%s'", jslGetTokenValueAsString()); } else jslTokenAsString(lex->tk, str, len); }
void jslGetTokenString(char *str, size_t len) { if (lex->tk == LEX_ID) { strncpy(str, "ID:", len); strncat(str, jslGetTokenValueAsString(), len); } else if (lex->tk == LEX_STR) { strncpy(str, "String:'", len); strncat(str, jslGetTokenValueAsString(), len); strncat(str, "'", len); } else jslTokenAsString(lex->tk, str, len); }
static bool _parse_time(JsLex *lex, TimeInDay *time, int initialChars) { time->hour = (int)stringToIntWithRadix(&jslGetTokenValueAsString(lex)[initialChars], 10, 0); jslGetNextToken(lex); if (lex->tk==':') { jslGetNextToken(lex); if (lex->tk == LEX_INT) { time->min = _parse_int(lex); jslGetNextToken(lex); if (lex->tk==':') { jslGetNextToken(lex); if (lex->tk == LEX_INT || lex->tk == LEX_FLOAT) { JsVarFloat f = stringToFloat(jslGetTokenValueAsString(lex)); time->sec = (int)f; time->ms = (int)(f*1000) % 1000; jslGetNextToken(lex); if (lex->tk == LEX_ID && strcmp(jslGetTokenValueAsString(lex),"GMT")==0) { jslGetNextToken(lex); } if (lex->tk == '+' || lex->tk == '-') { int sign = lex->tk == '+' ? 1 : -1; jslGetNextToken(lex); if (lex->tk == LEX_INT) { int i = _parse_int(lex); // correct the fact that it's HHMM and turn it into just minutes i = (i%100) + ((i/100)*60); time->zone = i*sign; jslGetNextToken(lex); } } return true; } } } } return false; }
int nativeCallGetCType(JsLex *lex) { if (lex->tk == LEX_R_VOID) { jslMatch(lex, LEX_R_VOID); return JSWAT_VOID; } if (lex->tk == LEX_ID) { int t = -1; char *name = jslGetTokenValueAsString(lex); if (strcmp(name,"int")==0) t=JSWAT_INT32; if (strcmp(name,"double")==0) t=JSWAT_JSVARFLOAT; if (strcmp(name,"bool")==0) t=JSWAT_BOOL; if (strcmp(name,"Pin")==0) t=JSWAT_PIN; if (strcmp(name,"JsVar")==0) t=JSWAT_JSVAR; jslMatch(lex, LEX_ID); return t; } return -1; // unknown }
JsVar *jswrap_json_parse_internal() { switch (lex->tk) { case LEX_R_TRUE: jslGetNextToken(lex); return jsvNewFromBool(true); case LEX_R_FALSE: jslGetNextToken(lex); return jsvNewFromBool(false); case LEX_R_NULL: jslGetNextToken(lex); return jsvNewWithFlags(JSV_NULL); case '-': { jslGetNextToken(lex); if (lex->tk!=LEX_INT && lex->tk!=LEX_FLOAT) return 0; JsVar *v = jswrap_json_parse_internal(lex); JsVar *zero = jsvNewFromInteger(0); JsVar *r = jsvMathsOp(zero, v, '-'); jsvUnLock2(v, zero); return r; } case LEX_INT: { long long v = stringToInt(jslGetTokenValueAsString(lex)); jslGetNextToken(lex); return jsvNewFromLongInteger(v); } case LEX_FLOAT: { JsVarFloat v = stringToFloat(jslGetTokenValueAsString(lex)); jslGetNextToken(lex); return jsvNewFromFloat(v); } case LEX_STR: { JsVar *a = jslGetTokenValueAsVar(lex); jslGetNextToken(lex); return a; } case '[': { JsVar *arr = jsvNewEmptyArray(); if (!arr) return 0; jslGetNextToken(lex); // [ while (lex->tk != ']' && !jspHasError()) { JsVar *value = jswrap_json_parse_internal(lex); if (!value || (lex->tk!=']' && !jslMatch(','))) { jsvUnLock2(value, arr); return 0; } jsvArrayPush(arr, value); jsvUnLock(value); } if (!jslMatch(']')) { jsvUnLock(arr); return 0; } return arr; } case '{': { JsVar *obj = jsvNewObject(); if (!obj) return 0; jslGetNextToken(lex); // { while (lex->tk == LEX_STR && !jspHasError()) { JsVar *key = jsvAsArrayIndexAndUnLock(jslGetTokenValueAsVar(lex)); jslGetNextToken(lex); JsVar *value = 0; if (!jslMatch(':') || !(value=jswrap_json_parse_internal(lex)) || (lex->tk!='}' && !jslMatch(','))) { jsvUnLock3(key, value, obj); return 0; } jsvAddName(obj, jsvMakeIntoVariableName(key, value)); jsvUnLock2(value, key); } if (!jslMatch('}')) { jsvUnLock(obj); return 0; } return obj; } default: { char buf[32]; jslTokenAsString(lex->tk, buf, 32); jsExceptionHere(JSET_SYNTAXERROR, "Expecting a valid value, got %s", buf); return 0; // undefined = error } } }
JsVar *jswrap_json_parse_internal(JsLex *lex) { switch (lex->tk) { case LEX_R_TRUE: jslGetNextToken(lex); return jsvNewFromBool(true); case LEX_R_FALSE: jslGetNextToken(lex); return jsvNewFromBool(false); case LEX_R_NULL: jslGetNextToken(lex); return jsvNewWithFlags(JSV_NULL); case '-': { jslGetNextToken(lex); if (lex->tk!=LEX_INT && lex->tk!=LEX_FLOAT) return 0; JsVar *v = jswrap_json_parse_internal(lex); JsVar *zero = jsvNewFromInteger(0); JsVar *r = jsvMathsOp(zero, v, '-'); jsvUnLock(v); jsvUnLock(zero); return r; } case LEX_INT: { long long v = stringToInt(jslGetTokenValueAsString(lex)); jslGetNextToken(lex); return jsvNewFromLongInteger(v); } case LEX_FLOAT: { JsVarFloat v = stringToFloat(jslGetTokenValueAsString(lex)); jslGetNextToken(lex); return jsvNewFromFloat(v); } case LEX_STR: { JsVar *a = jslGetTokenValueAsVar(lex); jslGetNextToken(lex); return a; } case '[': { JsVar *arr = jsvNewWithFlags(JSV_ARRAY); if (!arr) return 0; jslGetNextToken(lex); // [ while (lex->tk != ']') { JsVar *value = jswrap_json_parse_internal(lex); if (!value || (lex->tk!=']' && !jslMatch(lex, ','))) { jsvUnLock(value); jsvUnLock(arr); return 0; } jsvArrayPush(arr, value); jsvUnLock(value); } if (!jslMatch(lex, ']')) { jsvUnLock(arr); return 0; } return arr; } case '{': { JsVar *obj = jsvNewWithFlags(JSV_OBJECT); if (!obj) return 0; jslGetNextToken(lex); // { while (lex->tk == LEX_STR) { JsVar *key = jsvAsArrayIndexAndUnLock(jslGetTokenValueAsVar(lex)); jslGetNextToken(lex); JsVar *value = 0; if (!jslMatch(lex, ':') || !(value=jswrap_json_parse_internal(lex)) || (lex->tk!='}' && !jslMatch(lex, ','))) { jsvUnLock(key); jsvUnLock(value); jsvUnLock(obj); return 0; } jsvAddName(obj, jsvMakeIntoVariableName(key, value)); jsvUnLock(value); jsvUnLock(key); } if (!jslMatch(lex, '}')) { jsvUnLock(obj); return 0; } return obj; } default: return 0; // undefined = error } }
/*JSON{ "type" : "staticmethod", "class" : "Date", "name" : "parse", "generate" : "jswrap_date_parse", "params" : [ ["str","JsVar","A String"] ], "return" : ["float","The number of milliseconds since 1970"] } Parse a date string and return milliseconds since 1970. Data can be either '2011-10-20T14:48:00', '2011-10-20' or 'Mon, 25 Dec 1995 13:30:00 +0430' */ JsVarFloat jswrap_date_parse(JsVar *str) { if (!jsvIsString(str)) return 0; TimeInDay time; time.daysSinceEpoch = 0; time.hour = 0; time.min = 0; time.sec = 0; time.ms = 0; time.zone = 0; CalendarDate date = getCalendarDate(0); JsLex lex; jslInit(&lex, str); if (lex.tk == LEX_ID) { date.month = getMonth(jslGetTokenValueAsString(&lex)); date.dow = getDay(jslGetTokenValueAsString(&lex)); if (date.month>=0) { // Aug 9, 1995 jslGetNextToken(&lex); if (lex.tk == LEX_INT) { date.day = _parse_int(&lex); jslGetNextToken(&lex); if (lex.tk==',') { jslGetNextToken(&lex); if (lex.tk == LEX_INT) { date.year = _parse_int(&lex); jslGetNextToken(&lex); if (lex.tk == LEX_INT) { _parse_time(&lex, &time, 0); } } } } } else if (date.dow>=0) { date.month = 0; jslGetNextToken(&lex); if (lex.tk==',') { jslGetNextToken(&lex); if (lex.tk == LEX_INT) { date.day = _parse_int(&lex); jslGetNextToken(&lex); if (lex.tk == LEX_ID && getMonth(jslGetTokenValueAsString(&lex))>=0) { date.month = getMonth(jslGetTokenValueAsString(&lex)); jslGetNextToken(&lex); if (lex.tk == LEX_INT) { date.year = _parse_int(&lex); jslGetNextToken(&lex); if (lex.tk == LEX_INT) { _parse_time(&lex, &time, 0); } } } } } } else { date.dow = 0; date.month = 0; } } else if (lex.tk == LEX_INT) { // assume 2011-10-10T14:48:00 format date.year = _parse_int(&lex); jslGetNextToken(&lex); if (lex.tk=='-') { jslGetNextToken(&lex); if (lex.tk == LEX_INT) { date.month = _parse_int(&lex) - 1; jslGetNextToken(&lex); if (lex.tk=='-') { jslGetNextToken(&lex); if (lex.tk == LEX_INT) { date.day = _parse_int(&lex); jslGetNextToken(&lex); if (lex.tk == LEX_ID && jslGetTokenValueAsString(&lex)[0]=='T') { _parse_time(&lex, &time, 1); } } } } } } jslKill(&lex); time.daysSinceEpoch = fromCalenderDate(&date); return fromTimeInDay(&time); }
static JsVarInt _parse_int(JsLex *lex) { return (int)stringToIntWithRadix(jslGetTokenValueAsString(lex), 10, 0); }