Nodix script language

Nodix feature a unique script language, allowing easy programing of network message handler, with a synthax close to javascript, and variable convertible to javascript objects.

Script code is oriented around event handler definition to facilitate asynchronous and/or parallel execution.

There can be two types of scripts.

Application script allow to define initial configuration, module dependencies, and event handlers associated to a message list.

Web page script allow to generate dynamic and interactive html5 pages using application modules, allowing embeding of script variable into javascript code and generating javascript based on dynamic data. It supports query string parsing, cookies, html forms and rpc/json.

declarative statements

Declarative statement are executed once when the script is loaded, and correspond to script global variables.

let variable = value
declare and initialize a new global variable.
proc name (arg1, arg2) = ´ code ´
declare a script procedure.
handler name (node,payload) = ` code `
declare a script event handler for blockchain protocol.
accumulator
declare an accumulator procedure.

Code statements

Code statement are used inside of script procedures, event handlers or web pages.

error
Terminate the procedure with error state.
success
Terminate the procedure with success state.
loadmod
Load a module file from module definition.
push
Add the variable or expression into the target's children.
set
Assign the right side expression to left side variable.
A new key is automically added to target objects if it doesn't exist.
add
Arithmetic add on arg1 with arg2. If they are both strings they are concatenated.
sub
Arithmetic sub on arg1 with arg2.
gettime
Get milleconds elapsed since boot.
sethandler
Assign an handler to the message list for messages matching the expression.
foreach
Execute a procedure on each element of the list.
accumulate
Execute a procedure on each element of the list and accumulate the result.
accum
Used in accumulator to accumulate the value.
log
Log the specified string or variable.
if
Skip all the code until the matching endif if the expression evaluate to false.
endif
Mark the end of conditional execution block.
mod.proc(arg1,arg2) [?|:]
If 'mod' resolve to a module definition, call the module function with the specified argument(s) (max 2).

'?' or ':' Following the statement mark conditional execution block based on return value.
endor
mark the end of conditional execution block following module procedure call.

Statements used in page script

declarative statements

page name(arg1,arg2) = ` code `
declare an HTML page generation procedure.
longpoll eventname(node, payload, handler_data) = ` code `
declare an HTTP longpoll request handler that will be executed when message 'event name' is pushed in the internal message queue.
event {message filter} name(node, payload, handler_data) = ` code `
declare an HTTP event source that will be executed when message evaluating to true with the expression 'message filter' is pushed in the internal message queue.
json name(arg1,arg2) = ` code `
declare a http/json generation procedure.

Code statements

html_head
output the html header with the specified page title,stylesheets and meta tags.
html_block
output a raw html block from a file.
html_layout
output a raw html block from the blockchain application.
html_scripts
output the javascript files.
html_var
copy a script variable to javascript variable in json format.
html_js
generate javascript block using script variables.

Application script

The script language allow to declare variable using a variant of json object declaration, as well as messages handler and initilization function.
All variable but function parameters are global to the whole script scope.

let NODE_GFX_OBJECT my_object = ` {"name":"myobject",(NODE_BITCORE_MSG_LIST) "msg_queue" : []} `

let NODE_MODULE_DEF node_adx = ` { "file" : "modz/node_adx.tpo","order":0} `

handler on_msg(node, msg) = ` node_adx.process_msg(node,msg); `

proc init_node = ` sethandler my_object.msg_queue{ "cmd=msg" } = on_msg; `

Messages can then be queued asynchronously from the application or other module into the message list to trigger the handler.

Example C code to load a script from a file and send a message to it.

mem_zone_ref vars={PTR_NULL}, proc={PTR_NULL};

if(ret)ret = load_script("nodix.node", &vars,3);
if(ret)ret = resolve_script_var ( &vars, PTR_NULL, "init_node", NODE_SCRIPT_PROC, &proc);
if(ret)ret = execute_script_proc (&vars, &proc);
if(resolve_script_var(&vars, PTR_NULL, "my_object.msg_queue", NODE_BITCORE_MSG_LIST, &msg_list)) {

if(ret)ret=tree_manager_set_child_value_str(msg,"cmd","msg");
if(ret)ret=tree_manager_node_add_child(&msg_list, msg);
release_zone_ref(&msg_list);

}
if (!ret)log_output("could not emit message \n");


Web pages scripts.

The script language used for webpage is identical to the language used for application, but all function have additional built in parameters to handle the http protocol.

The built in webserver allow automatic execution of function defined in a script with url in for the form
"/script_file.site/page_function/param1/param2"
to execute the procedure page_function defined in the script 'script_file.site' at the root of the webfolder.

script_file.site

stylesheets for all pages

let NODE_JSON_ARRAY stylesheets = `["/assets/plugins/bootstrap/css/bootstrap.min.css", "/assets/css/style.css"]`

javascripts for all pages

let NODE_JSON_ARRAY scripts = `["/assets/plugins/jquery/jquery.min.js", "/assets/plugins/bootstrap/js/bootstrap.min.js", "/assets/js/custom.js"]`

meta tags for all pages

let NODE_JSON_ARRAY metas = `[{"viewport" : "width=device-width, initial-scale=1.0"}, {"description" : ""}, {"author" : ""}]`


page declaration
page index = `

push scripts,"/assets/js/blocks.js"
html_head "NodiX INDEX PAGE"
html_block "templates/menu.html"
html_block "templates/node.html"
html_scripts
html_var SelfNode;
html_js

$(document).ready(function ()
{

site_base_url = '/nodix.site';
api_base_url ='';
lang = 'en';

$('#node_name').html(SelfNode.user_agent);
$('#node_version').html(SelfNode.version);
$('#node_bheight').html(SelfNode.block_height);

get_node_lag(SelfNode)

});

end_js
html_block "templates/footer.html"
success

`

event source declaration
event {"cmd=newblock"} newblock_event(node, payload, handler_data) = `

push data< handler_data.write_group;
if(payload.block)
push data< payload.block;
success
endif
if(payload.header)
push data< payload.header;
success
endif
error

`