-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathholy.js
1 lines (1 loc) · 52.1 KB
/
holy.js
1
let hc={modes:{HolyNode:!1},files:{stdin:'',stdout:'',stderr:''},lexer:{char:'',line:1,index:0},parser:{index:0},symtab:{idle:!1,global:[],scoped:[],prototypes:[],class:[],types:[]}};const stderr=eval("(value) =>"+(hc.modes.HolyNode?void 0:'(document.getElementById("stdout/stderr").value = value) && (document.getElementById("stdout/stderr").style.color = "red")')),stdin=()=>eval(hc.modes.HolyNode?void 0:'document.getElementById("stdin")'),stdout=e=>(document.getElementById("stdout/stderr").value=e)&&(document.getElementById("stdout/stderr").style.color="black");export const holyc_web_run=async()=>stdout(await output(parser(await lexer(init_hc()))));export const holy_node_idle=async e=>(hc.symtab.idle=hc.modes.HolyNode=!0)&&await output(parser(await lexer(init_hc(e))));export const holy_node_script=async e=>(hc.modes.HolyNode=!0)&&await output(parser(await lexer(init_hc(e))));export const holy_script=async e=>document.getElementById("stdout/stderr").innerText=await output(parser(await lexer(init_hc(e))));class AstNode{token;next;left;right;constructor(e){this.type=e}}class Ast{next;ast}class Token{constructor(e,t,n){this.id=e,this.type=t,this.line=n}}const token_type={number:1,str:2,id:3,add:4,sub:5,div:6,mul:7,semi:8,lbrace:9,rbrace:10,i0:11,u0:12,i8:13,u8:14,i16:15,u16:16,i32:17,u32:18,i64:19,u64:20,f64:21,rparen:22,lparen:23,call:24,comma:25,assig:26,less:27,big:28,for:29,increment:30,decrement:31,assingsum:32,assingsub:33,assingdiv:34,assingmul:35,if:36,or:37,and:38,not:39,else:40,true:41,false:42,equal:43,return:44,bigequal:45,lessequal:46,bool:47,class:48,dot:49,classExp:50,define:51,include:52,js:53,jscode:54},token_cases=[{char:"/",render:e=>{if(e.files.stdin[e.lexer.index]==="/"){for(;e.files.stdin[e.lexer.index++]&&e.files.stdin[e.lexer.index]!=="\n";);return"{comment}"}return e.files.stdin[e.lexer.index]==="="?(e.lexer.index++,new Token("/=",token_type.assingdiv,e.lexer.line)):new Token("/",token_type.div,e.lexer.line)}},{char:"'",render:e=>lex_simple_quote_string(e)},{char:'"',render:e=>lex_string(e)},{char:"+",render:e=>e.files.stdin[e.lexer.index]==="+"&&e.lexer.index++&&new Token("++",token_type.increment,e.lexer.line)||e.files.stdin[e.lexer.index]==="="&&e.lexer.index++&&new Token("+=",token_type.assingsum,e.lexer.line)||new Token("+",token_type.add,e.lexer.line)},{char:"-",render:e=>e.files.stdin[e.lexer.index]==="-"&&e.lexer.index++&&new Token("--",token_type.increment,e.lexer.decrement)||e.files.stdin[e.lexer.index]==="="&&e.lexer.index++&&new Token("-=",token_type.assingsub,e.lexer.line)||new Token("-",token_type.sub,e.lexer.line)},{char:"*",render:e=>e.files.stdin[e.lexer.index]==="="&&e.lexer.index++&&new Token("*=",token_type.assingmul,e.lexer.line)||new Token("*",token_type.mul,e.lexer.line)},{char:";",render:e=>new Token(";",token_type.semi,e.lexer.line)},{char:".",render:e=>new Token(".",token_type.dot,e.lexer.line)},{char:"{",render:e=>new Token("{",token_type.rbrace,e.lexer.line)},{char:"}",render:e=>new Token("}",token_type.lbrace,e.lexer.line)},{char:"(",render:e=>new Token("(",token_type.rparen,e.lexer.line)},{char:")",render:e=>new Token(")",token_type.lparen,e.lexer.line)},{char:",",render:e=>new Token(",",token_type.comma,e.lexer.line)},{char:"!",render:e=>new Token("!",token_type.not,e.lexer.line)},{char:"=",render:e=>e.files.stdin[e.lexer.index]==="="&&e.lexer.index++&&new Token("==",token_type.equal,e.lexer.line)||new Token("=",token_type.assig,e.lexer.line)},{char:"<",render:e=>e.files.stdin[e.lexer.index]==="="&&e.lexer.index++&&new Token("<=",token_type.lessequal,e.lexer.line)||new Token("<",token_type.less,e.lexer.line)},{char:">",render:e=>e.files.stdin[e.lexer.index]==="="&&e.lexer.index++&&new Token(">=",token_type.bigequal,e.lexer.line)||new Token(">",token_type.big,e.lexer.line)},{char:"&",render:e=>e.files.stdin[e.lexer.index]==="&"&&e.lexer.index++&&new Token("&&",token_type.and,e.lexer.line)},{char:"|",render:e=>e.files.stdin[e.lexer.index]==="|"&&e.lexer.index++&&new Token("||",token_type.or,e.lexer.line)}],token_keywords=[{id:"for",type:token_type.for},{id:"class",type:token_type.class},{id:"if",type:token_type.if},{id:"else",type:token_type.else},{id:"return",type:token_type.return},{id:"TRUE",type:token_type.true},{id:"FALSE",type:token_type.false},{id:"Bool",type:token_type.bool},{id:"I0",type:token_type.i0},{id:"U0",type:token_type.u0},{id:"I8",type:token_type.i8},{id:"U8",type:token_type.u8},{id:"I16",type:token_type.i16},{id:"U16",type:token_type.u16},{id:"I32",type:token_type.i32},{id:"U32",type:token_type.u32},{id:"I64",type:token_type.i64},{id:"U64",type:token_type.u64},{id:"F64",type:token_type.f64},{id:"#define",type:token_type.define},{id:"#include",type:token_type.include},{id:"js",type:token_type.js}],is_alpha=e=>/^[A-Z0-9_#]$/i.test(e),is_number=e=>/^[0-9]$/.test(e),is_ignored=e=>(e==="\n"&&hc.lexer.line++,/[ \n\t]/.test(e)),lex_include=async e=>{const t=lex_alpha(e);return t.id!=="#include"?t:(e.lexer.index+=2,e.files.stdin=await fetch(lex_string(e).id).then(e=>e.text()).then(e=>e)+e.files.stdin.slice(e.lexer.index,e.files.stdin.length),e.lexer.index=0,"{include}")},lex_alpha=e=>{let t='';do t+=e.lexer.char;while(is_alpha(e.lexer.char=e.files.stdin[e.lexer.index++]))return e.lexer.index--,new Token(t,token_keywords.find(e=>e.id===t)?.type||token_type.id,e.lexer.line)},lex_number=e=>{let t='';do t+=e.lexer.char;while(is_number(e.lexer.char=e.files.stdin[e.lexer.index++]))return e.lexer.index--,new Token(t,token_type.number,e.lexer.line)},lex_simple_quote_string=e=>{e.lexer.char=e.files.stdin[e.lexer.index++];let t='';do!e.lexer.char&&lexer_error({id:"EOF",line:e.lexer.line}),t+=e.lexer.char;while((e.lexer.char=e.files.stdin[e.lexer.index++])!=="'")return new Token(t,token_type.str,e.lexer.line)},lex_string=e=>{e.lexer.char=e.files.stdin[e.lexer.index++];let t='';do!e.lexer.char&&lexer_error({id:"EOF",line:e.lexer.line}),t+=e.lexer.char;while((e.lexer.char=e.files.stdin[e.lexer.index++])!=='"')return new Token(t,token_type.str,e.lexer.line)},lexer_lex=async e=>{for(;(e.lexer.char=e.files.stdin[e.lexer.index++])&&e.lexer.char;){let t='';if(is_ignored(e.lexer.char))continue;if(e.lexer.char==="#"){if(t=await lex_include(e),t==="{include}")continue;return t}if(is_number(e.lexer.char))return lex_number(e);if(is_alpha(e.lexer.char))return lex_alpha(e);if(t=token_cases.find(t=>t.char===e.lexer.char)?.render(e),t==="{comment}")continue;if(t)return t;lexer_error({id:e.lexer.char,line:e.lexer.line})}},init_hc=e=>{if(stderr&&stderr(''),stdin()?.value&&(hc.files.stdin=stdin().value)||(hc.files.stdin=e),hc.files.stdout='',hc.files.stderr='',hc.lexer.char='',hc.lexer.index=0,hc.lexer.line=1,hc.parser.index=0,!hc.symtab.idle&&(hc.symtab.types=[]),!hc.symtab.idle&&(hc.symtab.global=[]),!hc.symtab.idle&&(hc.symtab.prototypes=[]),!hc.symtab.idle&&(hc.symtab.class=[]),!hc.symtab.idle&&(hc.symtab.scoped=[]),!hc.files.stdin){hc.files.stderr+="Compile failure\nLexer: nothing to compile\n";try{throw stderr(hc.files.stderr)}catch{throw new Error(hc.files.stderr)}}return hc},lexer=async e=>{let t=[];for(;1;){const n=await lexer_lex(e);if(!n)break;if(t.push(n),n.type===token_type.js&&e.files.stdin[e.lexer.index+1]==="{"){e.lexer.index++,t.push(new Token("{",token_type.rbrace,e.lexer.line)),e.lexer.index++,e.lexer.char=e.files.stdin[e.lexer.index];let n='';do e.lexer.char=e.files.stdin[e.lexer.index++],!e.lexer.char&&lexer_error({id:"EOF",line:e.lexer.line}),n+=e.lexer.char;while(e?.files?.stdin.substring(e.lexer.index,e.lexer.index+2)!=="};")t.push(new Token(n,token_type.jscode,e.lexer.line)),t.push(new Token("}",token_type.lbrace,e.lexer.line)),t.push(new Token(";",token_type.semi,e.lexer.line)),e.lexer.index+=2}}return t},get_symtab=e=>{for(let t=0;t<hc.symtab.global.length;++t)if(hc.symtab.global[t].id===e.id)return t},get_prototype=e=>{for(let t=0;t<hc.symtab.prototypes.length;++t)if(hc.symtab.prototypes[t].id===e.id)return t},get_class=e=>{for(let t=0;t<hc.symtab.class.length;++t)if(hc.symtab.class[t].id===e.id)return t;return-1},lexer_error=e=>{hc.files.stderr=`Compile failure\nLexer: '${e.id}' unexpected token in line ${e.line}\n`;try{throw stderr(hc.files.stderr)}catch{throw new Error(hc.files.stderr)}},internal_error=e=>{hc.files.stderr=`Compile failure\nInternal error: '${e}'`;try{throw stderr(hc.files.stderr)}catch{throw new Error(hc.files.stderr)}},parser_error=e=>{hc.files.stderr=`Compile failure\nParser: '${e.id}' unexpected token in line ${e.line}\n`;try{throw stderr(hc.files.stderr)}catch{throw new Error(hc.files.stderr)}},check_symtab=(e,t)=>{symtab_contain(e[hc.parser.index])!==t&&parser_error(e[hc.parser.index])},list_eat=(e,t)=>{try{if(e[hc.parser.index].type!==t)throw new Error;hc.parser.index++}catch{parser_error(e[hc.parser.index]?e[hc.parser.index]:e[hc.parser.index-1])}},symtab_contain=e=>!!hc.symtab.global.filter(t=>t.id===e.id).length,check_token=(e,t,n)=>{try{return e[t].type===n}catch{parser_error(e[t-1])}},check_ast_type=(e,t)=>{switch(t){case"id":return e===token_type.id;case"data_type":return e===token_type.i0||e===token_type.u0||e===token_type.i8||e===token_type.u8||e===token_type.i16||e===token_type.u16||e===token_type.i32||e===token_type.u32||e===token_type.i64||e===token_type.u64||e===token_type.f64||e===token_type.bool;case"assignment_operator":return e===token_type.assingdiv||e===token_type.assingmul||e===token_type.assingsub||e===token_type.assingsum}},is_dtype=(e,t)=>{try{let n=e[t].type;return n===token_type.i0||n===token_type.u0||n===token_type.i8||n===token_type.u8||n===token_type.i16||n===token_type.u16||n===token_type.i32||n===token_type.u32||n===token_type.i64||n===token_type.u64||n===token_type.f64||n===token_type.bool||hc.symtab.types.findIndex(n=>n.id===e[t].id)>-1}catch{parser_error(e[t-1])}},is_logicalop=(e,t)=>{try{let n=e[t].type;return n===token_type.big||n===token_type.less||n===token_type.or||n===token_type.and||n===token_type.not||n===token_type.equal||n===token_type.bigequal||n===token_type.lessequal}catch{parser_error(e[t-1])}},is_mathop=(e,t)=>{try{let n=e[t].type;return n===token_type.add||n===token_type.sub||n===token_type.div||n===token_type.mul||n===token_type.increment||n===token_type.decrement}catch{parser_error(e[t-1])}},is_assingop=(e,t)=>{try{let n=e[t].type;return n===token_type.assingdiv||n===token_type.assingmul||n===token_type.assingsub||n===token_type.assingsum||n===token_type.assig}catch{parser_error(e[t-1])}},list_eat_type=e=>{is_dtype(e,hc.parser.index)?hc.parser.index++:parser_error(e[hc.parser.index])},list_eat_logical=e=>{is_logicalop(e,hc.parser.index)?hc.parser.index++:parser_error(e[hc.parser.index])},list_eat_math=e=>{is_mathop(e,hc.parser.index)?hc.parser.index++:parser_error(e[hc.parser.index])},list_eat_compassing=e=>{is_assingop(e,hc.parser.index)?hc.parser.index++:parser_error(e[hc.parser.index])},parser_parse_class=e=>{let t=new AstNode(token_type.class);t.token=e[hc.parser.index],list_eat(e,token_type.class),check_symtab(e,!1),get_class(e[hc.parser.index])>-1?lexer_error(e[hc.parser.index]):hc.symtab.class.push(e[hc.parser.index]);const s=get_class(e[hc.parser.index]);hc.symtab.class[s].content=[],t.left=new AstNode(token_type.id),t.left.token=e[hc.parser.index],list_eat(e,token_type.id),list_eat(e,token_type.rbrace);let n=hc.parser.index;if(t.right=parser_parse_class_vars(e,s+1),list_eat(e,token_type.lbrace),check_token(e,hc.parser.index,token_type.semi))list_eat(e,token_type.semi);else{let s=[];for(;e[n++]&&e[n].type!==token_type.lbrace;)check_token(e,n,token_type.id)&&s.push({...e[n],value:0});hc.symtab.types.findIndex(t=>t.id===e[hc.parser.index].id)>-1&&lexer_error(e[hc.parser.index]),hc.symtab.types.push({...e[hc.parser.index],value:s,classType:!0}),t.left.left=new AstNode(token_type.id),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.id),list_eat(e,token_type.semi)}return t},parser_parse_logical_exp=e=>{if(check_token(e,hc.parser.index,token_type.semi)||check_token(e,hc.parser.index,token_type.comma)||check_token(e,hc.parser.index,token_type.lparen))return null;let t;return check_token(e,hc.parser.index-1,token_type.id)||check_token(e,hc.parser.index-1,token_type.number)||check_token(e,hc.parser.index-1,token_type.true)||check_token(e,hc.parser.index-1,token_type.false)?is_logicalop(e,hc.parser.index)?(t=new AstNode(e[hc.parser.index]?.type),t.token=e[hc.parser.index],list_eat_logical(e)):(check_token(e,hc.parser.index-1,token_type.id)||check_token(e,hc.parser.index-1,token_type.number)||check_token(e,hc.parser.index-1,token_type.true)||check_token(e,hc.parser.index-1,token_type.false))&&(t=new AstNode(e[hc.parser.index]?.type),t.token=e[hc.parser.index],list_eat_math(e)):is_logicalop(e,hc.parser.index-1)?check_token(e,hc.parser.index,token_type.not)?(t=new AstNode(token_type.not),t.token=e[hc.parser.index],list_eat(e,token_type.not)):check_token(e,hc.parser.index,token_type.id)?(check_symtab(e,!0),t=new AstNode(token_type.id),t.token=e[hc.parser.index],list_eat(e,token_type.id)):check_token(e,hc.parser.index,token_type.true)?(t=new AstNode(token_type.true),t.token={id:1,line:e[hc.parser.index].line,type:token_type.number},list_eat(e,token_type.true)):check_token(e,hc.parser.index,token_type.false)?(t=new AstNode(token_type.number),t.token={id:0,line:e[hc.parser.index].line,type:token_type.number},list_eat(e,token_type.false)):(t=new AstNode(token_type.number),t.token=e[hc.parser.index],list_eat(e,token_type.number)):check_token(e,hc.parser.index,token_type.id)?(check_symtab(e,!0),t=new AstNode(token_type.id),t.token=e[hc.parser.index],list_eat(e,token_type.id)):check_token(e,hc.parser.index,token_type.true)?(t=new AstNode(token_type.true),t.token={id:1,line:e[hc.parser.index].line,type:token_type.number},list_eat(e,token_type.true)):check_token(e,hc.parser.index,token_type.false)?(t=new AstNode(token_type.number),t.token={id:0,line:e[hc.parser.index].line,type:token_type.number},list_eat(e,token_type.false)):(t=new AstNode(token_type.number),t.token=e[hc.parser.index],list_eat(e,token_type.number)),t.right=parser_parse_logical_exp(e),t},parser_parse_exp=(e,s,n)=>{if(check_token(e,hc.parser.index,token_type.semi)||check_token(e,hc.parser.index,token_type.comma)||s&&check_token(e,hc.parser.index,token_type.lparen))return null;let t;if(hc.symtab.prototypes.find(t=>t.id===e[hc.parser.index].id)&&!check_token(e,hc.parser.index-1,token_type.number)&&!check_token(e,hc.parser.index-1,token_type.id))return parser_parse_call(e);if(check_token(e,hc.parser.index-1,token_type.id)||check_token(e,hc.parser.index-1,token_type.number)||check_token(e,hc.parser.index-1,token_type.classExp))is_mathop(e,hc.parser.index)?(check_token(e,hc.parser.index+1,token_type.id)||check_token(e,hc.parser.index+1,token_type.number))&&(t=new AstNode(e[hc.parser.index]?.type),t.token=e[hc.parser.index],list_eat_math(e)):is_assingop(e,hc.parser.index)?(t=new AstNode(e[hc.parser.index]?.type),t.token=e[hc.parser.index],list_eat_compassing(e)):(t=new AstNode(token_type.assig),t.token=e[hc.parser.index],list_eat(e,token_type.assig));else if(check_token(e,hc.parser.index-1,token_type.assig)||is_assingop(e,hc.parser.index-1))if(check_token(e,hc.parser.index,token_type.id)){let s;if(n?(s=hc.symtab.prototypes[n-1].args.find(t=>t.id===e[hc.parser.index].id),s||(s=hc.symtab.scoped[n-1]?.find(t=>t.id===e[hc.parser.index].id))):s=hc.symtab.prototypes.find(t=>t.id===e[hc.parser.index].id),!s&&check_symtab(e,!0),check_token(e,hc.parser.index+1,token_type.dot)){let n=[];for(;e[hc.parser.index].type===token_type.id;)e[hc.parser.index].type===token_type.id&&n.push(e[hc.parser.index].id),hc.parser.index+=2;hc.parser.index-=2,e[hc.parser.index].id=n.join("."),e[hc.parser.index].type=token_type.classExp,t=new AstNode(token_type.classExp),t.token=e[hc.parser.index],list_eat(e,token_type.classExp)}else t=new AstNode(token_type.id),t.token=e[hc.parser.index],list_eat(e,token_type.id)}else{if(!n){const t=get_symtab(e[hc.parser.index-2]);t!=void 0&&(hc.symtab.global[t]={id:e[hc.parser.index-2].id,line:e[hc.parser.index-2].line,value:e[hc.parser.index].id})}check_token(e,hc.parser.index,token_type.true)?(hc.symtab.global[get_symtab(e[hc.parser.index-2])].value=1,e[hc.parser.index].type=token_type.number,e[hc.parser.index].id=1,t=new AstNode(token_type.number),t.token=e[hc.parser.index],list_eat(e,token_type.number)):check_token(e,hc.parser.index,token_type.false)?(hc.symtab.global[get_symtab(e[hc.parser.index-2])].value=0,e[hc.parser.index].type=token_type.number,e[hc.parser.index].id=0,t=new AstNode(token_type.number),t.token=e[hc.parser.index],list_eat(e,token_type.number)):(t=new AstNode(token_type.number),t.token=e[hc.parser.index],list_eat(e,token_type.number))}else if(is_mathop(e,hc.parser.index-1)||check_token(e,hc.parser.index-1,token_type.return))if(check_token(e,hc.parser.index,token_type.id)){let s;n?(s=hc.symtab.prototypes[n-1].args.find(t=>t.id===e[hc.parser.index].id),s||(s=hc.symtab.scoped[n-1]?.find(t=>t.id===e[hc.parser.index].id))):s=hc.symtab.prototypes.find(t=>t.id===e[hc.parser.index].id),!s&&check_symtab(e,!0),t=new AstNode(token_type.id),t.token=e[hc.parser.index],list_eat(e,token_type.id)}else t=new AstNode(token_type.number),t.token=e[hc.parser.index],list_eat(e,token_type.number);else if(check_token(e,hc.parser.index,token_type.id)){let s;n?(s=hc.symtab.prototypes[n-1].args.find(t=>t.id===e[hc.parser.index].id),s||(s=hc.symtab.scoped[n-1]?.find(t=>t.id===e[hc.parser.index].id))):s=hc.symtab.prototypes.find(t=>t.id===e[hc.parser.index].id),!s&&check_symtab(e,!0),t=new AstNode(token_type.id),t.token=e[hc.parser.index],list_eat(e,token_type.id)}else check_token(e,hc.parser.index,token_type.semi)?parser_error(e[hc.parser.index]):(t=new AstNode(token_type.comma),t.token=e[hc.parser.index],list_eat(e,token_type.comma));return t.right=parser_parse_exp(e,s,n),t},parser_parse_str_args=e=>{if(check_token(e,hc.parser.index,token_type.semi))return null;let t;if(check_token(e,hc.parser.index,token_type.id)||check_token(e,hc.parser.index,token_type.number))if(check_token(e,hc.parser.index+1,token_type.dot)){let n=[];for(;e[hc.parser.index].type!==token_type.semi;)e[hc.parser.index].type===token_type.id&&n.push(e[hc.parser.index].id),hc.parser.index++;hc.parser.index--,e[hc.parser.index].id=n.join("."),e[hc.parser.index].type=token_type.classExp,t=new AstNode(token_type.classExp),t.token=e[hc.parser.index],list_eat(e,token_type.classExp)}else t=new AstNode(e[hc.parser.index]?.type),t.token=e[hc.parser.index],list_eat(e,e[hc.parser.index].type);else check_token(e,hc.parser.index,token_type.str)?(t=new AstNode(token_type.str),t.token=e[hc.parser.index],list_eat(e,token_type.str)):t=parser_parse_exp(e,!1);return check_token(e,hc.parser.index,token_type.assig)?(t.left=new AstNode(token_type.assig),t.left.token=e[hc.parser.index],list_eat(e,token_type.assig),t.left.right=parser_parse_exp(e,!1)):check_token(e,hc.parser.index,token_type.semi)||(t.left=new AstNode(token_type.comma),t.left.token=e[hc.parser.index],list_eat(e,token_type.comma)),t.right=parser_parse_str_args(e),t},parser_parse_inline_str=e=>{if(check_token(e,hc.parser.index,token_type.semi))return null;let t=new AstNode(token_type.str);return t.token=e[hc.parser.index],list_eat(e,token_type.str),check_token(e,hc.parser.index,token_type.semi)||(t.next=new AstNode(token_type.comma),t.next.token=e[hc.parser.index],list_eat(e,token_type.comma),check_token(e,hc.parser.index,token_type.str)||parser_error(e[hc.parser.index])),t.right=parser_parse_inline_str(e),t},parser_parse_return=(e,n)=>{let t=new AstNode(token_type.return);return t.token=e[hc.parser.index],list_eat(e,token_type.return),t.right=parser_parse_exp(e,!1,n),t.left=new AstNode(token_type.semi),t.left.token=e[hc.parser.index],list_eat(e,token_type.semi),t},parser_parse_str=e=>{let t=new AstNode(token_type.str);return t.token=e[hc.parser.index],list_eat(e,token_type.str),check_token(e,hc.parser.index,token_type.semi)?(t.left=new AstNode(token_type.semi),t.left.token=e[hc.parser.index],list_eat(e,token_type.semi)):(t.left=new AstNode(token_type.comma),t.left.token=e[hc.parser.index],list_eat(e,token_type.comma),check_token(e,hc.parser.index,token_type.str)?(t.right=parser_parse_inline_str(e),t.left.left=new AstNode(token_type.semi),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.semi)):(t.left.right=parser_parse_str_args(e),t.left.left=new AstNode(token_type.semi),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.semi))),t},parser_parse_args=(e=[])=>{if(check_token(e,hc.parser.index,token_type.lparen))return null;let t=new AstNode(e[hc.parser.index]?.type);return t.token=e[hc.parser.index],list_eat_type(e),t.next=new AstNode(token_type.id),t.next.token=e[hc.parser.index],list_eat(e,token_type.id),check_token(e,hc.parser.index,token_type.assig)&&(t.next.next=new AstNode(token_type.assig),t.next.next.token=e[hc.parser.index],list_eat(e,token_type.assig),check_token(e,hc.parser.index,token_type.number)?(t.next.next.next=new AstNode(token_type.number),t.next.next.next.token=e[hc.parser.index],list_eat(e,token_type.number)):(t.next.next.next=new AstNode(token_type.str),t.next.next.next.token=e[hc.parser.index],list_eat(e,token_type.str))),check_token(e,hc.parser.index,token_type.lparen)||(t.next.next=new AstNode(token_type.comma),t.next.next.token=e[hc.parser.index],list_eat(e,token_type.comma)),t.right=parser_parse_args(e),t},parser_parse_call_args=(e,n,o,s)=>{if(hc.symtab.prototypes[n].args.length===s)return null;let t;if(hc.symtab.prototypes[n].args[s]?.id?check_token(e,hc.parser.index,token_type.id)?(check_symtab(e,!0),t=new AstNode(token_type.id),t.token=e[hc.parser.index],list_eat(e,token_type.id),is_mathop(e,hc.parser.index)&&t):check_token(e,hc.parser.index,token_type.number)&&(t=new AstNode(token_type.number),t.token=e[hc.parser.index],list_eat(e,token_type.number)):check_token(e,hc.parser.index,token_type.id)?(check_symtab(e,!0),t=new AstNode(token_type.id),t.token=e[hc.parser.index],list_eat(e,token_type.id)):(t=new AstNode(token_type.number),t.token=e[hc.parser.index],list_eat(e,token_type.number)),s<hc.symtab.prototypes[n].args.length-1){if(t)if(check_token(e,hc.parser.index,token_type.comma))t.left=new AstNode(token_type.comma),t.left.token=e[hc.parser.index],list_eat(e,token_type.comma);else return t;else if(o||check_token(e,hc.parser.index,token_type.comma))t=new AstNode(token_type.comma),t.token=e[hc.parser.index],list_eat(e,token_type.comma);else if(!o||check_token(e,hc.parser.index,token_type.rparen))return t}else return t;return t.right=parser_parse_call_args(e,n,o,++s),t},parser_parse_call=e=>{hc.symtab.prototypes.findIndex(t=>t.id===e[hc.parser.index].id)<0&&check_symtab(e,!0);const n=get_prototype(e[hc.parser.index]);let t=new AstNode(token_type.call);if(t.token=e[hc.parser.index],list_eat(e,token_type.id),hc.symtab.prototypes[n].args.length){const s=hc.symtab.prototypes[n].args.filter(e=>e.id===void 0).length;if(check_token(e,hc.parser.index,token_type.semi)&&!s)return t.left=new AstNode(token_type.semi),t.left.token=e[hc.parser.index],list_eat(e,token_type.semi),t;t.left=new AstNode(token_type.rparen),t.left.token=e[hc.parser.index],list_eat(e,token_type.rparen),check_token(e,hc.parser.index,token_type.str)&&!s&&e[hc.parser.index].id==="*"?(t.left.left=new AstNode(token_type.str),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.str)):hc.symtab.prototypes[n].args.length&&(t.right=parser_parse_call_args(e,n,s,0)),t.left.left=new AstNode(token_type.lparen),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.lparen)}else check_token(e,hc.parser.index,token_type.rparen)&&(t.left=new AstNode(token_type.rparen),t.left.token=e[hc.parser.index],list_eat(e,token_type.rparen),check_token(e,hc.parser.index,token_type.str)&&e[hc.parser.index].id==="*"&&(t.left.next=new AstNode(token_type.str),t.left.next.token=e[hc.parser.index],list_eat(e,token_type.str)),t.left.left=new AstNode(token_type.lparen),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.lparen));return t},parser_parse_inline_vars=(e,o,n)=>{if(check_token(e,hc.parser.index,token_type.semi)&&!check_token(e,hc.parser.index-1,token_type.comma))return null;check_symtab(e,!1);let t=e[hc.parser.index],s=new AstNode(token_type.id);return s.token=e[hc.parser.index],list_eat(e,token_type.id),check_token(e,hc.parser.index,token_type.assig)?(o?hc.symtab.class[o-1].content.push({...t,value:0}):n?hc.symtab.scoped[n-1].push({...t,value:0}):hc.symtab.global.push({...t,value:0}),s.left=parser_parse_exp(e,!1,n),check_token(e,hc.parser.index,token_type.semi)||(s.left.left=new AstNode(token_type.comma),s.left.left.token=e[hc.parser.index],list_eat(e,token_type.comma))):check_token(e,hc.parser.index,token_type.semi)?o?hc.symtab.class[o-1].content.push({...t,value:0}):n?hc.symtab.scoped[n-1].push({...t,value:0}):hc.symtab.global.push({...t,value:0}):(o?hc.symtab.class[o-1].content.push({...t,value:0}):n?hc.symtab.scoped[n-1].push({...t,value:0}):hc.symtab.global.push({...t,value:0}),s.left=new AstNode(token_type.comma),s.left.token=e[hc.parser.index],list_eat(e,token_type.comma)),s.right=parser_parse_inline_vars(e,o,n),s},parser_parse_class_vars=(e,n)=>{if(check_token(e,hc.parser.index,token_type.lbrace))return null;let t=new AstNode(e[hc.parser.index]?.type);return t.token=e[hc.parser.index],list_eat_type(e),t.left=parser_parse_inline_vars(e,n),t.left.left=new AstNode(token_type.semi),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.semi),t.right=parser_parse_class_vars(e,n),t},parser_parse_class_var_exp=e=>{let t=new AstNode(token_type.id);return t.token=e[hc.parser.index],list_eat(e,token_type.id),check_token(e,hc.parser.index,token_type.assig)?t:(t.right=new AstNode(token_type.dot),t.right.token=e[hc.parser.index],list_eat(e,token_type.dot),t.right.right=parser_parse_class_var_exp(e),t)},parser_parse_class_assig=(e,s)=>{let n=hc.parser.index,i=[];for(;e[n].type!==token_type.assig&&e[++n];)e[n].type===token_type.id&&i.push(e[n].id);let o=!1;s&&hc.symtab.prototypes[prototypeIndex]?.args?.findIndex(t=>t.id===e[hc.parser.index].id)<0?parser_error(e[hc.parser.index]):(check_symtab(e,!0),s=hc.symtab.global.findIndex(t=>t.id===e[hc.parser.index].id),o=!0);let t=parser_parse_class_var_exp(e);return t.left=new AstNode(token_type.assig),t.left.token=e[hc.parser.index],list_eat(e,token_type.assig),o?t.left.left=parser_parse_exp(e,!1):t.left.left=parser_parse_exp(e,!1,s),t.left.left.left=new AstNode(token_type.semi),t.left.left.left.token=e[hc.parser.index],list_eat(e,token_type.semi),t},parser_parse_id=(e,n)=>{if(!hc.symtab.types.find(t=>t.id===e[hc.parser.index].id)&&check_token(e,hc.parser.index,token_type.id)){if(is_assingop(e,hc.parser.index+1)){let t=parser_parse_exp(e,!1,n);return t.left=new AstNode(token_type.semi),t.left.token=e[hc.parser.index],list_eat(e,token_type.semi),t}if(check_token(e,hc.parser.index+1,token_type.increment)||check_token(e,hc.parser.index+1,token_type.decrement))return parser_parse_prepostfix(e,!1);if(check_token(e,hc.parser.index+1,token_type.dot))return parser_parse_class_assig(e,n);let t=parser_parse_call(e);return list_eat(e,token_type.semi),t}let t=new AstNode(e[hc.parser.index]?.type);t.token=e[hc.parser.index],list_eat_type(e),n&&hc.symtab.prototypes[n-1]?.args?.find(t=>t.id===e[hc.parser.index].id)||n&&hc.symtab.scoped[n-1]?.find(t=>t.id===e[hc.parser.index].id)?parser_error(e[hc.parser.index]):check_symtab(e,!1);const s=e[hc.parser.index];if(t.left=new AstNode(token_type.id),t.left.token=e[hc.parser.index],list_eat(e,token_type.id),check_token(e,hc.parser.index,token_type.semi))n?(!hc.symtab.scoped[n-1]&&(hc.symtab.scoped[n-1]=[]),hc.symtab.scoped[n-1].push({...s,value:0})):hc.symtab.global.push({...s,value:0}),t.left.left=new AstNode(token_type.semi),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.semi);else if(check_token(e,hc.parser.index,token_type.comma))n?(!hc.symtab.scoped[n-1]&&(hc.symtab.scoped[n-1]=[]),hc.symtab.scoped[n-1].push({...s,value:0})):hc.symtab.global.push({...s,value:0}),t.left.left=new AstNode(token_type.comma),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.comma),t.right=parser_parse_inline_vars(e),t.left.left.left=new AstNode(token_type.semi),t.left.left.left.token=e[hc.parser.index],list_eat(e,token_type.semi);else if(check_token(e,hc.parser.index,token_type.assig))n?(!hc.symtab.scoped[n-1]&&(hc.symtab.scoped[n-1]=[]),hc.symtab.scoped[n-1].push({...s,value:0})):hc.symtab.global.push({...s,value:0}),t.right=parser_parse_exp(e,!1,n),check_token(e,hc.parser.index,token_type.comma)?(t.left.left=new AstNode(token_type.comma),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.comma),t.left.right=parser_parse_inline_vars(e,null,n),t.left.left.left=new AstNode(token_type.semi),t.left.left.left.token=e[hc.parser.index],list_eat(e,token_type.semi)):(t.left.left=new AstNode(token_type.semi),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.semi));else if(!n){const s=e[hc.parser.index-1].id;let o={id:s,type:e[hc.parser.index-2].type,args:void 0,return:void 0};t.left.left=new AstNode(token_type.rparen),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.rparen);let n=hc.parser.index;t.left.left.right=parser_parse_args(e);let i=[];for(;n<hc.parser.index;){let t={id:e[n+1].id,type:e[n].type,value:void 0};e[n+2].type===token_type.assig&&(t.value=e[n+3].id,n+=2),n+=2,e[n].type===token_type.comma&&n++,i.push(t)}o.args=i,hc.symtab.prototypes.push(o);const a=hc.symtab.prototypes.findIndex(e=>e.id===s)+1;t.left.left.left=new AstNode(token_type.lparen),t.left.left.left.token=e[hc.parser.index],list_eat(e,token_type.lparen),t.left.left.left.left=new AstNode(token_type.rbrace),t.left.left.left.left.token=e[hc.parser.index],list_eat(e,token_type.rbrace),t.right=parser_parse_block(e,a),t.left.left.left.left.left=new AstNode(token_type.lbrace),t.left.left.left.left.left.token=e[hc.parser.index],list_eat(e,token_type.lbrace)}return t},parser_parse_prepostfix=(e,s,n)=>{let t;if(is_mathop(e,hc.parser.index)){if(check_token(e,hc.parser.index,token_type.increment)?(t=new AstNode(token_type.increment),t.token=e[hc.parser.index],list_eat_math(e)):(t=new AstNode(token_type.decrement),t.token=e[hc.parser.index],list_eat_math(e)),n){let t=hc.symtab.prototypes[n]?.args?.findIndex(t=>t.id===e[hc.parser.index]);t<0&&(t=hc.symtab.scoped[n].findIndex(t=>t.id===e[hc.parser.index]),t<0&&parser_error(e[hc.parser.index]))}else check_symtab(e,!0);t.right=new AstNode(token_type.id),t.right.token=e[hc.parser.index],list_eat(e,token_type.id)}else{if(n){let t=hc.symtab.prototypes[n]?.args?.findIndex(t=>t.id===e[hc.parser.index]);t<0&&(t=hc.symtab.scoped[n].findIndex(t=>t.id===e[hc.parser.index]),t<0&&parser_error(e[hc.parser.index]))}else check_symtab(e,!0);t=new AstNode(token_type.id),t.token=e[hc.parser.index],list_eat(e,token_type.id),check_token(e,hc.parser.index,token_type.increment)?(t.right=new AstNode(token_type.increment),t.right.token=e[hc.parser.index],list_eat_math(e)):(t.right=new AstNode(token_type.decrement),t.right.token=e[hc.parser.index],list_eat_math(e))}return s||(t.left=new AstNode(token_type.semi),t.left.token=e[hc.parser.index],list_eat(e,token_type.semi)),t},parser_parse_ifelse=(e,n)=>{let t=new AstNode(token_type.if);return t.token=e[hc.parser.index],list_eat(e,token_type.if),t.left=new AstNode(token_type.rparen),t.left.token=e[hc.parser.index],list_eat(e,token_type.rparen),check_token(e,hc.parser.index,token_type.number)?(t.left.left=new AstNode(token_type.number),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.number)):check_token(e,hc.parser.index,token_type.true)?(t.left.left=new AstNode(token_type.true),t.left.left.token={id:1,line:e[hc.parser.index].line,type:token_type.number},list_eat(e,token_type.true)):check_token(e,hc.parser.index,token_type.false)?(t.left.left=new AstNode(token_type.number),t.left.left.token={id:0,line:e[hc.parser.index].line,type:token_type.number},list_eat(e,token_type.false)):(!hc.symtab.prototypes[n-1]?.args?.find(t=>t.id===e[hc.parser.index].id)&&!hc.symtab.scoped[n-1]?.find(t=>t.id===e[hc.parser.index].id)&&check_symtab(e,!0),t.left.left=new AstNode(token_type.id),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.id)),t.right=parser_parse_logical_exp(e,n),t.left.left.left=new AstNode(token_type.lparen),t.left.left.left.token=e[hc.parser.index],list_eat(e,token_type.lparen),t.left.left.next=new AstNode(token_type.rbrace),t.left.left.next.token=e[hc.parser.index],list_eat(e,token_type.rbrace),t.left.left.left.right=parser_parse_block(e,n),t.left.left.next.next=new AstNode(token_type.lbrace),t.left.left.next.next.token=e[hc.parser.index],list_eat(e,token_type.lbrace),hc.parser.index<e.length&&check_token(e,hc.parser.index,token_type.else)&&(t.left.left.left.left=new AstNode(token_type.else),t.left.left.left.left.token=e[hc.parser.index],list_eat(e,token_type.else),check_token(e,hc.parser.index,token_type.if)?t.left.left.left.next=parser_parse_ifelse(e):(t.left.left.left.next=new AstNode(token_type.rbrace),t.left.left.left.next.token=e[hc.parser.index],list_eat(e,token_type.rbrace),t.left.left.left.left.right=parser_parse_block(e,n),t.left.left.left.next.next=new AstNode(token_type.lbrace),t.left.left.left.next.next.token=e[hc.parser.index],list_eat(e,token_type.lbrace))),t},parser_parse_for=(e,n)=>{let t=new AstNode(token_type.for);if(t.token=e[hc.parser.index],list_eat(e,token_type.for),t.next=new AstNode(token_type.rparen),t.next.token=e[hc.parser.index],list_eat(e,token_type.rparen),n){let t=hc.symtab.prototypes[n]?.args?.findIndex(t=>t.id===e[hc.parser.index]);t<0&&(t=hc.symtab.scoped[n].findIndex(t=>t.id===e[hc.parser.index]),t<0&&parser_error(e[hc.parser.index]))}else check_symtab(e,!0);if(t.left=new AstNode(token_type.id),t.left.token=e[hc.parser.index],list_eat(e,token_type.id),t.right=parser_parse_exp(e,!1,n),t.left.left=new AstNode(token_type.semi),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.semi),n){let t=hc.symtab.prototypes[n]?.args?.findIndex(t=>t.id===e[hc.parser.index]);t<0&&(t=hc.symtab.scoped[n].findIndex(t=>t.id===e[hc.parser.index]),t<0&&parser_error(e[hc.parser.index]))}else check_symtab(e,!0);return t.left.left.left=new AstNode(token_type.id),t.left.left.left.token=e[hc.parser.index],list_eat(e,token_type.id),t.left.left.left.left=new AstNode(e[hc.parser.index]?.type),t.left.left.left.left.token=e[hc.parser.index],list_eat_logical(e),t.left.left.left.left.left=new AstNode(token_type.number),t.left.left.left.left.left.token=e[hc.parser.index],list_eat(e,token_type.number),t.left.left.left.left.left.left=new AstNode(token_type.semi),t.left.left.left.left.left.left.token=e[hc.parser.index],list_eat(e,token_type.semi),check_token(e,hc.parser.index,token_type.increment)||check_token(e,hc.parser.index,token_type.decrement)||check_token(e,hc.parser.index+1,token_type.decrement)||check_token(e,hc.parser.index+1,token_type.increment)?t.left.left.left.left.left.left.left=parser_parse_prepostfix(e,!0,n):(check_symtab(e,!0),t.left.left.left.left.left.left.next=new AstNode(token_type.id),t.left.left.left.left.left.left.next.token=e[hc.parser.index],list_eat(e,token_type.id),t.left.left.left.left.left.left.left=parser_parse_exp(e,!0,n)),t.left.left.left.left.left.left.left.next=new AstNode(token_type.lparen),t.left.left.left.left.left.left.left.next.token=e[hc.parser.index],list_eat(e,token_type.lparen),t.left.left.left.left.left.left.next=new AstNode(token_type.rbrace),t.left.left.left.left.left.left.next.token=e[hc.parser.index],list_eat(e,token_type.rbrace),t.left.left.left.left.left.left.right=parser_parse_block(e,n),t.left.left.left.left.left.left.next.next=new AstNode(token_type.lbrace),t.left.left.left.left.left.left.next.next.token=e[hc.parser.index],list_eat(e,token_type.lbrace),t},parser_parse_include=e=>{let t=new AstNode(token_type.include);return t.token=e[hc.parser.index],list_eat(e,token_type.include),t.left=new AstNode(token_type.str),t.left.token=e[hc.parser.index],list_eat(e,token_type.str),t},parser_parse_js=e=>{let t=new AstNode(token_type.js);return t.token=e[hc.parser.index],list_eat(e,token_type.js),t.left=new AstNode(token_type.rbrace),t.left.token=e[hc.parser.index],list_eat(e,token_type.rbrace),t.left.left=new AstNode(token_type.jscode),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.jscode),t.left.left.left=new AstNode(token_type.lbrace),t.left.left.left.token=e[hc.parser.index],list_eat(e,token_type.lbrace),t.left.left.left.left=new AstNode(token_type.semi),t.left.left.left.left.token=e[hc.parser.index],list_eat(e,token_type.semi),t},parser_parse_define=e=>{let t=new AstNode(token_type.define);t.token=e[hc.parser.index],list_eat(e,token_type.define);let s=e[hc.parser.index];check_symtab(e,!1),t.left=new AstNode(token_type.id),t.left.token=e[hc.parser.index],list_eat(e,token_type.id);let n;return check_token(e,hc.parser.index,token_type.number)?(n=e[hc.parser.index].id,t.left.left=new AstNode(token_type.number),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.number)):check_token(e,hc.parser.index,token_type.true)?(n=e[hc.parser.index].id,t.left.left=new AstNode(token_type.true),t.left.left.token={id:1,line:e[hc.parser.index].line,type:token_type.number},list_eat(e,token_type.true)):check_token(e,hc.parser.index,token_type.false)?(n=e[hc.parser.index].id,t.left.left=new AstNode(token_type.number),t.left.left.token={id:0,line:e[hc.parser.index].line,type:token_type.number},list_eat(e,token_type.false)):(n=e[hc.parser.index].id,t.left.left=new AstNode(token_type.str),t.left.left.token=e[hc.parser.index],list_eat(e,token_type.str)),hc.symtab.global.push({...s,value:n}),t},parser_parse_block=(e,n)=>{if(check_token(e,hc.parser.index,token_type.lbrace))return null;let t;switch(e[hc.parser.index].type){case token_type.bool:case token_type.i0:case token_type.u0:case token_type.i8:case token_type.u8:case token_type.i16:case token_type.u16:case token_type.i32:case token_type.u32:case token_type.i64:case token_type.u64:case token_type.f64:case token_type.id:t=parser_parse_id(e,n);break;case token_type.increment:case token_type.decrement:t=parser_parse_prepostfix(e,!1);break;case token_type.str:t=parser_parse_str(e);break;case token_type.for:t=parser_parse_for(e,n);break;case token_type.if:t=parser_parse_ifelse(e,n);break;case token_type.return:t=parser_parse_return(e,n);break;case token_type.class:t=parser_parse_class(e);break;default:parser_error(e[hc.parser.index])}return t.next=parser_parse_block(e,n),t},parser_parse=e=>{if(!e[hc.parser.index])return null;let t=new Ast;const n=e[hc.parser.index].type;switch(n){case token_type.bool:case token_type.i0:case token_type.u0:case token_type.i8:case token_type.u8:case token_type.i16:case token_type.u16:case token_type.i32:case token_type.u32:case token_type.i64:case token_type.u64:case token_type.f64:case token_type.id:t.ast=parser_parse_id(e);break;case token_type.define:t.ast=parser_parse_define(e);break;case token_type.js:t.ast=parser_parse_js(e);break;case token_type.include:t.ast=parser_parse_include(e);break;case token_type.increment:case token_type.decrement:t.ast=parser_parse_prepostfix(e,!1);break;case token_type.str:t.ast=parser_parse_str(e);break;case token_type.for:t.ast=parser_parse_for(e);break;case token_type.if:t.ast=parser_parse_ifelse(e);break;case token_type.class:t.ast=parser_parse_class(e);break;default:parser_error(e[hc.parser.index])}return t.next=parser_parse(e),t},parser=e=>e&&parser_parse(e),output_out_math_exp=(n,e)=>{let t=n;for(;e;){switch(e.type){case token_type.div:e.right.token.type===token_type.number?t/=parseInt(e.right.token.id):t/=parseInt(hc.symtab.global[get_symtab(e.right.token)].value);break;case token_type.mul:e.right.token.type===token_type.number?t*=parseInt(e.right.token.id):t*=parseInt(hc.symtab.global[get_symtab(e.right.token)].value);break;case token_type.add:e.right.token.type===token_type.number?t+=parseInt(e.right.token.id):t+=parseInt(hc.symtab.global[get_symtab(e.right.token)].value);break;case token_type.sub:e.right.token.type===token_type.number?t-=parseInt(e.right.token.id):t-=parseInt(hc.symtab.global[get_symtab(e.right.token)].value);break}if(e?.right?.right)e=e.right.right;else break;if(e.type!==token_type.add&&e.type!==token_type.sub&&e.type!==token_type.div&&e.type!==token_type.mul)break}return t},output_out_logical_exp=(s,i,a)=>{let o,e,t={number:0,boolean:!1};if(!i&&s.left.left.token.type===token_type.not?(o=s.right.token,e=s.right.right):i?i&&s.right.token.type===token_type.not?(o=s.right.right.token,e=s.right.right.right):i&&(o=s.right.token,e=s.right.right):(o=s.left.left.token,e=s.right),o.type===token_type.id){let e='';(e=hc.symtab.prototypes[a]?.args?.find(e=>e.id===o.id))?t.number=parseInt(e.value):(e=hc.symtab.scoped[a]?.find(e=>e.id===o.id))?t.number=parseInt(e.value):t.number=parseInt(hc.symtab.global[get_symtab(o)].value)}else t.number=parseInt(o.id);if(e?.token.type===token_type.add||e?.token.type===token_type.sub||e?.token.type===token_type.div||e?.token.type===token_type.mul)for(t.number=output_out_math_exp(t.number,e);e;)if(e=e.right,e&&(e.token.type===token_type.or||e.token.type===token_type.and||e.token.type===token_type.big||e.token.type===token_type.less||e.token.type===token_type.bigequal||e.token.type===token_type.lessequal||e.token.type===token_type.equal))break;t.number&&(t.boolean=!0);let n;for(;e;){if(e.right?.right?.token.type===token_type.add||e.right?.right?.token.type===token_type.sub||e.right?.right?.token.type===token_type.div||e.right?.right?.token.type===token_type.mul||e.right?.right?.token.type===token_type.not){let t;e.right.token.type===token_type.id?t=parseInt(hc.symtab.global[get_symtab(e.right.token)].value):t=parseInt(e.right.token.id),n=output_out_math_exp(t,e.right.right)}else e.right.token.type===token_type.id?n=parseInt(hc.symtab.global[get_symtab(e.right.token)].value):e.right.token.type===token_type.number?n=parseInt(e.right.token.id):e.right.token.type===token_type.not&&(e.right.right.token.type===token_type.id?n=parseInt(hc.symtab.global[get_symtab(e.right.right.token)].value):e.right.right.token.type===token_type.number&&(n=parseInt(e.right.right.token.id)));switch(e.type){case token_type.less:t.boolean=t.number<n,t.number=n;break;case token_type.lessequal:t.boolean=t.number<=n,t.number=n;break;case token_type.big:t.boolean=t.number>n,t.number=n;break;case token_type.bigequal:t.boolean=t.number>=n,t.number=n;break;case token_type.or:const s=output_out_logical_exp(e,!0,a);for(t.boolean=!!(t.boolean||s);e;)if(e=e.right,e&&e.token.type===token_type.or)break;break;case token_type.and:t.boolean=t.boolean&&!!n;break;case token_type.not:t.boolean=!t.boolean;break;case token_type.equal:t.boolean=t.number===n;break}if(!e)break;e=e.right.right,e&&e?.token?.type===token_type.not&&(e=e.right)}return t.boolean},output_out_exp=(a,l,m,t,r)=>{if(a?.left?.left?.token.id==="(")return;let o=-1,s=-1,i;if(check_ast_type(a?.token.type,"data_type"))i=a.left.token,t+1&&hc.symtab.prototypes[t]?.args?.find(e=>e.id===i.id)||hc.symtab.scoped[t]?.find(e=>e.id===i.id)?(s=hc.symtab.prototypes[t]?.args.findIndex(e=>e.id===i.id),s<0&&(s=hc.symtab.scoped[t].findIndex(e=>e.id===i.id))):o=get_symtab(a.left.token);else if(a?.token)i=a.token,t+1&&hc.symtab.prototypes[t]?.args.find(e=>e.id===i.id)||hc.symtab.scoped[t]?.find(e=>e.id===i.id)?(s=hc.symtab.prototypes[t]?.args.findIndex(e=>e.id===i.id),s<0&&(s=hc.symtab.scoped[t].findIndex(e=>e.id===i.id))):a.token.type===token_type.id&&(o=get_symtab(a.token));else return;let n,h;t+1&&(h=hc.symtab.prototypes[t]?.args.find(e=>e.id===i.id))?n=parseInt(h.value):o>-1?n=parseInt(hc.symtab.global[o].value):n=parseInt(i.id);let e;m?e=a.left:r?e=a.right:e=a;let d=[],u=null,c=e;for(;e;){switch(e.type){case token_type.dot:if(!u.left&&d.push(u.token),!e.right?.right){for(d.push(e.right.token),n=0;c;){switch(c.type){case token_type.assig:c.left.token.type===token_type.number&&(n=parseInt(c.left.token.id));break;case token_type.div:c.left.token.type===token_type.number&&(n/=parseInt(c.left.token.id));break}c=c.left}r||(o>=0?(Array.isArray(hc.symtab.global[o].value)||(hc.symtab.global[o].value=[]),hc.symtab.global[o].value.push({id:d.map(e=>e.id).join("."),value:n})):hc.symtab.prototypes[t].args[s]?.id===i.id?(Array.isArray(hc.symtab.prototypes[t].args[s].value)||(hc.symtab.prototypes[t].args[s].value=[]),hc.symtab.prototypes[t].args[s].value.push({id:d.map(e=>e.id).join("."),value:n})):(Array.isArray(hc.symtab.scoped[t][s].value)||(hc.symtab.scoped[t][s].value=[]),hc.symtab.scoped[t][s].value.push({id:d.map(e=>e.id).join("."),value:n})))}break;case token_type.div:case token_type.assingdiv:if(e.right.token.type===token_type.number)n/=parseInt(e.right.token.id);else{let s;t+1&&(s=hc.symtab.prototypes[t]?.args.find(t=>t.id===e.right.token.id))||(s=hc.symtab.scoped[t]?.find(t=>t.id===e.right.token.id))?e.right.token.type===token_type.classExp?n/=s.value.find(e=>e.id===a.join("."))?.value:n/=parseInt(s.value):(s=hc.symtab.prototypes.find(t=>t.id===e.right.token.id))?(output_out_procedures(e.right,l),n/=s.return):n/=parseInt(hc.symtab.global[get_symtab(e.right.token)].value)}r||(o>=0?hc.symtab.global[o].value=n:hc.symtab.prototypes[t].args[s]?.id===i.id?hc.symtab.prototypes[t].args[s].value=n:hc.symtab.scoped[t][s].value=n);break;case token_type.mul:case token_type.assingmul:if(e.right.token.type===token_type.number)n*=parseInt(e.right.token.id);else{let s;t+1&&(s=hc.symtab.prototypes[t]?.args.find(t=>t.id===e.right.token.id))||(s=hc.symtab.scoped[t]?.find(t=>t.id===e.right.token.id))?e.right.token.type===token_type.classExp?n*=s.value.find(e=>e.id===a.join("."))?.value:n*=parseInt(s.value):(s=hc.symtab.prototypes.find(t=>t.id===e.right.token.id))?(output_out_procedures(e.right,l),n*=s.return):n*=parseInt(hc.symtab.global[get_symtab(e.right.token)].value)}r||(o>=0?hc.symtab.global[o].value=n:hc.symtab.prototypes[t].args[s]?.id===i.id?hc.symtab.prototypes[t].args[s].value=n:hc.symtab.scoped[t][s].value=n);break;case token_type.assig:let a='';if(e.right.token.type===token_type.classExp&&(a=e.right.token.id.split("."),e.right.token.id=a[0],a.shift()),e.right.token.type===token_type.number)n=parseInt(e.right.token.id);else{let s;t+1&&(s=hc.symtab.prototypes[t]?.args.find(t=>t.id===e.right.token.id))||(s=hc.symtab.scoped[t]?.find(t=>t.id===e.right.token.id))?e.right.token.type===token_type.classExp?n=s.value.find(e=>e.id===a.join("."))?.value:n=parseInt(s.value):(s=hc.symtab.prototypes.find(t=>t.id===e.right.token.id))?(output_out_procedures(e.right,l),n=s.return):e.right.token.type===token_type.classExp?n=parseInt(hc.symtab.global[get_symtab(e.right.token)].value.find(e=>e.id===a.join("."))?.value):n=parseInt(hc.symtab.global[get_symtab(e.right.token)].value)}r||(o>=0?hc.symtab.global[o].value=n:hc.symtab.prototypes[t].args[s]?.id===i.id?hc.symtab.prototypes[t].args[s].value=n:hc.symtab.scoped[t][s].value=n);break;case token_type.assingsum:case token_type.add:if(e.right.token.type===token_type.number)n+=parseInt(e.right.token.id);else{let s;t+1&&(s=hc.symtab.prototypes[t]?.args.find(t=>t.id===e.right.token.id))||(s=hc.symtab.scoped[t]?.find(t=>t.id===e.right.token.id))?e.right.token.type===token_type.classExp?n+=s.value.find(e=>e.id===a.join("."))?.value:n+=parseInt(s.value):(s=hc.symtab.prototypes.find(t=>t.id===e.right.token.id))?(output_out_procedures(e.right,l),n+=s.return):n+=parseInt(hc.symtab.global[get_symtab(e.right.token)].value)}r||(o>=0?hc.symtab.global[o].value=n:hc.symtab.prototypes[t].args[s]?.id===i.id?hc.symtab.prototypes[t].args[s].value=n:hc.symtab.scoped[t][s].value=n);break;case token_type.assingsub:case token_type.sub:if(e.right.token.type===token_type.number)n-=parseInt(e.right.token.id);else{let s;t+1&&(s=hc.symtab.prototypes[t]?.args.find(t=>t.id===e.right.token.id))||(s=hc.symtab.scoped[t]?.find(t=>t.id===e.right.token.id))?e.right.token.type===token_type.classExp?n-=s.value.find(e=>e.id===a.join("."))?.value:n-=parseInt(s.value):(s=hc.symtab.prototypes.find(t=>t.id===e.right.token.id))?(output_out_procedures(e.right,l),n-=s.return):n-=parseInt(hc.symtab.global[get_symtab(e.right.token)].value)}r||(o>=0?hc.symtab.global[o].value=n:hc.symtab.prototypes[t].args[s]?.id===i.id?hc.symtab.prototypes[t].args[s].value=n:hc.symtab.scoped[t][s].value=n);break;case token_type.semi:return e}u=e,e=e.right}return check_ast_type(a?.left?.right?.token.type,"id")?output_out_exp(a.left.right,l,!0,t,r):check_ast_type(a?.right?.token.type,"id")&&output_out_exp(a.right,l,!0,t,r),r&&(hc.symtab.prototypes[t].return=n),e},output_out_get_ast_check=(e,t)=>e.left.token.id===t.id,output_out_get_ast=(e,t)=>{if(!e)return null;if(check_ast_type(e.ast.type,"data_type")){let n=output_out_get_ast_check(e.ast,t);if(n)return e.ast}return output_out_get_ast(e.next,t)},output_out_block=(e,t,n)=>{if(!e)return;switch(e.type){case token_type.bool:case token_type.i0:case token_type.u0:case token_type.i8:case token_type.u8:case token_type.i16:case token_type.u16:case token_type.i32:case token_type.u32:case token_type.i64:case token_type.u64:case token_type.f64:case token_type.id:e.left&&output_out_exp(e,t,!1,n);break;case token_type.if:const s=output_out_ifelse(e,t,n);if(s==="{RETURN}")return s;break;case token_type.for:const o=output_out_for(e,t,n);if(o==="{RETURN}")return o;break;case token_type.str:printf(e,n);break;case token_type.call:output_out_procedures(e,t);break;case token_type.return:return output_out_return(e,t,n),"{RETURN}";default:break}return output_out_block(e.right,t,n),output_out_block(e.next,t,n)},output_out_ifelse=(e,t,n)=>{const i=output_out_logical_exp(e,!1,n);let s;e.left?.left?.left?.left&&(s=e.left.left.left.left.right);let o='';return i?o=output_out_block(e.left.left.left.right,t,n):s&&(o=output_out_block(s,t,n)),!i&&e?.left?.left?.left?.next?.token.type===token_type.if&&output_out_ifelse(e.left.left.left.next,t),o},output_out_js=e=>{eval(e.left.left.token.id)},output_out_for=(t,a,n)=>{let e=get_symtab(t.left.token);e||(e=hc.symtab.prototypes[n]?.args?.findIndex(e=>e.id===t.left.token.id),e<0&&(e=hc.symtab.scoped[n]?.findIndex(e=>e.id===t.left.token.id)));const r=parseInt(t.right.right.token.id),l=t.left.left.left.left.token,c=parseInt(t.left.left.left.left.left.token.id);let i=t.left.left.left.left.left.left.left;i.type===token_type.id&&(i=t.left.left.left.left.left.left.left.right);let s;check_ast_type(i.type,"assignment_operator")?s=parseInt(i.right.token.id):s=1;let o='';switch(l.type){case token_type.less:for(let i=r;i<c;i+=s){if(o=output_out_block(t.left.left.left.left.left.left.right,a,n),o==="{RETURN}")return o;hc.symtab.global[e]?.id===t.left.token.id?hc.symtab.global[e].value=parseInt(hc.symtab.global[e].value)+s:hc.symtab.prototypes[n]?.args[e]?.id===t.left.token.id?hc.symtab.prototypes[n].args[e].value=parseInt(hc.symtab.prototypes[n].args[e].value)+s:hc.symtab.scoped[n][e].value=parseInt(hc.symtab.scoped[n][e].value)+s}break;case token_type.big:for(let i=r;i>c;i+=s){if(o=output_out_block(t.left.left.left.left.left.left.right,a,n),o==="{RETURN}")return o;hc.symtab.global[e]?.id===t.left.token.id?hc.symtab.global[e].value=parseInt(hc.symtab.global[e].value)+s:hc.symtab.prototypes[n]?.args[e]?.id===t.left.token.id?hc.symtab.prototypes[n].args[e].value=parseInt(hc.symtab.prototypes[n].args[e].value)+s:hc.symtab.scoped[n][e].value=parseInt(hc.symtab.scoped[n][e].value)+s}break}return o},output_out_procedures=(s,o)=>{const i=output_out_get_ast(o,s.token),t=get_prototype(i?.left?.token);let e=s.right,n=0;for(;hc.symtab.prototypes[t].args[n]&&e;)e.token.type===token_type.id?hc.symtab.prototypes[t].args[n].value=hc.symtab.global[get_symtab(e.token)].value:e.token.type===token_type.number&&(hc.symtab.prototypes[t].args[n].value=e.token.id),n++,e=e.right;output_out_block(i.right,o,t)},output_out_return=(e,t,n)=>{output_out_exp(e.right,t,!1,n,!0)},output=async t=>{if(!t)return hc.files.stdout;let e=t;do{switch(e.ast.type){case token_type.bool:case token_type.i0:case token_type.u0:case token_type.i8:case token_type.u8:case token_type.i16:case token_type.u16:case token_type.i32:case token_type.u32:case token_type.i64:case token_type.u64:case token_type.f64:case token_type.id:output_out_exp(e.ast,t);break;case token_type.if:output_out_ifelse(e.ast,t);break;case token_type.for:output_out_for(e.ast,t);break;case token_type.js:output_out_js(e.ast);break;case token_type.str:let n=e.ast;do printf(n),n=n.right;while(n)break;case token_type.call:output_out_procedures(e.ast,t);break;default:break}e=e.next}while(e)return hc.files.stdout},printf=(t,n)=>{let e=t.token.id;if(t.token.id.includes("%")){let s;if(n+1&&(s=hc.symtab.prototypes[n]?.args.find(e=>e.id===t.left.right.token.id))||(s=hc.symtab.scoped[n]?.find(e=>e.id===t.left.right.token.id)))e=e.replace(/%d/g,s.value);else if(t.left.right.token.type===token_type.number)e=e.replace(/%d/g,t.left.right.token.id);else if(t.left.right.token.type===token_type.classExp){let n=t.left.right.token.id.split("."),s=t.left.right.token;s.id=n.shift(),e=e.replace(/%d/g,hc.symtab.global[get_symtab(s)].value.find(e=>e.id===n.join("."))?.value)}else e=e.replace(/%d/g,hc.symtab.global[get_symtab(t.left.right.token)].value)}e=e.replace(/undefined/g,"NULL"),e=e.replace(/null/g,"NULL"),hc.files.stdout+=e.replace(/\\n|\\t/g,e=>{switch(e){case"\\r":case"\\n":return"\n";case"\\t":return" ";default:return e}})}