diff --git a/examples/javascript/Makefile b/examples/javascript/Makefile new file mode 100644 index 000000000..1a285d390 --- /dev/null +++ b/examples/javascript/Makefile @@ -0,0 +1,33 @@ +# application name +APPLICATION = riot_javascript + +# default BOARD environment +BOARD ?= native + +BOARD_INSUFFICIENT_MEMORY := airfy-beacon calliope-mini cc2650stk maple-mini \ + microbit nrf51dongle nrf6310 nucleo-f030 nucleo-f070 \ + nucleo-f072 nucleo-f103 nucleo-f302 nucleo-f334 nucleo-f410 \ + nucleo-l053 nucleo-l073 nucleo32-f031 nucleo32-f042 \ + nucleo32-f303 nucleo32-l031 opencm904 pca10000 \ + pca10005 spark-core stm32f0discovery weio yunjia-nrf51822 \ + +BOARD_BLACKLIST := arduino-duemilanove arduino-mega2560 arduino-uno chronos \ + msb-430 msb-430h qemu-i386 telosb waspmote-pro wsn430-v1_3b \ + wsn430-v1_4 z1 + +# Comment this out to disable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +CFLAGS += -DDEVELHELP + +# Set stack size to something (conservatively) enormous +CFLAGS += -DTHREAD_STACKSIZE_MAIN=9092 + +# Add the shell and some shell commands +USEMODULE += shell +USEMODULE += shell_commands + +# Add the package for Jerryscript +USEPKG += jerryscript + +include $(CURDIR)/../../Makefile.include diff --git a/examples/javascript/README.md b/examples/javascript/README.md new file mode 100644 index 000000000..488678142 --- /dev/null +++ b/examples/javascript/README.md @@ -0,0 +1,39 @@ +### About + +This example enables to execute arbitrary Javascript directly from the command line on the RIOT shell. + +### Acknowledgement +This example is based on [Jerryscript](https://github.com/jerryscript-project/jerryscript) which does all the heavy lifting, providing full ECMAScript 5.1 profile on your IoT device (kudos guys!). + +### Caveats + +- On your local board: best used with a serial communication program such [minicom](https://help.ubuntu.com/community/Minicom) instead of PyTerm (see why below). + +- On a testbed: you can try it on [IoT-lab](https://www.iot-lab.info). Tested and works so far on [IoT-lab M3](https://www.iot-lab.info/hardware/m3/), upload and flash the .elf, ssh into the node, and script away! + +- Except in the `print` instruction in your script, you have to replace single brackets `'` with `\'`. + +- Expect some issues with PyTerm which interprets by default the first `;` as the end of the script command. Furthermore, if the script is long, PyTerm seems to get confused (hence the recommended use of minicom). To start playing with PyTerm, first edit `;` line 256 of RIOT/dist/tools/pyterm/pyterm + +### How to build + +Type `make flash`. Then use your preferred serial communication tool to land in the RIOT shell. +Note: you may have to type `reboot` or to press `RESET` on the board (after the flash). + +### Running the example + +In the RIOT shell, `help` will provide the list of available commands. + +The `script` command will run the test script code that you input in the command line. +Some examples of scripts you can try: +``` +script print ('hello'); +``` +``` +script var x = Math.sqrt (64); var txt = \'\'; while (x>1) { txt += --x + \'\\n\';} print (txt); +``` +``` +script var person = { fname:\'John\', lname:\'Doe\', age:25 }; var text = \'\'; var x; for (x in person) { text += person[x] + \'\\n\'; } print (text); +``` + +Remark: outside of the print command, you may have to replace single brackets ' with \'. \ No newline at end of file diff --git a/examples/javascript/main.c b/examples/javascript/main.c new file mode 100644 index 000000000..ae1b162bc --- /dev/null +++ b/examples/javascript/main.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * @brief Showing an example of scripting (javascript) from command line + * + * @author Emmanuel Baccelli + * + * @} + */ + +#include +#include "shell.h" +#include "jerryscript.h" + +int shell_script(int argc, char **argv) +{ + if (argc < 2) { + puts("Usage: script \n" + "For example, try: \n" + "script var txt = \\'\\'; txt += Math.PI; print (\\'Pi=\\'+txt); \n" + "Note: you need to substitute usual quotes with \\' \n"); + return -1; + } + + jerry_char_t script[(2 * SHELL_DEFAULT_BUFSIZE + 1)]; + *script = '\0'; + for(int i = 1; i < argc; i++) { + if (i>1) { + strcat((char *)script, " "); + } + strcat((char *)script, argv[i]); + } + + size_t script_size = strlen((char *) script); + printf("Executing script: [%s]\n\n", script); + bool ret_value = jerry_run_simple(script, script_size, JERRY_INIT_EMPTY); + + return (ret_value != 0); +} + +const shell_command_t shell_commands[] = { + { "script", "Shell scripting ", shell_script }, + { NULL, NULL, NULL } +}; + +int main(void) +{ + printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD); + printf("This board features a(n) %s MCU.\n", RIOT_MCU); + + /* start the shell */ + char line_buf[2 * SHELL_DEFAULT_BUFSIZE]; + /* for longer script support shell buffer should be bigger */ + shell_run(shell_commands, line_buf, sizeof(line_buf)); + + return 0; +}