Lua code compilation

Lua 虽然是脚本解释语言, 在运行前需要预编译, 同时lua还支持代码预加载操作, 预编译操作等. 

在lua代码中  1. 使用load可以将文本转换成匿名函数,  2. 使用loadfile可以将外部文件转换成匿名函数. 3. 匿名函数可以赋予给一个变量然后调用, 或者直接使用()调用.

> a=1
> load("a=a+1 print(a)") ()
2
> f=load("a=a+1 print(a)")
> f()
3
load("a = a+1")
效果"等同"于
function () a = a+1 end

但实际上是有差别的,  1. load的效率远低于直接定义函数,  2. 另外, LOAD是有全局环境.

例如 : 

> do
>> a = 100
>> local a = 1
>> f1 = function () a=a+1 print("1:" .. a) end
>> f1()
>> f2 = load("a=a+1 print(a)")
>> f2()
>> end
1:2  -- f1输出本地变量的值
101  -- f2输出全局变量的值

注意, load和loadfile期望文本为chunk内容, 如果是表达式的话, 可在表达式前添加return返回表达式的值. 

例如 : 

> f = load("a")
> print (f)
nil
> f()
stdin:1: attempt to call global 'f' (a nil value)
stack traceback:
        stdin:1: in main chunk
        [C]: in ?
改成 :
> f = load("return a")  -- 返回表达式的值
> f()
> print(f())
nil

load和loadfile只是预加载代码, 并不会执行它, 只有执行了这个匿名函数后, 里面的代码才会得以执行. 

例如 : 

> f1 = load("f2 = function() a=99 print(a) end")
> f2()  -- 直接调用f2是不行的, 因为f1还没有执行.
stdin:1: attempt to call global 'f2' (a nil value)
stack traceback:
        stdin:1: in main chunk
        [C]: in ?
> f1()  -- f1被调用后, f2函数就存在了.
> f2()
99
> f3 = load("b=0")  -- b的定义同样要在f3函数调用后才会被执行
> print(b)
nil
> f3()
> print(b)
0

load和loadfile不检查文本的内容, 如果非法的话, 返回nil, 同时输出错误信息.

> print(load("err"))
nil     [string "err"]:1: syntax error near <eof>
> f = load("err")
> print(f)
nil

使用assert函数可以判断load和loadfile加载的内容是否正确(是否为nil), 如果为nil的话, 返回错误.

详见末尾assert的介绍.

> assert( load("err") )
stdin:1: [string "err"]:1: syntax error near <eof>
stack traceback:
        [C]: in function 'assert'
        stdin:1: in main chunk
        [C]: in ?

如果正确则返回参数值(匿名函数)

> f = assert( load("a=1 print(a)") )
> print(f)
function: 0x204eae0
> f()
1
> assert(nil)
stdin:1: assertion failed!
stack traceback:
        [C]: in function 'assert'
        stdin:1: in main chunk
        [C]: in ?
> assert(nil,"nihao")
stdin:1: nihao
stack traceback:
        [C]: in function 'assert'
        stdin:1: in main chunk
        [C]: in ?
> = assert(1,"nihao")
1       nihao
> a = assert(1,"nihao")
> print(a)
1

dofile是对loadfile封装后调用这个匿名函数 : 

function dofile (filename)
  local f = assert(loadfile(filename))
  return f()
end
> do
>> print ("enter function to be plotted (with variable 'x'):")
>> local l = io.read()
>> local f = assert(load("local x = ...; return " .. l))
>> for i=1,20 do
>>   print( string.rep("*", f(i)) )
>> end
>> end
enter function to be plotted (with variable 'x'):
x  -- 输入x
*
**
***
****
*****
******
*******
********
*********
**********
***********
************
*************
**************
***************
****************
*****************
******************
*******************
********************

string.rep($1, $2) 将$1复制$2遍. 如string.rep("*", 10) 复制星号10遍.

load可以使用reader函数作为参数, 从reader函数读取输入, 直到输入为nil.

例如load(io.lines(filename, "*L"))

这里的io.lines(filename, "*L") 返回一个reader函数, 调用这个函数从文件中每次读取1行.

http://blog.163.com/digoal@126/blog/static/16387704020141188350795/

load使用reader函数作为参数时, 从reader输入直到nil.

所以load(io.lines(filename, "*L")) 和 loadfile("filename")效果是一样的.

参考 : 

load (ld [, source [, mode [, env]]])

Loads a chunk.

If ld is a string, the chunk is this string. If ld is a function, load calls it repeatedly to get the chunk pieces. Each call to ld must return a string that concatenates with previous results. A return of an empty string, nil, or no value signals the end of the chunk.

If there are no syntactic errors, returns the compiled chunk as a function; otherwise, returns nil plus the error message.

If the resulting function has upvalues, the first upvalue is set to the value of env, if that parameter is given, or to the value of the global environment. (When you load a main chunk, the resulting function will always have exactly one upvalue, the _ENV variable (see §2.2). When you load a binary chunk created from a function (see string.dump), the resulting function can have arbitrary upvalues.)

