发布太极语言部分解释器
(太极元年丙戌三月二十九日辰时发布)
我先发布太极语言一部分的解释器,能解释运行一些太极语言程序。
我重点做的是编译部分,但还没最后完成,不过解释器倒好做,现在先发布一部分。
把下面的例子程序保存成tj1.u,tj2.u……文件,
输入
taiji tj1.u
taiji tj2.u
……
就可以运行了。
例1.
int leijiahe(int n)
{
int i;i=0;
int j;j=0;
while(i<=n)
{
j=j+i;
i=i+1;
}
return j;
}
show(leijiahe(20));//显示
show(leijiahe(21));
int k;
k=leijiahe(10);
show(k);
例2.
void swap(int *p1;int *p2)
{
int i;
i=*p1;
*p1=*p2;
*p2=i;
}
int a;a=2;
int b;b=3;
swap(&a;&b);
show(a);
show(b);
例3.
type student
{
char * name;
int age;
int high;
};
student chen;
chen.name="wei";
chen.age=26;
student * pcw;
pcw=&chen;
pcw->high=170;
show(chenwei.name);
……
我将写文章全面的从0开始教太极语言。
我为什么这么早发布这个解释器呢?
看如下的C/C++代码:
int id=tj_compile(str);
tj_setMemberint(id,"x",x);
tj_setMemberint(id,"y",x);
tj_run(id);
int z=tj_getMemberint(id,"z");
tj_compile等函数都是导出函数,我把这些函数都做在了动态链接库中。
能猜出来这是在做什么吗?
比如说str是
"int x;/
int y;/
int z;/
z=x*x+y*y;"
上面的代码我注释一下:
int id=tj_compile(str);
//编译这个字符串
tj_setMemberint(id,"x",x);
tj_setMemberint(id,"y",x);
//设置x与y
tj_run(id);
//运行,
int z=tj_getMemberint(id,"z");
//取得z的值!
这样解释器可以与应用程序相交互!
再看一个:
char * str;
int color;
int bkcolor;
int RGB(int red;int green;int blue)
{
int c;
c=red+green*256+blue*256*256;
return c;
}
color=RGB(0;0;0);
bkcolor=RGB(255;255;255);
if(dllcall("kernel32.dll";"lstrcmp";str;"while")==0)
{
color=RGB(0;0;255);
bkcolor=RGB(208;12;243);
}
elseif(str[0]=='i')
{
color=RGB(255;255;255);
bkcolor=RGB(208;12;243);
}
elseif('0'<=str[0]&&str[0]<='9')
{
color=RGB(255;0;0);
bkcolor=RGB(255;255;255);
}
“太极宝鉴”是未来太极语言的开发环境。这是太极宝鉴配置文件(conf.txt),修改这个文件就可以自由设置显示颜色!这里把while设置成紫底蓝字,所有以i开头的词为紫底白字,数字为白底红字。现在你可以打开太极宝鉴试一下,看到了吧,你可以自己试着修改一下这个文件。以前我做过一个可以自由设置颜色的程序,但这次这个程序的设置自由到了这种程度!
你可以想想在太极宝鉴程序中的运行情况了——
这是一段C++代码:
……
int id=tj_compile(strfile);
tj_setMemberstr(id,"str",str1);//str1是要显示的
tj_run(id);
color=tj_getMemberint(id,"color");
bkcolor=tj_getMemberint(id,"bkcolor");
show(hdc,x,y,str,len,color,bkcolor);
……
太极宝鉴配置文件程序中的str为什么没初试化就被使用了呢?在tj_run前不是有一句tj_setMemberstr吗,这就是给str赋初值,tj_compile是编译并初始化全局名字空间。太极语言解释器实现了完全的与应用程序的沟通。太极宝鉴通过太极语言解释器可以完全自由的配置。这个用途是非常广泛的。比如离线浏览器或批量下载软件,把判断某个URL是要下载的格式的方法完全提供给使用者
int id=tj_compile(UserConfigFile);
tj_setMemberstr(id,"str",CurrentUrl);
tj_run(id);
match=tj_getMemberint(id,"match");
if(match)
Download(CurrentUrl);
UserConfigFile是使用者自己的配置文件内容,灵活的用太极语言判断是否要下载。你可以用类C/C++的那种方式来判断URL。
再给大家看一个例子:
type FILETIME
{
int a1;
int a2;
};
type WIN32_FIND_DATA
{
int dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
int nFileSizeHigh;
int nFileSizeLow;
int dwReserved0;
int dwReserved1;
char [260]cFileName;
char [14]cAlternateFileName;
} ;
WIN32_FIND_DATA wfd;
int hl;
hl=dllcall("Kernel32.dll";"FindFirstFileA";"*.*";&wfd);
show(wfd.cFileName);
while(dllcall("Kernel32.dll";"FindNextFileA";hl;&wfd)!=0)
{
show(wfd.cFileName);
show("/n");
}
运行后显示当前目录下所有文件。
太极宝鉴支持宏操作,你现在按F1,再按几下键盘,然后按F2,发生什么事情了?
F1是开始记录宏,F2是播放宏,再按F1就停止记录。
现在可以想想是怎么运行的了。
刚才的宏是被保存在“太极宝鉴.exe”所在目录下的"input.txt"文件中,打开看:
int id;
dllcall("太极宝鉴.dll";"input";id;97);
dllcall("太极宝鉴.dll";"input";id;97);
dllcall("太极宝鉴.dll";"input";id;113);
……
你把这个文件改成
int id;
int i;i=97;
while(i<97+26)
{
dllcall("太极宝鉴.dll";"input";id;i);
i=i+1;
}
再按F2,看到什么了?从a到z的26个字母。
dllcall是调用dll中的函数。
刚才有句代码:
if(dllcall("kernel32.dll";"lstrcmp";str;"while")==0)……
这是在调用kernel32.dll中的函数lstrcmp。
看dllcall("太极宝鉴.dll";"input";id;113):
input是太极宝鉴.dll中的一个函数。
太极宝鉴.exe--->taijidllr.dll--->太极宝鉴.dll--->太极宝鉴.exe
数据就在这些模块中互相传递,而且有taijidllr.dll解释太极语言代码。
用这种方式,任何软件都可以迅速建立宏机制!所需要考虑的仅仅是生成宏代码。
然后调用太极语言解释运行,宏中用dll调用反过来控制程序自身。
看下面的代码
#include
extern "C"
{
int __declspec(dllimport) __stdcall tj_compile(char * str);
int __declspec(dllimport) __stdcall tj_run(int id);
int __declspec(dllimport) __stdcall tj_setMemberint(int id,char * name,int n);
int __declspec(dllimport) __stdcall tj_setMemberstr(int id,char * name,char * str);
int __declspec(dllimport) __stdcall tj_getMemberint(int id,char * name);
char * __declspec(dllimport) __stdcall tj_getMemberstr(int id,char * name);
int __declspec(dllimport) __stdcall tj_runstr(int id,char * str);
}
#pragma comment(lib, "taijidllr.lib")
main()
{
char * str=
"int x;"
"int y;"
"y=x*x;";
int id=tj_compile(str);
tj_setMemberint(id,"x",3);
tj_run(id);
int y=tj_getMemberint(id,"y");
printf("y=%d",y);
}
现在能想到怎么实现宏机制吗?还有,能想到声明中最后一个函数是干什么用的吗?
下面的代码是太极宝鉴中的。
记录按键时:
if(remember)
{
char * str=new char[200];
sprintf(str,"dllcall(/"太极宝鉴.dll/";/"input/";id;%d);/r/n",key);
file_addline("input.txt",str);
};
(生成宏程序)
播放按键时:
int id=tj_compile(str);
tj_setMemberint(id,"id",(int)this);
tj_run(id);
(编译并运行宏程序,this指向当前窗口类实例)
run时会遇到这样的代码:
dllcall("太极宝鉴.dll";"input";id;97);
调用太极宝鉴.dll中的input函数。
太极宝鉴.dll中input函数的 C++源代码如下:
extern "C" int __declspec(dllexport) __stdcall input(int id,char key)
{
wintj * ptj=(wintj * )id;//当前窗口类实例
ptj->input(key);
return 1;
}
用这种方式,任何软件都可以迅速建立宏机制!而且宏是用的太极语言!基本与C/C++是兼容的,语法与C/C++很多是一样的,描述非常自由。你的C/C++库都可以拿来用上做为宏的函数库类库!我觉的这可比微软的VBA强多了吧?如果将来微软的Visual Studio , MS OFFICE 等都用太极语言来做宏机制……哈,那太好了!
我的 csdn blog:
http://blog.csdn.net/universee
目前太极语言解释器还未经过严格测试,如果你发现了问题,可以去我的blog上回复告诉我。
2006.4.22夜