// DataToGeneratorData.txt


//-------------------------------------------------------------------------------------------------
// void, bool, char, int, float, double, digit, [interval],
// string, vector, set, map, graph, program, function, module.  *




bool isPrimitive(type){
	ok = {"void", "bool", "char", "int", "float", "double", "string"}.in(type);
	return ok;
}


// 1 - Container,  0 - Final
bool isContainer(type){
	ok = {"vector", "set", "map"}.in(type);
	return ok;
}




//-------------------------------------------------------------------------------------------------
var BuildThreeForData(p_Data){
	type = typeof(*p_Data);
	if(type == "vector"){
		size = p_Data->size();
		row = {};
		i = 0;
		for(;i<size;++i){
			isCont = isContainer(typeof((*p_Data)[i]));
			row.push(isCont);
			}
		R = {"type":type};
		i = 0;
		for(;i<size;++i){
			row[i] = (
				row[i] ?
				BuildThreeForData(&(*p_Data)[i]) :
				isPrimitive(typeof((*p_Data)[i]))
				);
			}
		R.row = row;
		return R;
		}
	if(type == "set"){
		analog = (vector)(*p_Data);
		R = BuildThreeForData(&analog);
		R.type = type;
		return R;
		}
	if(type == "map"){
		keys = p_Data->getKeys();
		size = keys.size();
		row = {};
		i = 0;
		for(;i<size;++i){
			p_Value = &(*p_Data)[keys[i]];
			isCont = isContainer(typeof(*p_Value));
			row.push(isCont);
			}
		R = {"type":type};
		i = 0;
		for(;i<size;++i){
			p_Value = &(*p_Data)[keys[i]];
			row[i] = (
				row[i] ?
				BuildThreeForData(p_Value) :
				isPrimitive(typeof(*p_Value))
				);
			}
		R.row = row;
		return R;
		}
	return isPrimitive(type);
}




bool isSetInThreeData(p_Three){
	type = typeof(*p_Three);
	if(type == "map"){
		if(p_Three->type == "set")return true;
		size = p_Three->row.size();
		i = 0;
		for(;i<size;++i){
			ok = isSetInThreeData(&p_Three->row[i]);
			if(ok)return true;
			}
		}
	return false;
}



bool isAllPrimitiveInThreeData(p_Three){
	type = typeof(*p_Three);
	if(type == "map"){
		size = p_Three->row.size();
		i = 0;
		for(;i<size;++i){
			ok = isAllPrimitiveInThreeData(&p_Three->row[i]);
			if(!ok)return false;
			}
		return true;
		}
	return *p_Three;
}





var findAllAccessToStringInData(p_Data){

	findF = (thisFunc,p_Data,p_Way,p_Access)=>{
		type = typeof(*p_Data);
		if(type == "string"){
			p_Access->push(*p_Way);
			return;
			}
		if(type == "vector"){
			size = p_Data->size();
			i = 0;
			n = p_Way->size();
			p_Way->push(0);
			for(;i<size;++i){
				(*p_Way)[n] = i;
				thisFunc->run(thisFunc,&(*p_Data)[i],p_Way,p_Access);
				}
			p_Way->pop();
			return;
			}
		if(type == "map"){
			keys = p_Data->getKeys();
			size = keys.size();
			i = 0;
			n = p_Way->size();
			p_Way->push(0);
			for(;i<size;++i){
				(*p_Way)[n] = keys[i];
				thisFunc->run(thisFunc,&(*p_Data)[keys[i]],p_Way,p_Access);
				}
			p_Way->pop();
			return;
			}
		};

	Access = {};
	Way = {};
	findF.run(&findF,p_Data,&Way,&Access);
	return Access; 
}




var BuildFunctionFromDataPrimitiv(p_Data){
	text = p_Data->export();
	if(text.size()<=50){
		P = "()=>{return 1;}";
		P = PROGRAM(P);
		P.setSub({0,0,0},PROGRAM(text));
		F = eval(P);
		return F;
		}
	if(text.size()<=500){
		P = "()=>{R=1;return R;}";
		P = PROGRAM(P);
		P.setSub({0,0,1},PROGRAM(text));
		F = eval(P);
		trace(F);
		return F;
		}

	trace(JSON("stringify",*p_Data));

	AccessAllStrWays = findAllAccessToStringInData(p_Data);
	trace((*p_Data)[AccessAllStrWays[1]]);
	trace(AccessAllStrWays.size());

	return ()=>{};
}








// DataToGeneratorData.txt	:-|