UNPKG

force-lang

Version:

a modern forth lang compatible with NodeJS

1,459 lines (1,451 loc) 42.9 kB
const log = require('bunny-logger'); //const request = require('request-promise-native'); const request = require('sync-request'); const JSON5 = require('json5'); const env = require('./env'); const err = require('./error'); const eval = require('./eval'); const loadfile = require('./load-file'); const obj_utils = require('./obj_utils'); const vsprintf = require('format').vsprintf; const cheerio = require('cheerio'); class NativeLib{ constructor(){ this.populate(); } make_func_obj(func_name){ return { "_type":"TC_COMP_FUNC", "_datum":func_name } } test_func(){ log.info('...hai detto pippo?'); } bye_func(){ process.exit(0); } noop_func(){ //do nothing (no operation) } print_stack_func(){ env.print_stack(); } print_env_func(){ env.print_debug(); } print_words_func(){ let x = env._dict; //x=x.filter(item => item._type == 'TC_NATIVE_FUNC'); for(var item of x){ if(item._datum._type == 'TC_NATIVE_FUNC'|| item._datum._type == 'TC_COMP_FUNC'){ //log.info(`${item._name} `); process.stdout.write(`${item._name} `); } } log.info(''); } emit_func(){ const x = env.s.pop(); //log.info(x); if(x._type === 'TC_NUM'){ process.stdout.write(String.fromCharCode(x._datum)); return; } env.s.push(err.throw(`unknown item type ${x._type} of ${x._datum}`)); } see_func(func_name){ var x=env.lookup(func_name); if(!x){ log.info('no word found...'); return; } switch(x._datum._type){ case 'TC_NATIVE_FUNC': log.info(`: ${x._name}`); log.info('<native func> ;'); break; case 'TC_COMP_FUNC': log.info(`: ${x._name}`); process.stdout.write(` `); for(var n of x._datum._datum){ process.stdout.write(`${n._datum} `); } log.info(''); break; default: log.info('not a word...'); break; } } print_tos_func(){ const x = env.s.pop(); if(!x) return; //log.info(x); switch(x._type){ case 'TC_NUM': case 'TC_STR': case 'TC_BOOL': log.info(x._datum); break; case 'TC_JSON': log.info(obj_utils.stringify(x._datum)); break; case 'TC_FUNC_JS': log.info('#-<js func>'); break; case 'TC_LAMBDA_FUNC': log.info('#-<lambda func>'); break; case 'TC_VAR': log.info(x._name); break; case 'TC_ERR': log.info(`ERR: ${x._datum.msg}`); break; default: log.info(`unknown: { ${x._type} ${x._datum} }`); break; } } print_debug_tos_func(){ const x = env.s.pop(); if(!x) return; //log.info(x); switch(x._type){ case 'TC_NUM': case 'TC_STR': case 'TC_BOOL': log.info(`{ ${x._type} ${x._datum} }`); break; case 'TC_JSON': log.info(`{ ${x._type} ${obj_utils.stringify(x._datum)} }`); break; case 'TC_FUNC_JS': log.info('#-<js func>'); break; case 'TC_LAMBDA_FUNC': log.info('#-<lambda func>'); break; case 'TC_VAR': log.info(`{ ${x._type} ${x._name} ${obj_utils.stringify(x._datum._datum)} }`); break; case 'TC_ERR': log.info(`ERR: ${x._datum.msg}`); break; default: log.info(`unknown: { ${x._type} ${x._datum} }`); break; } } assign_var_func(){ const varx = env.s.pop(); const val = env.s.pop(); if(!varx || !val) { env.s.push(err.throw('no items on top 2 elements of the stack... aborting')); return; } //log.info(varx); //log.info(val); switch(val._type){ case'TC_NUM': case 'TC_STR': case 'TC_JSON': case 'TC_PROMISE': varx._datum = val; //env.set(varx._name, val, varx._type, varx._where); break; default: break; } } read_var_func(){ const varx = env.s.pop(); if(!varx) { env.s.push(err.throw('no element on top of the stack... aborting')); return; } //log.info(varx); switch(varx._datum._type){ case'TC_NUM': case 'TC_STR': case 'TC_JSON': case 'TC_PROMISE': env.s.push(varx._datum); break; default: break; } } not_func(){ if(!env.is_bool(env.TOS())){ env.s.push(err.throw('TOS is not a bool. aborting operation...')); return; } let x = env.get_bool_val(env.s.pop()); env.s.push(env.set_bool_val(!x)); } and_func(){ if(!env.is_bool(env.TOS())){ env.s.push(err.throw('TOS is not a bool. aborting operation...')); return; } if(!env.is_bool(env.TOS2())){ env.s.push(err.throw('TOS" is not a bool. aborting operation...')); return; } let a=env.get_bool_val(env.s.pop()); let b=env.get_bool_val(env.s.pop()); env.s.push(env.set_bool_val(a&&b)); } or_func(){ if(!env.is_bool(env.TOS())){ env.s.push(err.throw('TOS is not a bool. aborting operation...')); return; } if(!env.is_bool(env.TOS2())){ env.s.push(err.throw('TOS2 is not a bool. aborting operation...')); return; } let a=env.get_bool_val(env.s.pop()); let b=env.get_bool_val(env.s.pop()); env.s.push(env.set_bool_val(a||b)); } is_num_func(){ if(env.is_num(env.s.pop())){ env.s.push(env.true_obj()); return; } env.s.push(env.false_obj()); } is_string_func(){ if(env.is_string(env.s.pop())){ env.s.push(env.true_obj()); return; } env.s.push(env.false_obj()); } is_list_func(){ if(env.is_list(env.s.pop())){ env.s.push(env.true_obj()); return; } env.s.push(env.false_obj()); } is_falsy_func(){ let x = env.s.pop(); if(x){ switch(x._type){ case 'TC_NUM': if(x._datum==0) return env.s.push(env.true_obj()); else return env.s.push(env.false_obj()); break; case 'TC_STR': if(x._datum == '') return env.s.push(env.true_obj()); break; case 'TC_BOOL': if(env.is_false(x)) return env.s.push(env.true_obj()); break; case 'TC_JLIST': case 'TC_JOBJ': default: return env.s.push(env.false_obj()); break; } } return env.s.push(env.true_obj()); } dup_func(){ env.s.push(env.TOS()); } swap_func(){ if(env.TOS() && env.TOS2()){ let x = env.s.pop(); let y = env.s.pop(); env.s.push(x); env.s.push(y); return; } env.s.push(err.throw('not 2 elemets in the stack... aborting...')); } drop_func(){ env.s.pop(); } ndrop_func(){ if(env.TOS() && env.TOS()._type=== 'TC_NUM'){ try{ let n=env.s.pop()._datum; while(n>0) { env.s.pop(); n--; } return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. TOS is not a number.")); } nbye_func(){ if(env.TOS() && env.TOS()._type == 'TC_NUM'){ process.exit(env.s.pop()._datum); } env.s.push(err.throw('TOS not a number... aborting')); } over_func(){ env.s.push(env.s.look_at(1)); } num_plus_func(){ if(env.TOS() && env.TOS()._type == 'TC_NUM' && env.TOS2() && env.TOS2()._type == 'TC_NUM'){ env.s.push({_type: 'TC_NUM', _datum: env.s.pop()._datum + env.s.pop()._datum}); return; } env.s.push(err.throw('no numbers on top 2 elements of the stack... aborting')); } num_minus_func(){ if(env.TOS() && env.TOS()._type == 'TC_NUM' && env.TOS2() && env.TOS2()._type == 'TC_NUM'){ let x = env.s.pop()._datum; let y = env.s.pop()._datum; env.s.push({_type: 'TC_NUM', _datum: y - x}); return; } env.s.push(err.throw('no numbers on top 2 elements of the stack... aborting')); } num_times_func(){ if(env.TOS() && env.TOS()._type == 'TC_NUM' && env.TOS2() && env.TOS2()._type == 'TC_NUM'){ env.s.push({_type: 'TC_NUM', _datum: env.s.pop()._datum * env.s.pop()._datum}); return; } env.s.push(err.throw('no numbers on top 2 elements of the stack... aborting')); } num_div_func(){ if(env.TOS() && env.TOS()._type == 'TC_NUM' && env.TOS2() && env.TOS2()._type == 'TC_NUM'){ let x = env.s.pop()._datum; let y = env.s.pop()._datum; env.s.push({_type: 'TC_NUM', _datum: y / x}); return; } env.s.push(err.throw('no numbers on top 2 elements of the stack... aborting')); } plus_func(){ eval.eval('f+'); } minus_func(){ eval.eval('n:-'); } times_func(){ eval.eval('n:*'); } division_func(){ eval.eval('n:/'); } module_func(){ eval.eval('n:%'); } string_plus_func(){ if(env.is_string(env.TOS()) || env.is_string(env.TOS2())){ if(env.is_num(env.TOS()) || env.is_num(env.TOS2()) || env.is_string(env.TOS()) || env.is_string(env.TOS2())){ const x= env.s.pop(); const y= env.s.pop(); env.s.push({"_type":"TC_STR","_datum":y._datum+x._datum}); return; } } env.s.push(err.throw("invalid arguments type")); } array_plus_func(){ if(env.is_list(env.TOS()) || env.is_list(env.TOS2())){ const x= env.s.pop(); const y= env.s.pop(); env.s.push({"_type":"TC_JSON","_datum":y._datum.concat(x._datum)}); return; } env.s.push(err.throw("invalid arguments type")); } array_at_func(){ if(env.is_num(env.TOS()) && env.is_list(env.TOS2())){ try{ var index=env.s.pop()._datum; var arr=env.s.pop()._datum; if(index<0) index=arr.length+index; if(index>=arr.length || index<0){ env.s.push(err.throw("invalid index bound")); return; } const value=arr[index]; const xval=env.adj_bool_val(value); env.s.push({"_type":env.guess_type(value), "_datum":xval}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type")); } array_set_at_func(){ if(env.TOS() && env.is_num(env.TOS2()) && env.is_list(env.s.look_at(2))){ try{ var value=env.s.pop()._datum; var index=env.s.pop()._datum; var arr=env.s.pop()._datum; if(index<0) index=arr.length+index; if(index>=arr.length || index<0){ env.s.push(err.throw("invalid index bound")); return; } arr[index]=value; env.s.push({"_type":"TC_JSON", "_datum":arr}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type")); } object_at_func(){ if(env.is_string(env.TOS()) && env.is_obj(env.TOS2())){ try{ var key=env.s.pop()._datum; var obj=env.s.pop()._datum; var value=obj[key]; if(value){ const xval=env.adj_bool_val(value); env.s.push({"_type":env.guess_type(value), "_datum":xval}); return; } env.s.push(err.throw("invalid object key")); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type")); } object_set_at_func(){ if(env.TOS() && env.is_string(env.TOS2()) && env.is_obj(env.s.look_at(2))){ try{ var value=env.s.pop()._datum; var key=env.s.pop()._datum; var obj=env.s.pop()._datum; obj[key]=value; env.s.push({"_type":'TC_JSON', "_datum":obj}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type")); } array_length_func(){ if(env.is_list(env.TOS())){ try{ var x=env.s.pop()._datum.length; env.s.push({"_type":"TC_NUM","_datum":x}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. TOS not a list")); } array_push_func(){ if(env.is_list(env.TOS2()) && env.TOS()){ try{ var value=env.s.pop()._datum; var arr=env.s.pop()._datum; arr.push(value); env.s.push({"_type":"TC_JSON","_datum":arr}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type.")); } array_pop_func(){ if(env.is_list(env.TOS())){ try{ var value=env.s.pop()._datum.pop(); const xval=env.adj_bool_val(value); env.s.push({"_type":env.guess_type(value), "_datum":xval}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. TOS not a list")); } object_keys_func(){ if(env.is_obj(env.TOS())){ try{ var x=env.s.pop()._datum; env.s.push({"_type":"TC_JSON","_datum":Object.keys(x)}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type.")); } object_values_func(){ if(env.is_obj(env.TOS())){ try{ var x=env.s.pop()._datum; env.s.push({"_type":"TC_JSON","_datum":Object.values(x)}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type.")); } string_split_func(){ if(env.TOS() && env.is_string(env.TOS2())){ try{ var x=env.s.pop(); var y=env.s.pop()._datum; var z; if(env.is_string(x)){ z=y.split(x._datum); } if(env.is_obj(x)){ z=y.split(x._datum.separator, x._datum.limit); } if(z){ env.s.push({"_type":"TC_JSON","_datum":z}); return; } }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type.")); } string_join_func(){ if(env.is_string(env.TOS()) && env.is_list(env.TOS2())){ try{ var separator=env.s.pop()._datum; var list=env.s.pop()._datum; env.s.push({"_type":"TC_STR","_datum":list.join(separator)}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type.")); } json_stringify_func(){ if(env.is_json(env.TOS())){ try{ env.s.push({"_type":"TC_STR","_datum":JSON5.stringify(env.s.pop()._datum)}); }catch(e){ env.s.push(err.throw(e)); } return; } env.s.push(err.throw("invalid arguments type.")); } json_parse_func(){ if(env.is_string(env.TOS())){ try{ env.s.push({"_type":"TC_JSON","_datum":JSON5.parse(env.s.pop()._datum)}); }catch(e){ env.s.push(err.throw(e)); } return; } env.s.push(err.throw("invalid arguments type.")); } string_at_func(){ if(env.is_num(env.TOS()) && env.is_string(env.TOS2())){ try{ var index=env.s.pop()._datum; var str=env.s.pop()._datum; if(index<0) index=str.length+index; env.s.push({"_type":"TC_STR","_datum":str[index]}); }catch(e){ env.s.push(err.throw(e)); } return; } env.s.push(err.throw("invalid arguments type.")); } string_set_at_func(){ if(env.is_string(env.TOS()) && env.is_num(env.TOS2()) && env.is_string(env.s.look_at(2))){ try{ var replacement=env.s.pop()._datum; var index=env.s.pop()._datum; var str=env.s.pop()._datum; if(index<0) index=str.length+index; var result=str.substr(0, index) + replacement+ str.substr(index + replacement.length); env.s.push({"_type":"TC_STR","_datum":result}); }catch(e){ env.s.push(err.throw(e)); } return; } env.s.push(err.throw("invalid arguments type.")); } equal_func(){ if(env.TOS() && env.TOS2()){ try{ var x=env.s.pop()._datum; var y=env.s.pop()._datum; env.s.push({"_type":"TC_BOOL","_datum":y===x ? 'T' : 'F'}); }catch(e){ env.s.push(err.throw(e)); } return; } env.s.push(err.throw("invalid arguments type.")); } eq_func(){ if(env.TOS() && env.TOS2()){ try{ var x=env.s.pop()._datum; var y=env.s.pop()._datum; env.s.push({"_type":"TC_BOOL","_datum":y==x ? 'T' : 'F'}); }catch(e){ env.s.push(err.throw(e)); } return; } env.s.push(err.throw("invalid arguments type.")); } num_minor_func(){ if(env.is_num(env.TOS()) && env.is_num(env.TOS2())){ try{ var x=env.s.pop()._datum; var y=env.s.pop()._datum; env.s.push({"_type":"TC_BOOL","_datum":y<x ? 'T' : 'F'}); }catch(e){ env.s.push(err.throw(e)); } return; } env.s.push(err.throw("invalid arguments type.")); } num_major_func(){ if(env.is_num(env.TOS()) && env.is_num(env.TOS2())){ try{ var x=env.s.pop()._datum; var y=env.s.pop()._datum; env.s.push({"_type":"TC_BOOL","_datum":y>x ? 'T' : 'F'}); }catch(e){ env.s.push(err.throw(e)); } return; } env.s.push(err.throw("invalid arguments type.")); } num_min_eq_func(){ if(env.is_num(env.TOS()) && env.is_num(env.TOS2())){ try{ var x=env.s.pop()._datum; var y=env.s.pop()._datum; env.s.push({"_type":"TC_BOOL","_datum":y<=x ? 'T' : 'F'}); }catch(e){ env.s.push(err.throw(e)); } return; } env.s.push(err.throw("invalid arguments type.")); } num_maj_eq_func(){ if(env.is_num(env.TOS()) && env.is_num(env.TOS2())){ try{ var x=env.s.pop()._datum; var y=env.s.pop()._datum; env.s.push({"_type":"TC_BOOL","_datum":y>=x ? 'T' : 'F'}); }catch(e){ env.s.push(err.throw(e)); } return; } env.s.push(err.throw("invalid arguments type.")); } delete_dict_func(){ if(env.TOS() && env.TOS()._type=='TC_STR'){ try{ env.delete(env.s.pop()._datum); }catch(e){ env.s.push(err.throw(e)); } return; } env.s.push(err.throw("invalid arguments type.")); } net_request_func(){ //async.... if(env.is_obj(env.TOS())){ try{ //let resp= await request(env.s.pop()._datum); let x=env.s.pop()._datum; let resp= request(x.method,x.url,x); //env.s.push({"_type":"TC_STR","_datum":resp}); env.s.push({"_type":"TC_STR","_datum":resp.body.toString('utf8')}); }catch(e){ env.s.push(err.throw(e)); } return; } env.s.push(err.throw("invalid arguments type.")); } included_func(){ if(env.is_string(env.TOS())){ try{ const arg= env.s.pop()._datum; const filename = loadfile.resolve_path(arg); var x = loadfile.loadsync(filename); eval.eval(x); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type")); } file_slurp_func(){ if(env.is_string(env.TOS())){ try{ const arg= env.s.pop()._datum; const filename = loadfile.resolve_path(arg); var x = loadfile.loadsync(filename); env.s.push({"_type":"TC_STR","_datum":x}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type")); } file_write_func(){ if(env.TOS() && env.TOS2() && env.is_string(env.TOS()) && env.is_string(env.TOS2())){ try{ const arg= env.s.pop()._datum; const filename = loadfile.resolve_path(arg); const data = env.s.pop()._datum; loadfile.writesync(filename, data); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. 2 Strings are expected.")); } file_append_func(){ if(env.TOS() && env.TOS2() && env.is_string(env.TOS()) && env.is_string(env.TOS2())){ try{ const arg= env.s.pop()._datum; const filename = loadfile.resolve_path(arg); const data = env.s.pop()._datum; loadfile.appendsync(filename, data); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. 2 Strings are expected.")); } file_exists_func(){ if(env.TOS() && env.is_string(env.TOS())){ try{ const arg= env.s.pop()._datum; const filename = loadfile.resolve_path(arg); let exists=loadfile.existssync(filename); env.s.push(env.set_bool_val(exists)); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a String is expected.")); } throw_func(){ if(env.TOS() && env.TOS()._type == 'TC_STR'){ env.s.push(err.throw(env.s.pop()._datum)); return; } if(env.TOS() && env.TOS()._type == 'TC_JSON'){ const err_arg = env.s.pop(); env.s.push(err.throw(err_arg._datum.msg, err_arg._datum.code)); return; } env.s.push(err.throw('invalid throw argument in TOS')); } require_js_func(){ if(env.TOS() && env.TOS()._type == 'TC_STR'){ try{ const arg= env.s.pop()._datum; const filename = loadfile.resolve_path(arg); var js=require(filename); env.s.push({"_type":env.guess_type(js),"_datum":js}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw('invalid request-js argument type')); } funcjs_exec_func(){ try{ if(env.TOS() && env.TOS()._type=='TC_LAMBDA_FUNC'){ eval.eval_parsed(env.s.pop()._datum); return; } if(env.TOS() && env.TOS()._type == 'TC_FUNC_JS'){ var x=env.s.pop()._datum; var arity=x.length; var args=[]; //log.info(arity); while(arity>0){ args.unshift(env.s.pop()._datum); arity--; } //log.info(args); var y=x.apply(null,args); //log.info(y); if(y) env.s.push({"_type":env.guess_type(y),"_datum":y}); return; } if(env.TOS() && env.TOS()._type == 'TC_STR' && env.TOS2() && env.TOS2()._type=='TC_JSON'){ var method=env.s.pop()._datum; var method_list=method.split("."); var x=env.s.pop()._datum; var funcall=x; for(var item of method_list){ funcall=funcall[item]; } //log.info(funcall); var arity=funcall.length; var args=[]; //log.info(arity); while(arity>0){ args.unshift(env.s.pop()._datum); arity--; } //log.info(args); var y=funcall.apply(x,args); //log.info(y); if(y) env.s.push({"_type":env.guess_type(y),"_datum":y}); return; } env.s.push(err.throw('invalid funcall-js argument type')); }catch(e){ env.s.push(err.throw(e)); } } handle_repl_func(){ err.handle_repl(); } handle_standard_func(){ err.handle_standard(); } regex_test_func(){ try{ if(env.is_obj(env.TOS()) && env.is_string(env.TOS2())){ var rex_obj = env.s.pop(),_datum; var str = env.s.pop()._datum; var my_rex = new RegExp(rex_obj.rex, rex_obj.flags); const result = my_rex.test(str); env.s.push( result ? env.true_obj() : env.false_obj() ); return; } if(env.is_string(env.TOS()) && env.is_string(env.TOS2())){ var rex = env.s.pop()._datum; var str = env.s.pop()._datum; var my_rex = new RegExp(rex); const result = my_rex.test(str); env.s.push( result ? env.true_obj() : env.false_obj() ); return; } env.s.push(err.throw('invalid regex test argument type')); }catch(e){ env.s.push(err.throw(e)); } } regex_exec_func(){ try{ if(env.is_obj(env.TOS()) && env.is_string(env.TOS2())){ var rex_obj = env.s.pop(),_datum; var str = env.s.pop()._datum; var my_rex = new RegExp(rex_obj.rex, rex_obj.flags); const result = my_rex.exec(str); env.s.push( result ? {"_type":"TC_JSON","_datum":result} : 0 ); return; } if(env.is_string(env.TOS()) && env.is_string(env.TOS2())){ var rex = env.s.pop()._datum; var str = env.s.pop()._datum; var my_rex = new RegExp(rex); const result = my_rex.exec(str); env.s.push( result ? {"_type":"TC_JSON","_datum":result} : 0 ); return; } env.s.push(err.throw('invalid regex exec argument type')); }catch(e){ env.s.push(err.throw(e)); } } regex_match_func(){ try{ if(env.is_obj(env.TOS()) && env.is_string(env.TOS2())){ var rex_obj = env.s.pop(),_datum; var str = env.s.pop()._datum; var my_rex = new RegExp(rex_obj.rex, rex_obj.flags); const result = str.match(my_rex); env.s.push( result ? {"_type":"TC_JSON","_datum":result} : 0 ); return; } if(env.is_string(env.TOS()) && env.is_string(env.TOS2())){ var rex = env.s.pop()._datum; var str = env.s.pop()._datum; var my_rex = new RegExp(rex); const result = str.match(my_rex); env.s.push( result ? {"_type":"TC_JSON","_datum":result} : 0 ); return; } env.s.push(err.throw('invalid regex match argument type')); }catch(e){ env.s.push(err.throw(e)); } } regex_search_func(){ try{ if(env.is_obj(env.TOS()) && env.is_string(env.TOS2())){ var rex_obj = env.s.pop(),_datum; var str = env.s.pop()._datum; var my_rex = new RegExp(rex_obj.rex, rex_obj.flags); const result = str.search(my_rex); env.s.push({"_type":"TC_NUM","_datum":result}); return; } if(env.is_string(env.TOS()) && env.is_string(env.TOS2())){ var rex = env.s.pop()._datum; var str = env.s.pop()._datum; var my_rex = new RegExp(rex); const result = str.search(my_rex); env.s.push({"_type":"TC_NUM","_datum":result}); return; } env.s.push(err.throw('invalid regex search argument type')); }catch(e){ env.s.push(err.throw(e)); } } regex_replace_func(){ try{ if(env.is_obj(env.TOS()) && env.is_string(env.TOS2()) && env.is_string(env.s.look_at(2))){ var rex_obj = env.s.pop(),_datum; var replace = env.s.pop()._datum; var str = env.s.pop()._datum; var my_rex = new RegExp(rex_obj.rex, rex_obj.flags); const result = str.replace(my_rex, replace); env.s.push({"_type":"TC_JSON","_datum":result}); return; } if(env.is_string(env.TOS()) && env.is_string(env.TOS2()) && env.is_string(env.s.look_at(2))){ var rex = env.s.pop()._datum; var replace = env.s.pop()._datum; var str = env.s.pop()._datum; var my_rex = new RegExp(rex); const result = str.replace(my_rex, replace); env.s.push({"_type":"TC_STR","_datum":result}); return; } env.s.push(err.throw('invalid regex replace argument type')); }catch(e){ env.s.push(err.throw(e)); } } array_shift_func(){ try{ if(env.is_list(env.TOS())){ let value = env.s.pop()._datum.shift(); const xval=env.adj_bool_val(value); env.s.push({"_type":env.guess_type(value), "_datum":xval}); return; } env.s.push(err.throw('invalid operation. TOS is not an list')); }catch(e){ env.s.push(err.throw(e)); } } array_unshift_func(){ try{ if(env.TOS() && env.is_list(env.TOS2())){ let value = env.s.pop()._datum; let array = env.s.pop()._datum; array.unshift(value); env.s.push({"_type":"TC_JSON", "_datum":array}); return; } env.s.push(err.throw('invalid operation. TOS2 is not an list')); }catch(e){ env.s.push(err.throw(e)); } } array_each_func(){ try{ if(env.TOS() && env.TOS()._type=='TC_LAMBDA_FUNC' && env.is_list(env.TOS2())){ let funcall = env.s.pop()._datum; let array = env.s.pop()._datum; //Vx€array, !!funcall while(array.length >0 ){ var value = array.shift(); const xval=env.adj_bool_val(value); env.s.push({"_type":env.guess_type(value), "_datum":xval}); eval.eval_parsed(funcall); } return; } env.s.push(err.throw('invalid arguments. TOS should be a LAMBDA function and TOS2 should be a list')); }catch(e){ env.s.push(err.throw(e)); } } parse_args_func(){ try{ if(env.is_list(env.TOS())){ const rx_double_dash = /^\-\-[a-zA-Z0-9]+/; const rx_single_dash = /^\-[a-zA-Z0-9]+/; const rx_no_dash = /^[^\-]/; const rx_two_dashes = /^\-\-/; let args = {argv:[]}; const params_data = env.s.pop()._datum; //log.info(params_data); let param_found=false; let test_col, is_dash; let argv = env.lookup('os:argv')._datum._datum; argv.shift(); argv.shift(); argv.shift(); //log.info(argv); while(argv.length > 0) { let item = argv.shift(); is_dash=0; // log.info(item); // if(rx_double_dash.test(item)){ // test_col= 1; // is_dash = true; // } // if(rx_single_dash.test(item)) { // test_col = 0; // is_dash = true; // } // if(is_dash) { // param_found = false; // for(var param_item of params_data){ // log.info(param_item[test_col]); // if(param_item[test_col]=== (test_col === 0)? item.match(rx_single_dash)[0] : item.match(rx_double_dash[0])){ // log.info('d: ',param_item); // param_found = true; // break; // } // } // //if ! invalid parameter // if(!param_found) log.info(`invalid parameter ${item}`); // } if(rx_double_dash.test(item)){ param_found = false; for(var param_item of params_data){ if(param_item[1]===item.match(rx_double_dash)[0]){ //log.info('dd: ',param_item); param_found = true; switch(param_item[2]){ case 'y': //log.info('ha param'); if(argv[0] && rx_no_dash.test(argv[0])){ args[param_item[1].replace(rx_two_dashes,'')] = argv.shift(); } else { log.info(`error, parameter ${item} needs value...`); //error needs param... } break; case 'n': //log.info('no param'); args[param_item[1].replace(rx_two_dashes,'')] = true; break; case '?': //log.info('opt param'); if(argv[0] && rx_no_dash.test(argv[0])){ args[param_item[1].replace(rx_two_dashes,'')] = argv[0]; }else{ args[param_item[1].replace(rx_two_dashes,'')] = true; } break; default: break; } break; } } //if ! invalid parameter if(!param_found) log.info(`invalid parameter ${item}`); }else if(rx_single_dash.test(item)) { param_found= false; for(var param_item of params_data){ if(param_item[0]===item.match(rx_single_dash)[0]){ //log.info('sd: ',param_item); param_found = true; switch(param_item[2]){ case 'y': //log.info('ha param'); if(argv[0] && rx_no_dash.test(argv[0])){ args[param_item[1].replace(rx_two_dashes,'')] = argv.shift(); } else { log.info(`error, parameter ${item} needs value...`); //error needs param... } break; case 'n': //log.info('no param'); args[param_item[1].replace(rx_two_dashes,'')] = true; break; case '?': //log.info('opt param'); if(argv[0] && rx_no_dash.test(argv[0])){ args[param_item[1].replace(rx_two_dashes,'')] = argv[0]; }else{ args[param_item[1].replace(rx_two_dashes,'')] = true; } break; default: break; } break; } } if(!param_found) log.info(`invalid parameter ${item}`); }else { //else{ //normal argv... args.argv.push(item); } } //log.info(args); env.s.push({"_type":"TC_JSON", "_datum":args}); return; } env.s.push(err.throw('invalid arguments. TOS should be a list')); }catch(e){ env.s.push(err.throw(e)); } } await_func(){ if(env.TOS() && env.TOS()._type=== 'TC_PROMISE'){ try{ env.s.pop()._datum.then(x => { env.s.push({"_type":env.guess_type(x), "_datum":x}); }); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a Promise was expected.")); } string_format_func(){ if(env.TOS() && env.TOS2() && env.is_string(env.TOS2()) && env.is_list(env.TOS())){ try{ const args_list=env.s.pop()._datum; const fmt=env.s.pop()._datum; env.s.push({"_type":"TC_STR", "_datum":vsprintf(fmt,args_list)}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a String and a List in TOS and TOS2 was expected.")); } string_length_func(){ if(env.TOS() && env.is_string(env.TOS())){ try{ const str=env.s.pop()._datum; env.s.push({"_type":"TC_NUM", "_datum":str.length}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a String was expected.")); } string_to_upper_func(){ if(env.TOS() && env.is_string(env.TOS())){ try{ const str=env.s.pop()._datum; env.s.push({"_type":"TC_STR", "_datum":str.toUpperCase()}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a String was expected.")); } string_to_lower_func(){ if(env.TOS() && env.is_string(env.TOS())){ try{ const str=env.s.pop()._datum; env.s.push({"_type":"TC_STR", "_datum":str.toLowerCase()}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a String was expected.")); } xml_load_func(){ if(env.TOS() && env.is_string(env.TOS())){ try{ const str=env.s.pop()._datum; const $ = cheerio.load(str); env.s.push({"_type":env.guess_type($), "_datum":$}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a String was expected.")); } xml_loadXML_func(){ if(env.TOS() && env.is_string(env.TOS())){ try{ const str=env.s.pop()._datum; const $ = cheerio.load(str, {xmlMode: true}); env.s.push({"_type":env.guess_type($), "_datum":$}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a String was expected.")); } xml_select_func(){ if(env.TOS() && env.TOS2() && env.TOS2()._type=="TC_FUNC_JS" && env.is_string(env.TOS())){ try{ const arg=env.s.pop()._datum; const $=env.s.pop()._datum; const resp=$(arg); env.s.push({"_type":env.guess_type(resp), "_datum":resp}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a XML object was expected.")); } xml_get_text_func(){ if(env.TOS() && env.is_json(env.TOS())){ try{ const $=env.s.pop()._datum; const resp=$.text(); env.s.push({"_type":env.guess_type(resp), "_datum":resp}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a JSON object was expected.")); } xml_get_html_func(){ if(env.TOS() && env.is_json(env.TOS())){ try{ const $=env.s.pop()._datum; const resp=$.html(); env.s.push({"_type":env.guess_type(resp), "_datum":resp}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a JSON object was expected.")); } xml_get_attr_func(){ if(env.TOS() && env.is_string(env.TOS()) && env.TOS2() && env.is_json(env.TOS2())){ try{ const attr=env.s.pop()._datum; const $=env.s.pop()._datum; const resp=$.attr(attr); env.s.push({"_type":env.guess_type(resp), "_datum":resp}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a JSON object was expected.")); } xml_has_class_func(){ if(env.TOS() && env.is_string(env.TOS()) && env.TOS2() && env.is_json(env.TOS2())){ try{ const attr=env.s.pop()._datum; const $=env.s.pop()._datum; const resp=$.hasClass(attr); env.s.push(env.set_bool_val(resp)); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a JSON object was expected.")); } xml_get_val_func(){ if(env.TOS() && env.is_json(env.TOS())){ try{ const $=env.s.pop()._datum; const resp=$.val(); env.s.push({"_type":env.guess_type(resp), "_datum":resp}); return; }catch(e){ env.s.push(err.throw(e)); return; } } env.s.push(err.throw("invalid arguments type. a JSON object was expected.")); } populate_repl(){ env.set('handle',{_type: 'TC_NATIVE_FUNC', _datum: this.handle_repl_func}, 'TC_WORD'); } populate(){ env.set('pippo',{_type: 'TC_NATIVE_FUNC', _datum: this.test_func}, 'TC_WORD'); env.set('bye',{_type: 'TC_NATIVE_FUNC', _datum: this.bye_func}, 'TC_WORD'); env.set('noop',{_type: 'TC_NATIVE_FUNC', _datum: this.noop_func}, 'TC_WORD'); env.set('.s',{_type: 'TC_NATIVE_FUNC', _datum: this.print_stack_func}, 'TC_WORD'); env.set('.e',{_type: 'TC_NATIVE_FUNC', _datum: this.print_env_func}, 'TC_WORD'); env.set('words',{_type: 'TC_NATIVE_FUNC', _datum: this.print_words_func}, 'TC_WORD'); env.set('emit',{_type: 'TC_NATIVE_FUNC', _datum: this.emit_func}, 'TC_WORD'); env.set('.',{_type: 'TC_NATIVE_FUNC', _datum: this.print_tos_func}, 'TC_WORD'); env.set('.?',{_type: 'TC_NATIVE_FUNC', _datum: this.print_debug_tos_func}, 'TC_WORD'); env.set('!',{_type: 'TC_NATIVE_FUNC', _datum: this.assign_var_func}, 'TC_WORD'); env.set('@',{_type: 'TC_NATIVE_FUNC', _datum: this.read_var_func}, 'TC_WORD'); env.set('not',{_type: 'TC_NATIVE_FUNC', _datum: this.not_func}, 'TC_WORD'); env.set('and',{_type: 'TC_NATIVE_FUNC', _datum: this.and_func}, 'TC_WORD'); env.set('or',{_type: 'TC_NATIVE_FUNC', _datum: this.or_func}, 'TC_WORD'); env.set('is_num',{_type: 'TC_NATIVE_FUNC', _datum: this.is_num_func}, 'TC_WORD'); env.set('is_string',{_type: 'TC_NATIVE_FUNC', _datum: this.is_string_func}, 'TC_WORD'); env.set('is_list',{_type: 'TC_NATIVE_FUNC', _datum: this.is_list_func}, 'TC_WORD'); env.set('is_falsy',{_type: 'TC_NATIVE_FUNC', _datum: this.is_falsy_func}, 'TC_WORD'); env.set('dup',{_type: 'TC_NATIVE_FUNC', _datum: this.dup_func}, 'TC_WORD'); env.set('swap',{_type: 'TC_NATIVE_FUNC', _datum: this.swap_func}, 'TC_WORD'); env.set('drop',{_type: 'TC_NATIVE_FUNC', _datum: this.drop_func}, 'TC_WORD'); env.set('ndrop',{_type: 'TC_NATIVE_FUNC', _datum: this.ndrop_func}, 'TC_WORD'); env.set('nbye',{_type: 'TC_NATIVE_FUNC', _datum: this.nbye_func}, 'TC_WORD'); env.set('over',{_type: 'TC_NATIVE_FUNC', _datum: this.over_func}, 'TC_WORD'); env.set('n:+',{_type: 'TC_NATIVE_FUNC', _datum: this.num_plus_func}, 'TC_WORD'); env.set('n:-',{_type: 'TC_NATIVE_FUNC', _datum: this.num_minus_func}, 'TC_WORD'); env.set('n:*',{_type: 'TC_NATIVE_FUNC', _datum: this.num_times_func}, 'TC_WORD'); env.set('n:/',{_type: 'TC_NATIVE_FUNC', _datum: this.num_div_func}, 'TC_WORD'); env.set('+',{_type: 'TC_NATIVE_FUNC', _datum: this.plus_func}, 'TC_WORD'); env.set('-',{_type: 'TC_NATIVE_FUNC', _datum: this.minus_func}, 'TC_WORD'); env.set('*',{_type: 'TC_NATIVE_FUNC', _datum: this.times_func}, 'TC_WORD'); env.set('/',{_type: 'TC_NATIVE_FUNC', _datum: this.division_func}, 'TC_WORD'); env.set('%',{_type: 'TC_NATIVE_FUNC', _datum: this.module_func}, 'TC_WORD'); env.set('handle',{_type: 'TC_NATIVE_FUNC', _datum: this.handle_standard_func}, 'TC_WORD'); env.set('throw',{_type: 'TC_NATIVE_FUNC', _datum: this.throw_func}, 'TC_WORD'); env.set('s:+',{_type: 'TC_NATIVE_FUNC', _datum: this.string_plus_func}, 'TC_WORD'); env.set('a:+',{_type: 'TC_NATIVE_FUNC', _datum: this.array_plus_func}, 'TC_WORD'); env.set('included',{_type: 'TC_NATIVE_FUNC', _datum: this.included_func}, 'TC_WORD'); env.set('a:@',{_type: 'TC_NATIVE_FUNC', _datum: this.array_at_func}, 'TC_WORD'); env.set('a:!',{_type: 'TC_NATIVE_FUNC', _datum: this.array_set_at_func}, 'TC_WORD'); env.set('m:@',{_type: 'TC_NATIVE_FUNC', _datum: this.object_at_func}, 'TC_WORD'); env.set('m:!',{_type: 'TC_NATIVE_FUNC', _datum: this.object_set_at_func}, 'TC_WORD'); env.set('a:len',{_type: 'TC_NATIVE_FUNC', _datum: this.array_length_func}, 'TC_WORD'); env.set('a:push',{_type: 'TC_NATIVE_FUNC', _datum: this.array_push_func}, 'TC_WORD'); env.set('a:pop',{_type: 'TC_NATIVE_FUNC', _datum: this.array_pop_func}, 'TC_WORD'); env.set('m:keys',{_type: 'TC_NATIVE_FUNC', _datum: this.object_keys_func}, 'TC_WORD'); env.set('m:values',{_type: 'TC_NATIVE_FUNC', _datum: this.object_values_func}, 'TC_WORD'); env.set('s:split',{_type: 'TC_NATIVE_FUNC', _datum: this.string_split_func}, 'TC_WORD'); env.set('s:join',{_type: 'TC_NATIVE_FUNC', _datum: this.string_join_func}, 'TC_WORD'); env.set('j:stringify',{_type: 'TC_NATIVE_FUNC', _datum: this.json_stringify_func}, 'TC_WORD'); env.set('j:parse',{_type: 'TC_NATIVE_FUNC', _datum: this.json_parse_func}, 'TC_WORD'); env.set('s:@',{_type: 'TC_NATIVE_FUNC', _datum: this.string_at_func}, 'TC_WORD'); env.set('s:!',{_type: 'TC_NATIVE_FUNC', _datum: this.string_set_at_func}, 'TC_WORD'); env.set('=',{_type: 'TC_NATIVE_FUNC', _datum: this.equal_func}, 'TC_WORD'); env.set('===',{_type: 'TC_NATIVE_FUNC', _datum: this.equal_func}, 'TC_WORD'); env.set('==',{_type: 'TC_NATIVE_FUNC', _datum: this.eq_func}, 'TC_WORD'); env.set('<',{_type: 'TC_NATIVE_FUNC', _datum: this.num_minor_func}, 'TC_WORD'); env.set('>',{_type: 'TC_NATIVE_FUNC', _datum: this.num_major_func}, 'TC_WORD'); env.set('<=',{_type: 'TC_NATIVE_FUNC', _datum: this.num_min_eq_func}, 'TC_WORD'); env.set('>=',{_type: 'TC_NATIVE_FUNC', _datum: this.num_maj_eq_func}, 'TC_WORD'); env.set('f:slurp',{_type: 'TC_NATIVE_FUNC', _datum: this.file_slurp_func}, 'TC_WORD'); env.set('f:write',{_type: 'TC_NATIVE_FUNC', _datum: this.file_write_func}, 'TC_WORD'); env.set('f:append',{_type: 'TC_NATIVE_FUNC', _datum: this.file_append_func}, 'TC_WORD'); env.set('f:exists',{_type: 'TC_NATIVE_FUNC', _datum: this.file_exists_func}, 'TC_WORD'); env.set('net:request',{_type: 'TC_NATIVE_FUNC', _datum: this.net_request_func}, 'TC_WORD'); env.set('j:require-js',{_type: 'TC_NATIVE_FUNC', _datum: this.require_js_func}, 'TC_WORD'); env.set('!!',{_type: 'TC_NATIVE_FUNC', _datum: this.funcjs_exec_func}, 'TC_WORD'); env.set('G:delete',{_type: 'TC_NATIVE_FUNC', _datum: this.delete_dict_func}, 'TC_WORD'); env.set('rx:test',{_type: 'TC_NATIVE_FUNC', _datum: this.regex_test_func}, 'TC_WORD'); env.set('rx:exec',{_type: 'TC_NATIVE_FUNC', _datum: this.regex_exec_func}, 'TC_WORD'); env.set('rx:match',{_type: 'TC_NATIVE_FUNC', _datum: this.regex_match_func}, 'TC_WORD'); env.set('rx:search',{_type: 'TC_NATIVE_FUNC', _datum: this.regex_search_func}, 'TC_WORD'); env.set('rx:replace',{_type: 'TC_NATIVE_FUNC', _datum: this.regex_replace_func}, 'TC_WORD'); env.set('a:shift',{_type: 'TC_NATIVE_FUNC', _datum: this.array_shift_func}, 'TC_WORD'); env.set('a:unshift',{_type: 'TC_NATIVE_FUNC', _datum: this.array_unshift_func}, 'TC_WORD'); env.set('a:each',{_type: 'TC_NATIVE_FUNC', _datum: this.array_each_func}, 'TC_WORD'); env.set('os:parse-args',{_type: 'TC_NATIVE_FUNC', _datum: this.parse_args_func}, 'TC_WORD'); env.set('await',{_type: 'TC_NATIVE_FUNC', _datum: this.await_func}, 'TC_WORD'); env.set('s:format',{_type: 'TC_NATIVE_FUNC', _datum: this.string_format_func}, 'TC_WORD'); env.set('s:len',{_type: 'TC_NATIVE_FUNC', _datum: this.string_length_func}, 'TC_WORD'); env.set('s:to_upper',{_type: 'TC_NATIVE_FUNC', _datum: this.string_to_upper_func}, 'TC_WORD'); env.set('s:to_lower',{_type: 'TC_NATIVE_FUNC', _datum: this.string_to_lower_func}, 'TC_WORD'); env.set('xml:loadDOM',{_type: 'TC_NATIVE_FUNC', _datum: this.xml_load_func}, 'TC_WORD'); env.set('xml:loadXML',{_type: 'TC_NATIVE_FUNC', _datum: this.xml_loadXML_func}, 'TC_WORD'); env.set('xml:$',{_type: 'TC_NATIVE_FUNC', _datum: this.xml_select_func}, 'TC_WORD'); env.set('xml:get_text',{_type: 'TC_NATIVE_FUNC', _datum: this.xml_get_text_func}, 'TC_WORD'); env.set('xml:get_html',{_type: 'TC_NATIVE_FUNC', _datum: this.xml_get_html_func}, 'TC_WORD'); env.set('xml:get_attr',{_type: 'TC_NATIVE_FUNC', _datum: this.xml_get_attr_func}, 'TC_WORD'); env.set('xml:has_class',{_type: 'TC_NATIVE_FUNC', _datum: this.xml_has_class_func}, 'TC_WORD'); env.set('xml:get_val',{_type: 'TC_NATIVE_FUNC', _datum: this.xml_get_val_func}, 'TC_WORD'); } }; module.exports = new NativeLib();