source is used as the source of the chunk for error messages and debug information (see §4.9). When absent, it defaults to ld, if ld is a string, or to "=(load)" otherwise.

The string mode controls whether the chunk can be text or binary (that is, a precompiled chunk). It may be the string "b" (only binary chunks), "t" (only text chunks), or "bt" (both binary and text). The default is "bt".

loadfile ([filename [, mode [, env]]])

Similar to load, but gets the chunk from file filename or from the standard input, if no file name is given.

assert (v [, message])

Issues an error when the value of its argument v is false (i.e., nil or false); otherwise, returns all its arguments. message is an error message; when absent, it defaults to "assertion failed!"

时间: 2024-10-30 15:56:38

Lua code compilation的相关文章

Serializing Lua objects into Lua Code

The following little snippet allows you to 'pickle' Lua objects directly into Lua code (with the exception of functions, which are serialized as raw bytecode). Metatable support is on the way, but for now, it should be useful enough. Example code: vi

Embedding Lua, in Scala, using Java(转)

LuaJ I was reading over the list of features that CurioDB lacks compared to Redis , that I'd previously documented. It contained the item "no Lua scripting", which I'd written confidently at the time, certain that I wouldn't possibly be able to

Lua教程(十九):C调用Lua_Lua

1. 基础:     Lua的一项重要用途就是作为一种配置语言.现在从一个简单的示例开始吧.   复制代码 代码如下:     --这里是用Lua代码定义的窗口大小的配置信息     width = 200     height = 300       下面是读取配置信息的C/C++代码:   复制代码 代码如下: #include <stdio.h> #include <string.h> #include <lua.hpp> #include <lauxlib

Lua数据结构 &amp;#8212; 闭包(四)

作者:罗日健 前面几篇文章已经说明了Lua里面很常用的几个数据结构,这次要分享的也是常用的数据结构之一 – 函数的结构.函数在Lua里也是一种变量,但是它却很特殊,能存储执行语句和被执行,本章主要描述Lua是怎么实现这种函数的. 在脚本世界里,相信闭包这个词大家也不陌生,闭包是由函数与其相关引用环境组成的实体.可能有点抽象,下面详细说明: 一. 闭包的组成 闭包主要由以下2个元素组成: 函数原型:上图意在表明是一段可执行代码.在Lua中可以是lua_CFunction,也可以是lua自身的虚拟机

Lua所有内置函数罗列_Lua

在大多数Lua语法分析中可以获得这些标准Lua函数. 无可争辩, 我们可以查阅Lua网站, 但是一些少了的函数被Blizzard进行了调整. 下面列出了所有Lua函数. WoW API中的Lua注意在WoWAPI没有提供所有标准的Lua函数, 很显然, 操作系统以及文件I/O库是不支持的 Lua函数这些函数都是Lua编程语言的一部分, 点击这里了解更多. •assert(value) - 检查一个值是否为非nil, 若不是则(如果在wow.exe打开调试命令)显示对话框以及输出错误调试信息 •c

Lua中的常用函数库汇总_Lua

lua库函数 这些函数都是Lua编程语言的一部分, 点击这里了解更多. assert(value) - 检查一个值是否为非nil, 若不是则(如果在wow.exe打开调试命令)显示对话框以及输出错误调试信息 collectgarbage() - 垃圾收集器. (新增于1.10.1) date(format, time) - 返回当前用户机器上的时间. error("error message",level) - 发生错误时,输出一条定义的错误信息.使用pcall() (见下面)捕捉错误

使用Lua来扩展C++程序的方法_Lua

 介绍 如果用户能够通过一些脚本语言来修改应用本身的行为,那么许多应用可以变得更适合用户使用.一些商业应用就提供了此类便利.例如 Microsoft Office 的 VBA 脚本编程或在视频游戏 World of Warcraft 中使用 Lua .脚本语言把应用作为一个平台提供一系列终端用户可以获得并操控的服务. 做为嵌入到程序中的语言,我们有很多可用的选择:开源和不开源的脚本引擎,或者可以从头开始创建一个.现在,最为熟知的脚本语言是JavaScript,Lua和Python,还有很多其它的

Awesome Torch

Awesome Torch  This blog from:    A curated list of awesome Torch tutorials, projects and communities. Table of Contents Tutorials Model Zoo Recurrent Networks Convolutional Networks ETC Libraries Model related GPU related IDE related ETC Links Tutor

嵌入式设备web服务器比较

目录(?)[-] Boa Thttpd Mini_httpd Shttpd Lighttpd Goahead AppWeb Apache 开发语言和开发工具 结论 备注   现在在嵌入式设备中所使用的web服务器主要有:boa.thttpd.mini_httpd.shttpd.lighttpd.goaheand.appweb和apache等. Boa 1.介绍 Boa诞生于1991年,作者Paul Philips.是开源的,应用很广泛,特别适合于嵌入式设备,网上流行程度很广.它的官方网站说boa