var chalang_compiler = (function() { var w2o = { "int4": 0, binary: 2, int1: 3, int2: 4, int0: 12, print: 10, "return": 11, nop: 12, fail: 13, drop: 20, dup: 21, swap: 22, tuck: 23, rot: 24, ddup: 25, tuckn: 26, pickn: 27, ">r": 30, "r>": 31, "r@": 32, hash: 40, verify_sig: 41, verify_account_sig: 42, "+": 50, "-": 51, "*": 52, "/": 53, ">": 54, "<": 55, "^": 56, rem: 57, "==": 58, "=2": 59, "if": 70, "else": 71, then: 72, not: 80, and: 81, or: 82, xor: 83, band: 84, bor: 85, bxor: 86, stack_size: 90, id2balance: 91, pub2addr: 92, total_coins: 93, height: 94, slash: 95, gas: 96, ram: 97, id2pub: 98, oracle: 99, many_vars: 100, many_funs: 101, ":": 110, def: 114, ";": 111, recurse: 112, call: 113, "!":120, "@": 121, cons: 130, car: 131, nil: 132, "++": 134, split: 135, reverse: 136, is_list: 137 }; function remove_comments(s) { // single-line erlang style comments % comment s = s.replace( /%[^\n]*(\n|$)/g, "\n"); // multi-line ( forth style comments ) s = s.replace( /\([^)]*(\n|$|\))/g, ""); // single-line forth style comments ; comment s = s.replace( /\;[^\n]*(\n|$)/g, ";\n"); return(s); }; function clean_whitespace(page){ return(page.replace(/\s+/g, " ")); }; function add_spaces(page){ //add spaces to either side of the 7 special characters. page = page.replace( /[\(\)\[\]\:\;\,]/g, function(x){ return(" "+x+" ")}); return(page); }; var vars_regex = /var(\s+[^\s\;]+)+\s*;/g; function get_vars(page){ var vars = {}; var n = 1; //grab between "var" and ";" var p2 = page.match(vars_regex); if(p2){ p2.map(function(p3){ p3 .match(/[^\s]+/g) //remove "var" and ";" from the ends .slice(1, -1) .map(function(x){ vars[x] = n; n += 1; }); }); }; return(vars); }; function remove_vars(page){ return(page.replace(vars_regex, "")); }; var string_regex = /\.\" [^\"]*\"/g; //example: `." hello world"` function parse_strings(page){ return(page.replace( string_regex, parse_string)); }; function parse_string(string){ string = string.slice(3, -1); //console.log(string); return( " binary " //.concat(string.length.toString()) //.concat(" ") .concat(btoa(string)) .concat(" ")); }; function doit(s){ var page0 = remove_comments(s); //console.log(page0); var page1 = add_spaces(page0); //console.log(page1); var vars = get_vars(page1); //console.log(JSON.stringify(vars)); var page2 = remove_vars(page1); //console.log(page2); var page3 = clean_whitespace(page2); //console.log(page3); var page3_5 = parse_strings(page3); //console.log(page3_5); var page4 = do_macros(page3_5); //console.log(page4); var db = {vars:vars,funs:{}}; var fv = get_funs(page4, db); var page5 = remove_functions(page4); //console.log(page5); var ops = to_opcodes(page5, fv); //console.log(ops.code); return(ops.code); }; function remove_functions(page){ var words = page.match(/[^\s]+/g); for(var i = 0; ir var square ; def r@ ! r@ 0 + @ r@ 0 + @ * ; square ! 4 square @ r@ 1 + >r call r> drop ` return(test(code)); }; function test0(){ var map_code = ` ( a b c multiline comment ) var foo bar ; %variable declaration foo 4 ! %storing a value in the variable macro [ nil ; forth style comment macro , swap cons ; macro ] , reverse ; : square dup * ; : map2 car swap r@ call rot cons swap nil == if drop drop reverse else drop recurse call then ; macro map >r nil swap map2 call r> drop ; macro test [ 5,6, 7] square print print print map [25, 36, 49] == >r drop drop r> ; test `; return(test(map_code)); } function test(code){ var s = doit(code); console.log(JSON.stringify(s)); var d = chalang_object.data_maker(1000, 1000, 50, 1000, [], [], chalang_object.new_state(0, 0)); var x = chalang_object.run5(s, d); console.log(JSON.stringify(x.stack)); return(x.stack); }; return({ test2: test2, test1: test1, test0: test0, test: test, doit: doit, ops: w2o, four_bytes: four_bytes }); })();