예제 #1
0
파일: hash.c 프로젝트: vidarh/FPL
ReturnCode REGARGS
AddVar(struct Data *scr, /* pointer to struct Data */
       struct Identifier *ident,/* identifier struct pointer */
       struct Local **local,
       uchar output)
{
  ReturnCode ret;
  struct Local *temp;
  if(ret=AddIdentifier(scr, ident))
    INFO(scr, CERROR_IDENTIFIER_USED, ident->name);
  else {
    GETMEM(temp, sizeof(struct Local));  
    temp->next=*local;
    temp->ident=ident;
    *local=temp;

    scr->currvariables++; /* increase number of current symbols */
    scr->totalvariables++; /* increase total number of symbols */
    ident->number= ++IdentNumber;
    if(output) {
      CALL(PutArg(scr, COMP_DECLARE, ident->flags));
      if(!(ident->flags&FPL_EXPORT_SYMBOL)) {
        CALL(PutArg(scr, COMP_NOTHING, ident->number));
      }
      else {
        CALL(PutArg(scr, COMP_NOTHING, ident->hash));
      }
      CALL(PutString(scr, COMP_NOTHING, ident->name, -1));
    }
  }
  return(ret);
}
예제 #2
0
//-----------------------------------------------------------------------------
// return values: 0 - OK, 1 - wrong arguments, 2 - wrong command, 3 - string too long, 4 -- unclosed string
int mglParser::Parse(mglGraph *gr, std::wstring str, long pos)
{
	if(Stop || gr->NeedStop())	return 0;
	curGr = gr->Self();
	std::wstring arg[1024];
	str=mgl_trim_ws(str);
	long n,k=0,m=0,mm=0,res;
	// try parse ':' -- several commands in line
	for(n=0;n<long(str.length());n++)
	{
		if(str[n]=='\'' && (n==0 || str[n-1]!='\\'))	k++;
		if(k%2)	continue;
		if(str[n]=='(')	m++;	if(str[n]==')')	m--;
		if(str[n]=='{')	mm++;	if(str[n]=='}')	mm--;
		if(str[n]=='#')	break;
		if((str[n]==':' || str[n]=='\n') && k%2==0 && m==0 && mm==0)
		{
			res=Parse(gr,str.substr(0,n),pos);
			if(!res)	res=Parse(gr,str.substr(n+1),pos);
			return res;
		}
	}
	if(k%2 || m || mm)	return 4;	// strings is not closed
	// define parameters or start cycle
	res = ParseDef(str);	if(res)	return res-1;
	// parse arguments (parameters $1, ..., $9)
	PutArg(str,false);	str=mgl_trim_ws(str);

	std::wstring opt;
	for(k=0;k<1024;k++)	// parse string to substrings (by spaces)
	{
		n = mglFindArg(str);
		if(n<1)	// this is option
		{
			if(str[-n]==';')	opt = str.substr(-n+1);
			if(n<0)	str = str.substr(0,-n);
			break;
		}
		arg[k] = str.substr(0,n);
		str = mgl_trim_ws(str.substr(n+1));
	}
	// try to find last argument
	if(str[0]!=0 && str[0]!='#' && str[0]!=';')	{	arg[k] = str;	k++;	}
	if(k<1) n =0;
	else
	{
		// fill arguments by its values
		mglArg *a = new mglArg[k];
		FillArg(gr, k, arg, a);
		// execute first special (program-flow-control) commands
		if(!skip() && !arg[0].compare(L"stop"))
		{	Stop = true;	delete []a;	return 0;	}
		if(!arg[0].compare(L"func"))
		{	Stop = true;	delete []a;	return 0;	}
		n = FlowExec(gr, arg[0].c_str(),k-1,a);
		if(n)		{	delete []a;	return n-1;	}
		if(skip())	{	delete []a;	return 0;	}
		if(!arg[0].compare(L"load"))
		{
			int n = a[0].type==1?0:1;
			a[0].s.assign(a[0].w.begin(),a[0].w.end());
			if(!n)	mgl_parser_load(this,a[0].s.c_str());
			delete []a;	return n;
		}
		if(!arg[0].compare(L"define"))
		{
			if(k==3)
			{
				DeleteVar(arg[1].c_str());	// force to delete variable with the same name
				mglNum *v=AddNum(arg[1].c_str());
				if(arg[2][0]=='!')	// complex number is added
				{	HADT dd = mglFormulaCalcC(arg[2].substr(1),this, DataList);
					v->d=NAN;	v->c = dd->a[0];	delete dd;	}
				else
				{	HMDT dd = mglFormulaCalc(arg[2],this, DataList);
					v->c = v->d = dd->a[0];	delete dd;	}
			}
			delete []a;	return k==3?0:1;
		}
		if(!arg[0].compare(L"rkstep"))
		{
			int res=1;
			if(k>2 && a[0].type==1 && a[1].type==1)
			{
				std::wstring a1 = arg[1], a2=arg[2];	res = 0;
				if(a1[0]=='\'')	a1 = a1.substr(1,a1.length()-2);
				if(a2[0]=='\'')	a2 = a2.substr(1,a2.length()-2);
				mgl_rk_step_w(this, a1.c_str(), a2.c_str(), (k>=3 && a[2].type==2)?a[2].v:1);
			}
			delete []a;	return res;
		}
		if(!arg[0].compare(L"call"))
		{
			n = 1;
			if(a[0].type==1)
			{
				int na=0;
				a[0].s.assign(a[0].w.begin(),a[0].w.end());
				n=-IsFunc(a[0].w.c_str(),&na);
				if(n && k!=na+2)
				{
					char buf[64];
					snprintf(buf,64,"Bad arguments for %ls: %ld instead of %d\n", a[0].w.c_str(),k-2,na);
					buf[63]=0;	gr->SetWarn(-1,buf);	n = 1;
				}
				else if(n)
				{
					mglFnStack fn;			fn.pos = pos;
					for(int i=0;i<10;i++)	{	fn.par[i] = par[i];	par[i]=L"";	}
					for(int i=1;i<k-1;i++)	AddParam(i,arg[i+1].c_str());
					fn_stack.push_back(fn);	n--;
				}
				else if(AllowFileIO)	// disable external scripts if AllowFileIO=false
				{
					FILE *fp = fopen(a[0].s.c_str(),"rt");
					if(fp)
					{
						register int i;
						mglParser *prs = new mglParser(AllowSetSize);
						prs->DataList.swap(DataList);	prs->NumList.swap(NumList);	prs->Cmd=Cmd;
						for(i=10;i<30;i++)	prs->AddParam(i,par[i].c_str());
						prs->Execute(gr,fp);
						for(i=10;i<30;i++)	AddParam(i,prs->par[i].c_str());
						DataList.swap(prs->DataList);	NumList.swap(prs->NumList);
						prs->Cmd=0;	delete prs;	fclose(fp);
					}
					else	n=1;
				}
			}
			delete []a;	return n;
		}
		if(!arg[0].compare(L"for"))
		{
			n = 1;
			char ch = arg[1][0];
			int r = ch-'0';
			if(ch>='a' && ch<='z')	r = 10+ch-'a';
//			int r = int(a[0].v);
			if(arg[1][1]==0 && (r>=0 && r<40))
			{
				if(a[1].type==0)
				{
					n=0;		fval[r] = *(a[1].d);
					fval[r].nx *= fval[r].ny*fval[r].nz;
				}
				else if(a[1].type==2 && a[2].type==2 && a[2].v>a[1].v)
				{
					mreal step = a[3].type==2?a[3].v:1;
					mm = int(step>0 ? (a[2].v-a[1].v)/step : 0);
					if(mm>0)
					{
						n=0;	fval[r].Create(mm+1);
						for(int ii=0;ii<mm+1;ii++)
							fval[r].a[ii] = a[1].v + step*ii;
					}
				}
				if(n==0)
				{
					for(int i=39;i>0;i--)
					{	for_stack[i]=for_stack[i-1];	if_for[i]=if_for[i-1];	}
					for_stack[0] = r+1;		fval[r].nz = pos;	if_for[0]=if_pos;
					wchar_t buf[32];		mglprintf(buf,32,L"%g",fval[r].a[0]);
					AddParam(r, buf);	fval[r].ny = 1;
				}
			}
			delete []a;	return n;
		}
		// alocate new arrays and execute the command itself
		n = PreExec(gr, k, arg, a);
		if(n>0)	n--;
		else if(!arg[0].compare(L"setsize") && !AllowSetSize)	n = 2;
		else	n = Exec(gr, arg[0].c_str(),k-1,a, arg[1].c_str(), opt.c_str());
		delete []a;
	}
	// delete temporary data arrays
	for(size_t i=0;i<DataList.size();i++)	if(DataList[i] && DataList[i]->temp)
	{	mglDataA *u=DataList[i];	DataList[i]=0;	delete u;	}
	return n;
}
예제 #3
0
//-----------------------------------------------------------------------------
int mglParser::ParseDef(std::wstring &str)
{
	if(!skip() && !str.compare(0,3,L"def") && (str[6]==' ' || str[6]=='\t'))
	{
		int res = 1;	mreal d;
		PutArg(str,true);
		const std::wstring s = mgl_trim_ws(str.substr(7));
		if(!str.compare(3,3,L"ine"))
		{
			int nn = s[1]<='9' ? s[1]-'0' : (s[1]>='a' ? s[1]-'a'+10:-1);
			if(s[0]=='$' && nn>=0 && nn<='z'-'a'+10)
			{
				AddParam(nn, mgl_trim_ws(s.substr(2)).c_str());	return 1;
			}
		}
		if(!str.compare(3,3,L"num"))
		{
			int nn = s[1]<='9' ? s[1]-'0' : (s[1]>='a' ? s[1]-'a'+10:-1);
			if(s[0]=='$' && nn>=0 && nn<='z'-'a'+10)
			{
				res = 0;
				HMDT dd = mglFormulaCalc(mgl_trim_ws(s.substr(2)), this, DataList);
				d = dd->a[0];	delete dd;
				char buf[32];	snprintf(buf,32,"%g",d);
				buf[31] = 0;	AddParam(nn, buf);
			}
			return res+1;
		}
		if(!str.compare(3,3,L"chr"))
		{
			int nn = s[1]<='9' ? s[1]-'0' : (s[1]>='a' ? s[1]-'a'+10:-1);
			if(s[0]=='$' && nn>=0 && nn<='z'-'a'+10)
			{
				res = 0;
				HMDT dd = mglFormulaCalc(mgl_trim_ws(s.substr(2)), this, DataList);
				d=dd->a[0];	delete dd;
				wchar_t buf[2]={0,0};	buf[0] = wchar_t(d);	AddParam(nn, buf);
			}
			return res+1;
		}
	}
	if(!skip() && !str.compare(0,3,L"ask") && (str[3]==' ' || str[3]=='\t'))
	{
		PutArg(str,true);
		std::wstring s = mgl_trim_ws(str.substr(4));
		int nn = s[1]<='9' ? s[1]-'0' : (s[1]>='a' ? s[1]-'a'+10:-1);
		if(s[0]=='$' && nn>=0 && nn<='z'-'a'+10)
		{
			s = mgl_trim_ws(s.substr(2));
			if(s[0]=='\'')	s=s.substr(1,s.length()-2);
			if(mgl_ask_func)
			{
				static wchar_t res[1024];
				mgl_ask_func(s.c_str(),res);
				if(*res)	AddParam(nn, res);
			}
			return mgl_ask_func?1:2;
		}
		else	return 2;
	}
	if(!skip() && !str.compare(0,3,L"for") && (str[3]==' ' || str[3]=='\t'))
	{
		size_t i;
		for(i=4;str[i]<=' ';i++);
		// if command have format 'for $N ...' then change it to 'for N ...'
		if(str[i]=='$' && str[i+1]>='0' && str[i+1]<='9')	str[i] = ' ';
		if(str[i]=='$' && str[i+1]>='a' && str[i+1]<='z')	str[i] = ' ';
	}
	return 0;
}