Location: The Netherlands Joined: May 2016
Posts: 67
|
Here's a simple script I wrote to evaluate any infix expression (e.g. 10+(1+3)*3*4^2):
/* infix_evaluate(infix,ret_fromstack,constants/scripts) * Evalute infix expression. */ var str,ret_fromstack,i,j,k,l,arg,d,len,newstr,newstr2,op,push,do_push; str=argument0
push=ds_queue_create() do_push=0
if argument3=0 { pcount=1+string_count('^',str)+2*(string_count('*',str)+string_count('/',str))+3*(string_count('+',str)+string_count('-',str)) str=string_repeat('(',pcount)+string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(str,'(','((((('),')',')))))'),'^',')^('),'*','))*(('),'/','))/(('),'+',')))+((('),'-',')))-(((')+string_repeat(')',pcount) argument3=50 argument4=ds_stack_create() argument5=ds_queue_create() global.ret_stack=argument4 global.ret_stack_exec=argument5 ret_fromstack=argument1 } else ret_fromstack=0
if string_char_at(str,1)!="(" { //show_message('Pushed on stack: '+str) if ds_map_exists(argument2,str) ds_stack_push(argument4,ds_map_find_value(argument2,str)) else if ds_map_exists(argument2,'scr_'+str) { //show_message('scr_'+str+'='+string(ds_map_find_value(argument2,'scr_'+str))) ds_queue_enqueue(argument5,ds_map_find_value(argument2,'scr_'+str)) ds_stack_push(argument4,ds_map_find_value(argument2,'scr_'+str)) } else { //show_message(str) if string_length(str)=string_length(string_digits(str))+string_count('-',str)+string_count('.',str) ds_stack_push(argument4,real(str)) else ds_stack_push(argument4,0) } return str; }
if argument3=1 return "";
newstr="" newstr2="" i=1 j=1 for(k=0;k<10;k+=1) { if string_char_at(str,i)="(" { i+=1 j=i d=1 len=string_length(str) while(d&&i<=len) { char=string_char_at(str,i) if char="(" d+=1 if char=")" d-=1 i+=1 } } //else if k=0 // ds_stack_push(argument4,real(string_copy(str,j,i-1-j))) op[k]=string_char_at(str,i) //if k=0 // show_message('Operator: '+op[k]) //show_message(string_copy(str,j,i-1-j)) newstr+=infix_evaluate(string_copy(str,j,i-1-j),argument1,argument2,argument3-1,argument4,argument5)+" " if string_pos(op[k],'^*/+-([]') { newstr2+=" "+op[k] //show_message('Operator correct: '+op[k]) //if op[k]='(' // i+=4 do_push=1 i+=1 } else break }
k_max=k-1
for(k=k_max;k>=0;k-=1) { if do_push { //exec='return '+string(ds_stack_pop(argument4))+op[0]+string(ds_stack_pop(argument4)) //ds_queue_enqueue(push,execute_string(exec) //show_message(exec) b=ds_stack_pop(argument4) a=ds_stack_pop(argument4) if op[k]='^' ds_queue_enqueue(push,power(a,b)) else if op[k]='*' ds_queue_enqueue(push,a*b) else if op[k]='/' { if b=0 ds_queue_enqueue(push,a) else ds_queue_enqueue(push,a/b) } else if op[k]='+' ds_queue_enqueue(push,a+b) else if op[k]='-' ds_queue_enqueue(push,a-b) else if op[k]='[' { //ds_queue_enqueue(argument5,a) ds_queue_enqueue(argument5,b) //show_message(string(a)+'~'+string(b)) do_push=0 } else if op[k]=']' { function=ds_queue_dequeue(argument5) for(l=0;l<16;l+=1) arg[l]=0 l=0 while(!ds_queue_empty(argument5)) { arg[l]=ds_queue_dequeue(argument5) l+=1 } //show_message(string(function)+"("+string(arg[0])+")") ds_queue_enqueue(push,script_execute(function,arg[0])) //show_message('function: '+string(function)+', result: '+string(push)) //(sin)~(1)`(0) } else if op[k]=',' { ds_queue_enqueue(argument5,b) do_push=0 } //show_message('Pushed operation '+string(a)+' '+op[k]+' '+string(b)+' result: '+string(push)) if do_push while(!ds_queue_empty(push)) ds_stack_push(argument4,ds_queue_dequeue(push)) } } if ret_fromstack return ds_stack_pop(argument4);
while(string_count(' ',newstr)) newstr=string_replace_all(newstr,' ',' ') return newstr+newstr2;
You can choose to either return the resulting value from the stack, or return the resulting postfix from the infix expression. For example 10+(1+3)*3*4^2 becomes 10 1 3 + 3 * 4 * +.
|