打印

【项目】FinC,C语言解释器

【项目】FinC,C语言解释器

FinC, a programming langauge & interpreter with C-like syntax 一个类似C语言的解释器,里面还带一个小型的shell(embedded-sample/interpreter),对于C程序员或许有些帮助,它实现了比较完整的C语言表达式命令行

页面:http://gro.clinux.org/projects/finc/
for example:(for语句)
finsh>>int i;
finsh>>for(i = 0; i < 10; i ++) printf("i = %d\n", i);
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
finsh>>

another: (前++、后++运算)
finsh>>int i = 0;
finsh>>printf("i++ = %d\n", i++);
i++ = 0
finsh>>printf("++i = %d\n", ++i);
++i = 2
finsh>>printf("++i++ = %d\n", ++i++);
++i++ = 3
finsh>>printf("i = %d\n", i);
i = 3

another: (位运算,十六进制输出,接上i = 3)
finsh>>printf("i << 2 = 0x%02x\n", i << 2);
i << 2 = 0x0c

another: (条件运算)
finsh>>i = 0;
finsh>>int j = 0;
finsh>>i = j == 0? 10 : 5;
finsh>>printf("i = %d\n", i);
i = 10

another: (字符串操作)
finsh>>string str = "Hello world";
finsh>>for(i = 0; i < string_length(str); i++) printf("%c\n", str);
H
e
l
l
o

w
o
r
l
d

......
其中没有"finsh>>"的,是shell的输出。

页面里也包括一些初步的文档,下一步的目标是朝C89标准迈进,实现强类型指针,多维数组(当前支持一维数组),应用方面0.3.x系列面向测试软件(和wxWidgets结合起来)。

TOP

神奇,前++,后++还有点问题。。。

再加几个example,还是基于finsh:
Ex1: (函数及函数指针)
finsh>>void _d(int d) { printf("%d\n", d); }
finsh>>pointer p;
finsh>>p = _d;
finsh>>int i = 0;
finsh>>_d(i);
0
finsh>>p(i);
0

Ex2: (结构体)
finsh>>struct tt{int id; string name;};
finsh>>tt t;
finsh>>t.id = 1;
finsh>>t.name = "Lee";
finsh>>printf("id: %d, name: %s\n", t.id, t.name);
id: 1, name: Lee

Ex3: (字符串操作)
finsh>>string str;
finsh>>str = "int main(int argc, char *argv[]){ printf(\"Hello, world\n\"); return 0; }";
finsh>>int i;
finsh>>i = string_find(str, "main");
finsh>>string main;
finsh>>main = string_sub(str, i, i + 4);
finsh>>printf("%s\n", main);
main

TOP

支持。

希望提供更全面点的说明呀。

TOP

OK,我有时间再把如何在C语言里嵌入FinC说说,让C语言具备C语言的解释能力

TOP

好啊,突出创意和项目特点,还有人们 FinC 有什么样的好处等等。多多益善啊。

TOP

在你的程序中使用FinC

在本文中将配合wxFinC来讨论如何在程序中使用FinC,wxFinC是一个FinC的简单C++包装。

FinC以库的形式提供给程序使用,提供一套API来操作FinC解释器,例如执行一个FinC语言的脚本文件,执行包含FinC语言描述的字符串等等,除次之外,它也提供了如何和FinC内部进行交互,例如载入一套FinC脚本以后,调用API去执行一个FinC的函数,或者运行完一个FinC语言的函数后获得其中的变量值等等比较高级的操作。

首先,FinC的APIs,所用到的结构体都定义在finclib.h文件中。(当初设计时还算比较精妙,用C代码写成,却使用了OO的思想,所以代码可能会看起来稍微有些怪,Anyway,开始可以不用管FinC内部的实现代码)

在使用FinC解释器时,需要有一个FinC的环境,结构体struct _FinC描述了它,所以首先wxFinC需要有一个FinC的成员FinC* m_pFinC,即:
class wxFinC
{
private:
        FinC* m_pFinC;
};

而使用时,m_pFinC必须由FinC解释器来分配(注意:FinC解释器中由严格的内存分配方式,不要试图操作FinC解释器中的内存对象)
wxFinC::wxFinC()
{
        m_pFinC = finc_init();
}

而在不再使用FinC时,也就是退出,需要把分配的对象还回给FinC解释器。
wxFinC::~wxFinC()
{
        finc_exit(m_pFinC);
}

OK,现在m_pFinC环境已经建立起来了,如何解释执行自己的FinC脚本呢?对wxFinC添加两个函数,RunScript,RunString,分别让FinC解释器解释执行FinC脚本文件,和包含FinC脚本的字符串。
int wxFinC::RunScript(wxString& filename)
{
        finc_run_script(m_pFinC, filename.c_str());

        return 0;
}

