// author.code




var testf2(var x){
	trace("OK testf2");
	return x+1;
}



void testf(){
	if(1<0)trace("true");else trace("false");
	var t=101;
	trace("OK:"+t);
	trace("ff:"+(testf2(20)+testf2(1000)));
}



void initMaxine(var f){
	if(typeof(f)=="string")f=getFunction(f);
	var mm=new {pages:{((map)({}))},stackf:{f}};
	return mm;
}



vector getListAllVar(var comand){
	S=((set)({}));
	acces={};
	accesf={};
	isf=0;
	while(1){
		p=comand.getRowSize(acces);
		x=comand.getSub(acces);
		if(!p){if(x.typeof()=="var")S.insert(((string)x));}
		acces.push(p);
		isf=x.typeof()=="function";
		accesf.push(isf);
		n=acces.size()-1;
		p=acces[n];
		isf=accesf[n];
		if(isf){if(p==1)--p;}
		while(!p){
			acces.pop_back();
			accesf.pop_back();
			--n;
			if(n<0)break;
			p=acces[n];
			isf=accesf[n];
			if(isf){if(p==1)--p;}
			}
		if(!p)break;
		--p;
		acces[n]=p;
		}
	return ((vector)S);
}



void ReplaceVars(var programa,var S){
	acces={};
	accesf={};
	isf=0;
	while(1){
		p=programa->getRowSize(acces);
		x=programa->getSub(acces);
		if(!p){if(x.typeof()=="var"){
			xx=((string)x);
			i=0;
			while(i<S.size()){
				if(S[i]==xx)programa->setSub(acces,PROGRAM("*p["+i+"]"));
				++i;
				}
			}}
		acces.push(p);
		isf=x.typeof()=="function";
		accesf.push(isf);
		n=acces.size()-1;
		p=acces[n];
		isf=accesf[n];
		if(isf){if(p==1)--p;}
		while(!p){
			acces.pop_back();
			accesf.pop_back();
			--n;
			if(n<0)break;
			p=acces[n];
			isf=accesf[n];
			if(isf){if(p==1)--p;}
			}
		if(!p)break;
		--p;
		acces[n]=p;
		}
}



bool getSubTree(var programa,var access){
	p=programa->getRowSize((*access));
	x=programa->getSub((*access));
	isf=x.typeof()=="function";
	if(isf){
		access->push(0);
		x=((string)programa->getSub((*access)));
		if(issystemf(x))isf=0;
		access->pop_back();
		}
	end=0;
	if(isf)end=1;
	while(p>end){
		--p;
		access->push(p);
		isf2=getSubTree(programa,access);
		if(isf2)return 1;
		access->pop_back();
		}
	return isf;
}



var virtualMahine(var mmodele){
	MeResult="void";
	glubina=0;
	thisPage= &mmodele->pages[mmodele->pages.length()-1];
	ff= &mmodele->stackf[mmodele->stackf.length()-1];
	pos=ff->Root();
	pos=ff->Next(pos);
	while(pos!=ff->Root()){
		comand=ff->getCommand(pos);
		str=((string)comand);
		if(str=="PAGEOPEN"){
			mmodele->pages.push(((map)({})));
			++glubina;
			}
		if(str=="PAGECLOSE"){
			mmodele->pages.pop_back();
			--glubina;
			}
		if(str=="PAGEOPEN"||str=="PAGECLOSE")thisPage= &mmodele->pages[mmodele->pages.length()-1];else {
			if(comand.typeof({})=="CreateVar"){
				namevar=comand.typeof({},"name");
				(*thisPage)[namevar]=0;
				comand=PROGRAM(namevar+"="+((string)comand.getSub({0})));
				}
			isReturn=0;
			if(comand.typeof({})=="return"){
				isReturn=1;
				comand=comand.getSub({0});
				}
			isIF=0;
			if(comand.typeof({})=="if"){
				isIF=1;
				comand=comand.getSub({0});
				}
			S=getListAllVar(comand);
			p={};
			i=0;
			while(i<S.size()){
				jj=j=mmodele->pages.size()-1;
				while(glubina>=jj-j){
					if(mmodele->pages[j].find(S[i]))break;
					--j;
					}
				if(glubina<jj-j)mmodele->pages[j=jj][S[i]]=0;
				p.push(&mmodele->pages[j][S[i]]);
				++i;
				}
			ReplaceVars(&comand,S);
			b=1;
			while(b){
				access={};
				b=getSubTree(&comand,&access);
				if(!b)MeResult=eval(comand);else {
					subcomand=comand.getSub(access);
					access2={};
					px=subcomand.getRowSize(access2);
					mmodele->pages.push(((map)({})));
					thisPage= &mmodele->pages[mmodele->pages.length()-1];
					var ff2;
					var names;
					ii=0;
					while(ii<px){
						access2.push(ii);
						x=subcomand.getSub(access2);
						access2.pop_back();
						if(!ii){
							ff2=getFunction(((string)x));
							names=ff2.getNamesStart();
							}else {
							x=eval(x);
							(*thisPage)[names[ii-1]]=x;
							}
						++ii;
						}
					mmodele->stackf.push(ff2);
					result=virtualMahine(mmodele);
					mmodele->stackf.pop_back();
					mmodele->pages.pop_back();
					thisPage= &mmodele->pages[mmodele->pages.length()-1];
					n=p.size();
					p.push(result);
					comand.setSub(access,PROGRAM("*p["+n+"]"));
					}
				}
			if(isReturn)break;
			}
		pos=ff->Next(pos);
		if(typeof(pos)=="vector")pos=pos[!MeResult];
		}
	while(glubina){
		mmodele->pages.pop_back();
		--glubina;
		}
	return MeResult;
}



int main(){
	mm=initMaxine("testf");
	virtualMahine(mm);
	getstring();
}


// author.code	:-|