Exemple #1
0
/*JSON{
  "type" : "staticmethod",
  "class" : "JSON",
  "name" : "parse",
  "generate" : "jswrap_json_parse",
  "params" : [
    ["string","JsVar","A JSON string"]
  ],
  "return" : ["JsVar","The JavaScript object created by parsing the data string"]
}
Parse the given JSON string into a JavaScript object

NOTE: This implementation uses eval() internally, and as such it is unsafe as it can allow arbitrary JS commands to be executed.
*/
JsVar *jswrap_json_parse(JsVar *v) {
  JsLex lex;
  jslInit(&lex, v);
  JsVar *res = jswrap_json_parse_internal(&lex);
  jslKill(&lex);
  return res;
}
Exemple #2
0
/*JSON{
  "type" : "staticmethod",
  "class" : "JSON",
  "name" : "parse",
  "generate" : "jswrap_json_parse",
  "params" : [
    ["string","JsVar","A JSON string"]
  ],
  "return" : ["JsVar","The JavaScript object created by parsing the data string"]
}
Parse the given JSON string into a JavaScript object

NOTE: This implementation uses eval() internally, and as such it is unsafe as it can allow arbitrary JS commands to be executed.
 */
JsVar *jswrap_json_parse(JsVar *v) {
  JsLex lex;
  JsVar *str = jsvAsString(v);
  JsLex *oldLex = jslSetLex(&lex);
  jslInit(str);
  jsvUnLock(str);
  JsVar *res = jswrap_json_parse_internal();
  jslKill();
  jslSetLex(oldLex);
  return res;
}
Exemple #3
0
/*JSON{
  "type" : "staticmethod",
  "ifndef" : "SAVE_ON_FLASH",
  "class" : "E",
  "name" : "nativeCall",
  "generate" : "jswrap_espruino_nativeCall",
  "params" : [
    ["addr","int","The address in memory of the function"],
    ["sig","JsVar","The signature of the call, `returnType (arg1,arg2,...)`. Allowed types are `void`,`bool`,`int`,`double`,`Pin`,`JsVar`"]
  ],
  "return" : ["JsVar","The native function"]
}
ADVANCED: This is a great way to crash Espruino if you're not sure what you are doing

Create a native function that executes the code at the given address. Eg. `E.nativeCall(0x08012345,'double (double,double)')(1.1, 2.2)` 

If you're executing a thumb function, you'll almost certainly need to set the bottom bit of the address to 1.

Note it's not guaranteed that the call signature you provide can be used - it has to be something that a function in Espruino already uses.
*/
JsVar *jswrap_espruino_nativeCall(JsVarInt addr, JsVar *signature) {
  unsigned int argTypes = 0;
  if (jsvIsUndefined(signature)) {
    // Nothing to do
  } else if (jsvIsString(signature)) {
    JsLex lex;
    jslInit(&lex, signature);
    int argType;
    bool ok = true;
    int argNumber = 0;
    argType = nativeCallGetCType(&lex);
    if (argType>=0) argTypes |= (unsigned)argType << (JSWAT_BITS * argNumber++);
    else ok = false;
    if (ok) ok = jslMatch(&lex, '(');
    while (ok && lex.tk!=LEX_EOF && lex.tk!=')') {
      argType = nativeCallGetCType(&lex);
      if (argType>=0) {
        argTypes |= (unsigned)argType << (JSWAT_BITS * argNumber++);
        if (lex.tk!=')') ok = jslMatch(&lex, ',');
      } else ok = false;
    }
    if (ok) ok = jslMatch(&lex, ')');
    jslKill(&lex);
    if (argTypes & (unsigned int)~0xFFFF)
      ok = false;
    if (!ok) {
      jsExceptionHere(JSET_ERROR, "Error Parsing signature at argument number %d", argNumber);
      return 0;
    }
  } else {
    jsExceptionHere(JSET_ERROR, "Invalid Signature");
    return 0;
  }

  return jsvNewNativeFunction((void *)(size_t)addr, (unsigned short)argTypes);
}
Exemple #4
0
/*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);
}
Exemple #5
0
JsVar *jslNewTokenisedStringFromLexer(JslCharPos *charFrom, size_t charTo) {
  // New method - tokenise functions
  // save old lex
  JsLex *oldLex = lex;
  JsLex newLex;
  lex = &newLex;
  // work out length
  size_t length = 0;
  jslInit(oldLex->sourceVar);
  jslSeekToP(charFrom);
  int lastTk = LEX_EOF;
  while (lex->tk!=LEX_EOF && jsvStringIteratorGetIndex(&lex->it)<=charTo+1) {
    if ((lex->tk==LEX_ID || lex->tk==LEX_FLOAT || lex->tk==LEX_INT) &&
        ( lastTk==LEX_ID ||  lastTk==LEX_FLOAT ||  lastTk==LEX_INT)) {
      jsExceptionHere(JSET_SYNTAXERROR, "ID/number following ID/number isn't valid JS");
      length = 0;
      break;
    }
    if (lex->tk==LEX_ID ||
        lex->tk==LEX_INT ||
        lex->tk==LEX_FLOAT ||
        lex->tk==LEX_STR ||
        lex->tk==LEX_TEMPLATE_LITERAL) {
      length += jsvStringIteratorGetIndex(&lex->it)-jsvStringIteratorGetIndex(&lex->tokenStart.it);
    } else {
      length++;
    }
    lastTk = lex->tk;
    jslGetNextToken();
  }

  // Try and create a flat string first
  JsVar *var = jsvNewStringOfLength((unsigned int)length, NULL);
  if (var) { // out of memory
    JsvStringIterator dstit;
    jsvStringIteratorNew(&dstit, var, 0);
    // now start appending
    jslSeekToP(charFrom);
    while (lex->tk!=LEX_EOF && jsvStringIteratorGetIndex(&lex->it)<=charTo+1) {
      if (lex->tk==LEX_ID ||
          lex->tk==LEX_INT ||
          lex->tk==LEX_FLOAT ||
          lex->tk==LEX_STR ||
          lex->tk==LEX_TEMPLATE_LITERAL) {
        jsvStringIteratorSetCharAndNext(&dstit, lex->tokenStart.currCh);
        JsvStringIterator it = jsvStringIteratorClone(&lex->tokenStart.it);
        while (jsvStringIteratorGetIndex(&it)+1 < jsvStringIteratorGetIndex(&lex->it)) {
          jsvStringIteratorSetCharAndNext(&dstit, jsvStringIteratorGetChar(&it));
          jsvStringIteratorNext(&it);
        }
        jsvStringIteratorFree(&it);
      } else {
        jsvStringIteratorSetCharAndNext(&dstit, (char)lex->tk);
      }
      lastTk = lex->tk;
      jslGetNextToken();
    }
    jsvStringIteratorFree(&dstit);
  }
  // restore lex
  jslKill();
  lex = oldLex;

  return var;
}