int wxFinC::RunString(wxString& str)
{
        finc_run_string(m_pFinC, str.c_str());

        return 0;
}

使用如上几种方法已经能够执行脚本程序了,但是只能使用语言的基本功能,如何直接和机器打交道呢?FinC允许直接向脚本环境注入API,使得FinC脚本能够直接调用本地的函数:
void finc_insert_func(FinC* self, unsigned char* p_name, void* p_func, unsigned char* p_rettype, ...);

那么有必要再添加方法:AddFunc
int wxFinC::AddFunc(wxString& func_name, void* func, wxString& return_type)
{
        finc_insert_func(m_pFinC, func_name.c_str(), func, return_type.c_str());

        return 0;
}

其中,
func_name是反应到FinC脚本里的名称,可以和实际的系统函数名无关。
func是系统函数指针。
return_type是系统函数的返回值。
那么函数的参数呢?由于FinC解释器对类型检查得并不严格,而是直接在调用时把所有的参数都传递给系统函数,所以函数参数可以省略掉。。。当然,代价就是,如果在执行FinC脚本时,调用系统函数参数错误将很可能导致程序崩溃。

还有什么?应该还有更多,欢迎你来补充。

完整的wxFinC代码:
/* -- file: wxfinc.h -- */
#ifndef __WX_FINC_H__
#define __WX_FINC_H__

#include "libfinc.h"

#include "wx/string.h"

class wxFinC
{
public:
        wxFinC();
        virtual ~wxFinC();

        int RunScript(wxString& filename);
        int RunString(wxString& str);

        int AddFunc(wxString& funcname, void* func, wxString& return_type);

private:
        FinC* m_pFinC;
};

#endif

/* -- file: wxfinc.cpp -- */
#include "wxfinc.h"

wxFinC::wxFinC()
{
        m_pFinC = finc_init();
}

wxFinC::~wxFinC()
{
        finc_exit(m_pFinC);
}

int wxFinC::RunScript(wxString& filename)
{
        finc_run_script(m_pFinC, filename.c_str());

        return 0;
}

int wxFinC::RunString(wxString& str)
{
        finc_run_string(m_pFinC, str.c_str());

        return 0;
}

int wxFinC::AddFunc(wxString& funcname, void* func, wxString& return_type)
{
        finc_insert_func(m_pFinC, funcname.c_str(), func, return_type.c_str());

        return 0;
}

TOP

接下去是什么?嗯,将是FinC 0.3系列的应用方面的实作:Test Execute。

Test Execute,用于测试领域的测试工具,主要是针对C语言程序的测试,特别是嵌入式设备方面的测试。(需要修改部分FinC的API接口,实现更加完整的wxFinC类,但是这个版本暂时不另发布,直接归到0.3.5中去)
另外得向0.3.5迈进,主要是实现*,&操作符,把pointer彻底的踢掉……

TOP

好啊,请搂主继续介绍,能把特色总结一下吗?这样可以当作项目的介绍!

TOP

FinC简介

FinC是一套语法类似C语言的编程语言解释器(The interpreter of a programming language):
0.3系列版本内部完全解释执行,不产生任何中间代码,支持C语言的基本数据类型(char/short/int/long/float),基本指针,字符串,结构体,一维数组等,支持?/:三项式语句,逗号语句,if/else条件语句,for/while循环,支持函数,支持调用系统函数。0.3系列的目标就是和C89完全兼容。
0.4系列版本将能够直接运行于Java虚拟机,并给出一个完全嵌入式设备上的Java虚拟机实现(二进制代码尺寸:32k、64k及以上级别)。

FinC也是一个实现非常短小的解释器,编译后二进制文件大小在100k左右,剪裁版本Finsh可完全用于嵌入式设备实现vxWorks shell类似的功能,而其大小仅在几k。

FinC 0.3系列的应用方向主要向两个方向发展:
- 全功能的FinC,用于C语言应用程序的测试(TestExecute),可以把一个动态链接库直接导入到解释器中,采用交互式或批处理的方式执行测试;交互式,能通过shell的形式直接调用动态链接库中的函数,查看/修改全局变量。
- 剪裁版本的Finsh,用于和TestExecute配合使用,能够在shell状态下交互的执行嵌入式设备中的函数,查看/修改变量、内存数据、设备寄存器等等。

TOP

FinC的初始目标:面向嵌入式领域的编程语言
所以它非常强调小、小、再小,实时、实时、再实时(实时特性现在无)

FinC 0.3曾被移植到多个系统,Linux/Win32/vxWorks/Nucleus以及DOOLOO RTOS……(嗯,终于算是和老大谈妥了,DOOLOO RTOS就要开放源代码,这个才是一个真正意义上的国产实时操作系统,大概今年年底代码 + 文档都会面世的,三年的心血啊

FinC 0.3系列内部实现概况:
完全采用C实现,但是极大的考虑了OO的思想,内部实现一个小型的OO C库: tiny
具备完整的词法分析&语法分析(也包含丰富的错误处理信息的,但是为了保持小型的体积把它给删除了)
完全手工完成的词法分析&语法分析程序

* 现在采用手工完成的词法分析&语法分析是越来越少,而有一个象FinC这么完备的LL(1)词法分析、语法分析好像也不多见,除了tcc,其他基本都是用yacc & flex自动生成出来的

TOP

看起来不错 :-)

TOP

我的新房快要到手了,我希望能设计一个家庭智能灯光系统,具体的要求很简单,就是判断门的开闭状态变化,然后自动的点亮房间里的灯光。

程序写起来非常非常的简单,但是我从来没有接触过嵌入式编程,不知道耀想实现我的想法,需要什么芯片,然后怎样写程序,怎样编译,最后怎样把这个程序烧到我买的芯片里面去,最后接上电路实现这个想法?
http://8bao.info

如果你更热爱金钱而非自由,更习惯于被奴役的安宁而
畏惧令人充满活力的争取自由的抗争,那么,请你静静
地走开。我们不会乞求你的建议或是帮助。伏下身去讨
好那喂养你的人吧。但愿身上的锁链不会给你造成太多
的痛苦,但愿未来的人们不会记起你曾经是我们的国人

TOP

灯光控制?
FinC不是一个嵌入式系统,是嵌入式系统中的一个应用,想要实现你的功能,估计你得把嵌入式相关的知识恶补一顿才行了

TOP

[quote:da658bb75e="atfa"]我的新房快要到手了,我希望能设计一个家庭智能灯光系统,具体的要求很简单,就是判断门的开闭状态变化,然后自动的点亮房间里的灯光。

程序写起来非常非常的简单,但是我从来没有接触过嵌入式编程,不知道耀想实现我的想法,需要什么芯片,然后怎样写程序,怎样编译,最后怎样把这个程序烧到我买的芯片里面去,最后接上电路实现这个想法?[/quote]
搞这么神奇?那白天呢?也开灯吗?我们的汽车上都有这个功能,一开门,灯会亮的!其实他是在门那边装了一个开并,门关上时,开关就关上了,打开时开关就开了! 好像不需要芯片的说!
房子已造好,努力盖工厂...

TOP

[quote:c6ccc8b095="wxMidnight"]灯光控制?
FinC不是一个嵌入式系统,是嵌入式系统中的一个应用,想要实现你的功能,估计你得把嵌入式相关的知识恶补一顿才行了[/quote]

恶补    老大太看得起我了,对我而言,嵌入式的知识应该叫做学习,而不是补习啊……嵌入式知识=0

[quote:c6ccc8b095="Kan"]
搞这么神奇?那白天呢?也开灯吗?我们的汽车上都有这个功能,一开门,灯会亮的!其实他是在门那边装了一个开并,门关上时,开关就关上了,打开时开关就开了! 好像不需要芯片的说![/quote]

老大啊,你回家后为了保持灯光打开就从来不关门?

我举一个例子:你回家后进门,客厅灯光自动打开,你离开客厅来到卧室,卧室自动开灯,客厅就关了,或者关一半。现在你老婆回家了,进门后客厅灯光自动打开!而不是关掉!现在你老婆也进入卧室,具体进去做什么我就不知道了 现在系统需要做的不是把刚才的灯光状态++,这样灯就关了,系统需要判断出这一次开门关门的事件是因为什么原因,最后决定保持灯光不变。过了1个小时,你们把事情搞定了 双双走出卧室,系统需要检测到这个信息,把卧室灯光全部关掉,而不是因为门的开闭状态只改变了一次,而误以为卧室里面还有一个人继而保持灯光的打开。

这就是我需要的系统,我想我们需要在房间的每一片地砖下安装感应装置或者在整个房间里面安装红外线设备才能准确的捕捉这些信息。
http://8bao.info

如果你更热爱金钱而非自由,更习惯于被奴役的安宁而
畏惧令人充满活力的争取自由的抗争,那么,请你静静
地走开。我们不会乞求你的建议或是帮助。伏下身去讨
好那喂养你的人吧。但愿身上的锁链不会给你造成太多
的痛苦,但愿未来的人们不会记起你曾经是我们的国人

TOP