diff --git a/examples/javascript/Makefile b/examples/javascript/Makefile index 21848e6638..b090e89b66 100644 --- a/examples/javascript/Makefile +++ b/examples/javascript/Makefile @@ -24,11 +24,24 @@ 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 + +JS_PATH := $(BINDIR)/js/$(MODULE) +# add directory of generated *.js.h files to include path +CFLAGS += -I$(JS_PATH) + +# generate .js.h header files of .js files +JS = $(wildcard *.js) +JS_H := $(JS:%.js=$(JS_PATH)/%.js.h) + +$(JS_PATH)/: + @mkdir -p $@ + +$(JS_H): | $(JS_PATH)/ +$(JS_H): $(JS_PATH)/%.js.h: %.js + xxd -i $< | sed 's/^unsigned/const unsigned/g' > $@ + +$(RIOTBUILD_CONFIG_HEADER_C): $(JS_H) diff --git a/examples/javascript/README.md b/examples/javascript/README.md index 4886781423..9d3bf1008c 100644 --- a/examples/javascript/README.md +++ b/examples/javascript/README.md @@ -1,39 +1,23 @@ ### About -This example enables to execute arbitrary Javascript directly from the command line on the RIOT shell. +This example shows how to write IoT applications using javascript. ### 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). +- currently, the only actual function available is "print" -- 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! +### How to use -- Except in the `print` instruction in your script, you have to replace single brackets `'` with `\'`. +Just put your javascript code in "main.js" (check the example). The file will +automatically be included when compiling the application, which will execute +the file right after booting. -- 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 run -### How to build +Type `make flash term`. -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 +Note: you may have to press `RESET` on the board (after the flash) if the board +reboots faster than the terminal program can start.. diff --git a/examples/javascript/main.c b/examples/javascript/main.c index 5c75d0e80f..18d7523c9f 100644 --- a/examples/javascript/main.c +++ b/examples/javascript/main.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2017 Inria + * 2017 Kaspar Schleiser * * 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 @@ -11,58 +12,64 @@ * @{ * * @file - * @brief Showing an example of scripting (javascript) from command line + * @brief Example of how to use javascript on RIOT * * @author Emmanuel Baccelli + * @author Kaspar Schleiser * * @} */ #include #include -#include "shell.h" + #include "jerryscript.h" +#include "jerryscript-ext/handler.h" -int shell_script(int argc, char **argv) +/* include header generated from main.js */ +#include "main.js.h" + +int js_run(const jerry_char_t *script, size_t script_size) { - 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_value_t ret_value; + + /* Initialize engine */ + jerry_init(JERRY_INIT_EMPTY); + + /* Register the print function in the global object. */ + jerryx_handler_register_global((const jerry_char_t *) "print", jerryx_handler_print); + + /* Setup Global scope code */ + ret_value = jerry_parse(script, script_size, false); + + if (!jerry_value_has_error_flag(ret_value)) { + /* Execute the parsed source code in the Global scope */ + ret_value = jerry_run(ret_value); } - 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]); + int res = 0; + + if (jerry_value_has_error_flag(ret_value)) { + printf("js_run(): Script Error!"); + res = -1; } - 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); + jerry_release_value(ret_value); - return (ret_value != 0); + /* Cleanup engine */ + jerry_cleanup(); + + return res; } -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)); + printf("Executing main.js:\n"); + + js_run(main_js, main_js_len); return 0; } diff --git a/examples/javascript/main.js b/examples/javascript/main.js new file mode 100644 index 0000000000..0243cda177 --- /dev/null +++ b/examples/javascript/main.js @@ -0,0 +1 @@ +print("Hello from JerryScript!");