⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interp.cpp

📁 GNU ccScript is a C++ class framework for creating a virtual machine execution system for use with a
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	cmd->enterMutex();	--image->refcount;	if(image)		if(!image->refcount && image != cmd->active)			delete image;	cmd->leaveMutex();	image = NULL;	while(stack)		pull();	purge();	leaveMutex();}bool ScriptInterp::step(void){	bool rtn = false;	Line *next, *line;	unsigned count = autoStepping;	if(!image)		return true;	enterMutex();	if(!frame[stack].line)		goto exit;trans:	updated = false;	frame[stack].index = 0;	line = getLine();	next = line->next;	rtn = execute(line->scr.method);	release();	if(!rtn || !frame[stack].line)		goto exit;		if((frame[stack].tranflag && !trace))	{		count = 0;		goto trans;	}	if(count-- && frame[stack].line == next && !trace)		goto trans;exit:	while(!frame[stack].line && stack)	{		if(frame[stack - 1].local == frame[stack].local)			break;		pull();		if(frame[stack].line)			advance();	}	if(!frame[stack].line)	{                if(initialized)                        exit();		rtn = false;	}	else if(!rtn && thread)	{		release();		startThread();	}	else		release();	leaveMutex();	return rtn;}void ScriptInterp::ripple(void){	char namebuf[256];	char *label;	Name *scr = frame[stack].script;	Line *line;		const char *name = getValue(NULL);	snprintf(namebuf, sizeof(namebuf), "%s", name);	label = strchr(namebuf, ':');	if(!label)	{		label = namebuf;		goto find;	}	*(label++) = 0;	scr = getScript(namebuf);	if(!scr)	{		logmissing(name, "missing", "script");		error("label-missing");		return;	}	find:	if(!label || !*label)	{		line = scr->first;		goto done;	}	line = scr->first;	while(line)	{		if(!stricmp(line->cmd, "label"))			if(!stricmp(line->args[0], label))				break;		line = line->next;	}		if(!line)	{		logmissing(name, "missing", "script");		error("label-missing");		return;	}done:        frame[stack].caseflag = false;        frame[stack].script = scr;	frame[stack].first = scr->first;        frame[stack].line = line;        frame[stack].index = 0;	frame[stack].mask = scr->mask;	updated = true;}bool ScriptInterp::redirect(bool evflag){	char namebuf[256];	const char *label = getValue(NULL);	char *ext;	size_t len;	bool pvt = true;	Name *scr = frame[stack].script;	bool shortflag = true;	unsigned base = frame[stack].base;	bool fun = false;	bool isfun = false;	unsigned long mask = frame[stack].line->mask & frame[stack].mask & cmd->imask;	if(!stricmp(frame[stack].line->cmd, "call"))		fun = true;	isfun = isFunction(scr);	if(!label)	{		logmissing(label, "missing", "script");		error("branch-failed");		return true;	}	if(*label == '&')		++label;	if(strstr(label, "::"))		shortflag = false;	len = strlen(label);retry:	if(shortflag)	{		snprintf(namebuf, sizeof(namebuf), "%s", frame[stack].script->name);		ext = strstr(namebuf, "::");		if(ext)			*ext = 0;		len = strlen(namebuf);		snprintf(namebuf + len, sizeof(namebuf) - len, "::%s", label);		scr = getScript(namebuf);		if(scr)		{			pvt = false;			goto script;		}		shortflag = false;		goto retry;	}	else if(!strncmp(label, "::", 2))	{		pvt = false;		setString(namebuf, sizeof(namebuf), frame[stack].script->name);		ext = strstr(namebuf, "::");		if(ext)			setString(ext, sizeof(namebuf) + namebuf - ext, label);		else			addString(namebuf, sizeof(namebuf), label);		label = namebuf;	}	else if(fun || isfun)	{		setString(namebuf, sizeof(namebuf), frame[stack].script->name);		ext = strstr(namebuf, "::");		if(ext)			setString(ext + 2, sizeof(namebuf) + namebuf - ext - 2, label);		else		{			addString(namebuf, sizeof(namebuf), "::");			addString(namebuf, sizeof(namebuf), label);		}		scr = getScript(namebuf);		if(scr)		{			pvt = false;			goto script;		}	}	scr = getScript(label);script:	if(!scr)	{		logmissing(label, "missing", "script");		error("script-not-found");		return true;	}	if(pvt && isPrivate(scr))	{		logmissing(label, "access", "script");		error("script-private");		return true;	}	if(!isfun && !fun && isFunction(scr) && scr != frame[stack].script)	{		logmissing(label, "access", "script");		error("script-function");		return true;	}	if(!isFunction(scr))		isfun = false;	if(isfun && evflag)		clearStack();	else while(evflag && stack > base)		pull();	frame[stack].caseflag = false;	frame[stack].script = scr;	frame[stack].line = frame[stack].first = scr->first;	frame[stack].index = 0;	if(evflag && isfun && stack)	{			mask = frame[stack - 1].line->mask & frame[stack - 1].mask & cmd->imask;		frame[stack].mask = (mask | scr->mask);	}	else if(evflag)		frame[stack].mask = getMask();	else		frame[stack].mask = (mask | scr->mask);	updated = true;	return true;}bool ScriptInterp::redirect(const char *scriptname){	Name *scr;	char namebuf[128];	char *ext;	if(!strncmp(scriptname, "::", 2))	{		setString(namebuf, sizeof(namebuf), frame[stack].script->name);		ext = strstr(namebuf, "::");		if(ext)			*ext = 0;		addString(namebuf, sizeof(namebuf), scriptname);	}	else		setString(namebuf, sizeof(namebuf), scriptname);	scr = getScript(namebuf);	if(scr)	{		clearStack();		frame[stack].script = scr;		frame[stack].line = frame[stack].first = scr->first;		frame[stack].mask = getMask();		return true;	}	else		logmissing(namebuf, "missing", "script");	return false;}unsigned long ScriptInterp::getMask(void){	unsigned sp = frame[stack].base;	unsigned long mask = 0;	while(sp < stack)	{		mask |= (frame[sp].script->mask & frame[sp].line->mask & cmd->imask);		++sp;	}	mask |= frame[stack].script->mask;	return mask;}void ScriptInterp::enterThread(ScriptThread *thr){}bool ScriptInterp::eventThread(const char *evt, bool flag){	if(updated)		return false;	if(scriptEvent(evt, flag))		updated = true;	return updated;}void ScriptInterp::exitThread(const char *msg){	if(updated)		return;	if(msg)		error(msg);	else		advance();	updated = true;}void ScriptInterp::startThread(void){	thread->start();}void ScriptInterp::waitThread(void){	timeout_t timer = getTimeout();	if(!timer)		return;	Thread::sleep(timer);	enterMutex();	delete thread;	thread = NULL;	if(!updated)		error("timeout");	updated = true;	leaveMutex();}bool ScriptInterp::exit(void){	if(exiting)		return false;	exiting = true;	trap((unsigned)0);	if(frame[stack].line)		return true;	return redirect("::exit");}bool ScriptInterp::signal(const char *trapname){	unsigned long mask, cmask;	Line *line = getLine();	if(!image)		return true;	MutexLock lock(*this);	cmask = mask = cmd->getTrapMask(trapname);	mask &= line->mask;	mask &= frame[stack].mask;	if(frame[stack].line)		mask &= frame[stack].line->mask;		if(exiting)		mask &= ~1;	if(!mask)		return false;//	stop(mask);	trap(trapname);	branching();	image->fastBranch(this);	return true;}bool ScriptInterp::signal(unsigned id){	unsigned long mask, cmask;	if(!image)		return true;	if(!id && exiting)		return false;	MutexLock lock(*this);	if(id >= TRAP_BITS)		return false;	cmask = mask = cmd->getTrapMask(id);	mask &= frame[stack].mask;	if(frame[stack].line)		mask &= frame[stack].line->mask;	if(!mask)		return false;//	stop(mask);	trap(id);	branching();	image->fastBranch(this);	return true;}const char *ScriptInterp::hasOption(void){	for(;;)	{		if(frame[stack].index >= frame[stack].line->argc)			return NULL;		if(*frame[stack].line->args[frame[stack].index] != '=')			break;		frame[stack].index += 2;	}	return frame[stack].line->args[frame[stack].index];}const char *ScriptInterp::getOption(const char *def){        for(;;)        {                if(frame[stack].index >= frame[stack].line->argc)                        return (char *)def;                if(*frame[stack].line->args[frame[stack].index] != '=')                        break;                frame[stack].index += 2;        }        return frame[stack].line->args[frame[stack].index++];}const char *ScriptInterp::getSymbol(const char *id){	const char *val = getExternal(id);	Symbol *sym;	if(val)		return val;	sym = mapSymbol(id);	if(!sym)		return NULL;	return extract(sym);}	Script::Symbol *ScriptInterp::getSymbol(unsigned short size){	const char *id = getOption(NULL);	if(!id)		return NULL;	if(*id != '%' && *id != '&' && *id != '@')		return NULL;	return mapSymbol(id, size);}	const char *ScriptInterp::getMember(void){	const char *cp = strchr(frame[stack].line->cmd, '.');	if(cp)		++cp;	return cp;}const char *ScriptInterp::getKeyoption(const char *kw){        unsigned idx = 0;        Line *line = frame[stack].line;        const char *opt;        while(idx < line->argc)        {                opt = line->args[idx++];                if(*opt == '=')                {                                  if(!strnicmp(kw, opt + 1, strlen(kw)))                                return line->args[idx];                        ++idx;                }	}	return NULL;}const char *ScriptInterp::getKeyword(const char *kw){        unsigned idx = 0;        Line *line = frame[stack].line;        const char *opt;        while(idx < line->argc)          {                       opt = line->args[idx++];                    if(*opt == '=')                {                        if(!strnicmp(kw, opt + 1, strlen(kw)))                                return getContent(line->args[idx]);                        ++idx;                }        }        return NULL;}Script::Symbol *ScriptInterp::getKeysymbol(const char *kw, unsigned size){	const char *opt = getKeyoption(kw);	Symbol *sym;	if(!opt)		return NULL;	if(*opt != '&')		return NULL;	sym = mapSymbol(opt, size);	if(!sym)		logmissing(opt);	return deref(sym);}const char *ScriptInterp::getSymContent(const char *opt){	Symbol *sym;	if(!opt)		return NULL;	if(*opt != '&')		return getContent(opt);	sym = mapSymbol(++opt);	if(sym)		return extract(sym);	logmissing(opt);	return NULL;}const char *ScriptInterp::getContent(const char *opt){	Symbol *sym;	const char *val;	char *tmp;	Array *a;	ScriptProperty *p;	long v;	if(!opt)		return NULL;	if(*opt == '%' && !opt[1])		return opt;	if(*opt == '{')		return ++opt;	if(*opt == '#')	{		tmp = getTemp();		val = getExternal(++opt);		if(val)		{			snprintf(tmp, 11, "%ld", strlen(val));			return tmp;		}		sym = mapSymbol(opt);		if(!sym)		{			logmissing(opt);			return NULL;		}		tmp = getTemp();		a = (Array *)&sym->data;		switch(sym->type)		{		case symARRAY:			snprintf(tmp, 11, "%d", a->tail);			return tmp;		case symCONST:		case symNORMAL:			snprintf(tmp, 11, "%ld", strlen(sym->data));			return tmp;		case symCOUNTER:			snprintf(tmp, 11, "%ld", atol(sym->data));			return tmp;		case symTIMER:			if(!sym->data[0])			{				setString(tmp, 11, "999999999");				return tmp;			}			v = atol(extract(sym));			if(v < 0)				snprintf(tmp, 11, "%ld", -v);			else				setString(tmp, 11, "0");			return tmp;		case symINITIAL:			return "0";		case symPROPERTY:			opt = sym->data + sizeof(ScriptProperty *);			memcpy(&p, &sym->data, sizeof(p));			snprintf(tmp, 11, "%ld", p->getValue(opt));			return tmp;	        case Script::symSTACK:        	case Script::symFIFO:                	if(a->tail >= a->head)                        	snprintf(tmp, 11, "%d", a->tail - a->head);                	else                        	snprintf(tmp, 11, "%d", a->count - (a->tail - a->head));                	return tmp;		default:			return NULL;		}			}	if(*opt != '%' && *opt != '@')		return opt;	if(*opt != '@')	{		++opt;		val = session->getExternal(opt);		if(val)			return val;	}	sym = mapSymbol(opt);	if(sym)		return extract(sym);	logmissing(opt);	return NULL;}const char *ScriptInterp::getValue(const char *def){	const char *opt = getOption(NULL);	if(!opt)		return def;		opt = getContent(opt);	if(!opt)		return def;	return opt;}	void ScriptInterp::logerror(const char *msg, const char *scrname){	if(!scrname && frame[stack].script)		scrname = frame[stack].script->name;	if(scrname)		slog.error() << logname << ": " << scrname << ": " << msg << endl;	else		slog.error() << logname << ": " << msg << endl;}void ScriptInterp::logmissing(const char *sym, const char *reason, const char *group){	char msg[65];        if(*sym == '@' || *sym == '%' || *sym == '&')                ++sym;	if(!frame[stack].line)		return;        slog.warn() << logname << ": " << frame[stack].script->filename                << "(" << frame[stack].line->lnum << "): " << group << " "                << sym << " " << reason << endl;	snprintf(msg, sizeof(msg), "%s(%d): %s %s",		frame[stack].script->filename, frame[stack].line->lnum, group, sym);	cmd->enterMutex();	if(image->getLast(msg))	{		cmd->leaveMutex();		return;	}	image->setValue(msg, reason);	if(!stricmp(reason, "undefined"))		reason = "missing";	cmd->errlog(reason, msg);	cmd->leaveMutex();}bool ScriptInterp::done(void){	if(!stack && !frame[stack].line && exiting)		return true;		return false;}bool ScriptInterp::catSymbol(const char *id, const char *value, unsigned short size){	Symbol *sym;	if(!id)		return false;	if(!value)		return true;	while(*id == '%' || *id == '&' || *id == '@')		++id;	if(!*id)		return false;	MutexLock local(*this);	if(strchr(id, '.') && session != this)		MutexLock sess(*session);	sym = mapSymbol(id, size);	if(!sym)		return false;	return append(sym, value);}	bool ScriptInterp::putSymbol(const char *id, const char *value, unsigned short size){	Symbol *sym;	if(!id)		return false;	if(!value)		value = "";	while(*id == '&' || *id == '%' || *id == '@')		++id;	if(!*id)		return false;	MutexLock local(*this);	if(strchr(id, '.') && session != this)		MutexLock sess(*session);	sym = mapSymbol(id, size);	if(!sym)		return false;	return commit(sym, value);}bool ScriptInterp::getSymbol(const char *id, char *buffer, unsigned short size){	Symbol *sym;	const char *cp;	if(!id)		return false;	if(!buffer)		return false;	while(*id == '&' || *id == '%' || *id == '@')		++id;	if(!*id)		return false;	MutexLock local(*this);	if(strchr(id, '.') && session != this)		MutexLock sess(*session);	sym = mapSymbol(id);	if(!sym)		return false;	*buffer = 0;	cp = extract(sym);	if(!cp)		return false;	setString(buffer, size, cp);	return true;}timeout_t ScriptInterp::getTimeout(void){	if(!thread)		return 0;	return thread->getTimeout();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -