引言
上面第1节,概要介绍了Lua1.0源代码的编译和执行过程,下面就让我们来看看真正的源代码吧。
main函数你在哪里?
任何一个可执行的程序都有一个main函数,那lua的main函数在哪里呢?在lua.c里面。
/*
** lua.c
** Linguagem para Usuarios de Aplicacao
** TeCGraf - PUC-Rio
** 28 Apr 93
*/
#include <stdio.h>
#include "lua.h"
#include "lualib.h"
int main (int argc, char *argv[])
{
int i;
if (argc < 2)
{
puts ("usage: lua filename [functionnames]");
return 0;
}
iolib_open ();
strlib_open ();
mathlib_open ();
lua_dofile (argv[1]);
return 0;
}
上面代码和原来默认下载的代码不一样,原因是我删掉了那些没用的干扰片段。我们从上面的代码可以看出main函数的主要操作有
- 检测参数是否符合要求
- 打开iolib, iolib_open() 这个主要作用是提供lua的对文件操作的函数
- 打开strlib,strlib_open() 这个主要作用是提供lua的对字符串操作的函数
- 打开mathlib, mathlib_open() 这个主要作用是提供了lua的一些数学函数
而最关键的一句是
lua_dofile (argv[1]);
这行代码是真正开始打开lua脚本文件,分析词法,语法和执行的语句。
现在我们简单介绍一下lua和c语言的相互操作
在c语言中,为了提供一个lua中可以执行的函数,首先必须得定义这个函数,然后使用lua_register来注册这个函数,这是一个宏。定义如下
#define lua_register(n,f) (lua_pushcfunction(f), lua_storeglobal(n))
这里我们看是lua_register实际上等于执行了两个函数操作lua_pushcfunction(f)和lua_storeglobal(n)。任何一个c函数都必须具有lua_CFunction的类型。然后才能够被lua注册,而后一个函数,则是将该c函数的参数入栈。
我们看到了lua_register的时候,不妨想想,既然如此,我们是否可以自己写个函数,然后注册给lua呢?最后在脚本中验证一下?
OK,可以的,让我们试试吧。捡简单的strlib来试试。在strlib.c文件中添加如下的函数
/**
Find the index of first occurance of sub_str from the right side
index=strrfind(str,sub_str)
*/
static void str_rfind(void)
{
int n;
char *s1,*s2;
lua_Object o1=lua_getparam(1);
lua_Object o2=lua_getparam(2);
if(!lua_isstring(o1) || !lua_isstring(o2))
{
lua_error("incorrect arguments to function `strfind'");
return;
}
s1=lua_getstring(o1);
s2=lua_getstring(o2);
n=strlen(s1)-(strstr(s1,s2)-s1);
lua_pushnumber(n);
}
/**
Find the character at position index
ch=strat(str,index)
*/
static void str_at(void)
{
char *s;
int index;
lua_Object o1=lua_getparam(1);
lua_Object o2=lua_getparam(2);
if(!lua_isstring(o1))
{
lua_error("incorrent arguments to function `strat'");
return;
}
s=strdup(lua_getstring(o1));
index=lua_getnumber(o2);
if(index>strlen(s)){
lua_error("index out of bound error to function `strat'");
return;
}
s[index]=0;
lua_pushstring(&s[index-1]);
free(s);
}
/**
check whether the string ends with sub_str
bool result=strendswith(str,sub_str)
*/
static void str_ends_with(void)
{
char *s1,*s2;
char *s1_sub;
lua_Object o1=lua_getparam(1);
lua_Object o2=lua_getparam(2);
int str_from_index=0;
int sub_len=0;
if(!lua_isstring(o1) || !lua_isstring(o2))
{
lua_error("incorrect parameters to function `strendswith`");
return;
}
s1=strdup(lua_getstring(o1));
s2=strdup(lua_getstring(o2));
sub_len=strlen(s2);
str_from_index=strlen(s1)-sub_len;
s1_sub=s1+str_from_index;
if(strcmp(s1_sub,s2)==0)
{
lua_pushnumber(1);
}
else
{
lua_pushnil();
}
free(s1);
free(s2);
}
然后在strlib_open函数中注册这三个函数
lua_register("strrfind",str_rfind);
lua_register("strat",str_at);
lua_register("strendswith",str_ends_with);
好了,编译吧。。。
脚本如下
a="apple"
print(strat(a,4))
print(strrfind(a,"pp"))
print(strendswith(a,"le"))
看看输出结果吧。。。是不是正确的。
重要事项:Lua的索引是从1开始的,不是从0,各位亲注意了。。。
版权所有,保留所有权利。