专题:一个自制代码生成器(嵌入式脚本语言)之堆栈结构和总入口

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。


专题:一个自制代码生成器(嵌入式脚本语言)之总述-CSDN博客

专题:一个自制代码生成器(嵌入式脚本语言)之对象模型-CSDN博客

专题:一个自制代码生成器(嵌入式脚本语言)之堆栈结构和总入口-CSDN博客 (本篇)

专题:一个自制代码生成器(嵌入式脚本语言)之核心逻辑-CSDN博客

专题:一个自制代码生成器(嵌入式脚本语言)之辅助逻辑-CSDN博客

专题:一个自制代码生成器(嵌入式脚本语言)之应用实例-CSDN博客

专题:一个自制代码生成器(嵌入式脚本语言)之模型开发-CSDN博客


目录

一、堆栈概述

二、代码

三、总入口


一、堆栈概述

        此处“堆栈”指的是“栈”。栈是用来实现上下文关系的基本数据结构,最熟悉的场景就是函数调用。

        函数调用时函数参数被放在栈里面,函数返回后栈被清理。

        栈一般被描述为后进先出的结构,适合于表达上下文关系。

        作为脚本语言,自然要处理上下文关系,各种嵌套、循环都涉及到变量的覆盖问题。

        代码其实相当的简单,用vector就可以实现栈,要点是在每个正确的地方入栈和出栈。

二、代码

        栈结构用vector实现,每层是一个对象,为了方便,提供了三个直接操作栈顶的方法。

struct CCTStack : public vector<CCTObject >
{
	void Push()
	{
		CCTObject o;
		this->push_back(o);
	}
	void Pop()
	{
		this->pop_back();
	}
	bool AddRef(string const& objname, CCTObject * pObj)
	{
		if (0 == this->size())return false;
		this->rbegin()->SetObjectAddRef(objname, pObj);
		return true;
	}
	bool Add(string const& objname, CCTObject const& obj)
	{
		if (0 == this->size())return false;
		this->rbegin()->SetObjectAdd(objname, obj);
		return true;
	}
	bool AddProperty(string const& objname, string const& obj)
	{
		if (0 == this->size())return false;
		this->rbegin()->SetObjectAddProperty(objname, obj);
		return true;
	}

	string& toString(string& ret)const
	{
		string str;
		stringstream ss;
		for (const_iterator it = begin(); it != end(); ++it)
		{
			ss << "===============================" << endl;
			ss << it->toString(str) << endl;
		}
		return ret = ss.str();
	}
};

三、总入口

        总入口如下:

	//处理模板文件,输出到ss中
	bool ProcessTemplate(char const* templatefile, stringstream& ss, CCTObject& O, CCTStack& S)
	{
		m_functions.clear();

		CEasyFile file;
		string filedata;
		if (!file.ReadFile(templatefile, filedata))
		{
			thelog << "未能打开模板文件 " << templatefile << ende;
			return false;
		}
		long end = filedata.size();
		bool ret = _ProcessBlock(filedata, 0, end, ss, O, S);
		if (!ret)
		{
			thelog << "操作失败 " << templatefile << " 输出文件在出错处中止 " << ende;
		}

		//thelog << endl << ss.str() << endi;
		return ret;
	}
	bool ProcessFile(char const* infile, char const* outfile, CCTObject& O, CCTStack& S)
	{
		thelog << "开始处理 " << infile << " 输出到 " << outfile << endi;
		stringstream ss;
		bool ret = ProcessTemplate(infile, ss, O, S);
		//thelog << endl << ss.str() << endi;

		CEasyFile file;
		if (!file.WriteFile(outfile, ss.str().c_str()))
		{
			thelog << "写文件出错 " << outfile << ende;
			return false;
		}

		return ret;
	}

        前两个参数为输入文件和输出,输入文件是模板,输出是文本。两个接口的区别是一个输出到stringstream对象,一个输出到文件(其实调用了另一个)。

        第三个参数是对象模型,相当于预设的全局变量,可以在脚本任何地方引用。

        第四个参数是栈对象,一般不需要预设数据,不过如果有环境变量之类可以设置进去。

        脚本里面搜索对象时优先从堆栈搜索,堆栈里没有才从对象模型里搜索。

        调用示例:

		CCodeTemplate ct;
		CCTObject O;
		CCTStack S;
		stringstream ss;

		O.SetObjectAddProperty("sys", "aaaaaaaaaaaaa\n");

		if (!ct.ProcessTemplate("simplesample.ct", ss, O, S))
		{
			thelog << "执行失败" << ende;
		}
		thelog <<"========================="<< endl << ss.str() << endi;

        实际的处理逻辑从_ProcessBlock()开始,下一篇将详细解释。

(这里是结束,但不是整个系列的结束)

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值