Welcome to Scribd, the world's digital library. Read, publish, and share books and documents. See more
Download
Standard view
Full view
of .
Look up keyword
Like this
1Activity
0 of .
Results for:
No results containing your search query
P. 1
Lua Programming the Next Generation

Lua Programming the Next Generation

Ratings: (0)|Views: 7|Likes:
Published by Mikhail Miguel

More info:

Published by: Mikhail Miguel on Feb 12, 2012
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

07/22/2014

pdf

text

original

 
The basic structure of Lua (pro-nounced LOO-ah, and whose namemeans
moon
in Portuguese) is that of alanguage interpreter (the program,
lua
)which generates and runs byte code, aset of optional basic libraries (for inputand output, maths, and so on, all writtenin standard C), and a compiler (
luac 
) togenerate byte code offline. Because of the highly standard nature of the Luacode base, it works on almost any plat-form that sports a C compiler. The Linuxversion clocks in at just over 100K, withthe combined set of default libraries tak-ing a further 72K. Many embeddedprojects have taken advantage of itssmall size (and its ability to build any-where), as have several gamescompanies, such as Criterion Studios,LucasArts (Grim Fandango), andBioWare (with MDK2 and Baldur’sGate). For a longer list of uses visit [1].
HarvestMoon
As a language, it has all the featuresyou’d expect from a functional scriptinglanguage, including the obligatory onlinemanual, available at [2]. First off, wehave the data types. These may not beplentiful (see Table 1: Lua Types), butthey are capable of satisfying a program-mers usual desires. The variablesthemselves follow the ideals of a loosely-typed language, and so can hold anytype it pleases, at any particular time.Attempting to use undefined variablescauses them to have the type
nil
, whichcan cause some operations (for example,string concatenation) to fail. The Luaconcept of a ‘number’ is equivalent tothe C type
double
. However, perfor-mance junkies (using version 5) canchange this to
float 
(or even
int 
) andrecompile
 Lua
. Just add
#define LUA_NUMBER float
before #
include
ing
lua.h
. Anyone usingversion 4, or earlier, will need to manu-ally modify the code a little further.There is also a range of flow controlstatements, that fit the following:
do
block
end• while
exp
do
block
end• repeat 
block
until
exp
if 
exp
then
block
endif 
exp
then
block
else
otherblock
endif 
exp
then
block
elseif 
exp
then
otherblock
end
[and so on…]
• for 
var=start,end[,step]
do
block
end• for 
var
in
iterator
do
block
end
F
rom a linguistics point of view, Luacould be considered fairly ordinary!It has all the necessary features tomake it a usable language, but lacks anystrong selling points in the vein of Perl’sregular expressions, or C’s speed of exe-cution. Its strengths do not lie withindividual parts of the language, but howit functions as a whole, and how well itconnects with the outside world.We shall be looking at Lua as a cus-tomization and configuration tool,showing how the end user can cus-tomize particular software (using
elinks
as an example), and what steps must betaken in order to implement such func-tionality in their own applications.
The Whole Of The Moon
 Lua
began in 1993 as a language forBrazilian academics at Tecgraf, in thePontifical Catholic University of Rio de Janeiro (PUC-Rio). Its purpose was toprovide a simple method of extendingapplications through a basic procedurallanguage, traditional datatypes, and avirtual machine. All these features haveremained a fundamental part of 
 Lua
tothe present day, with therelease of version 5.0.2(for minor bug fixes) onMarch 17, 2004. Itsuptake has been assteady (some would sayslow) as its update cycle;just 12 public releases inits entire 11 year history.However, as a compensa-tion, there is little chanceof code breakingovernight, and everyrelease so far has beenincredibly stable.
As a scripting language,Lua is fairly unique.Ithas a strong following from twoniche markets:Linux users,and computer game programmers.Whatis itaboutthis language thatappeals? Whatis so special? Steven Goodwin investigates.
BY STEVEN GOODWIN
Lua – The NextGeneration
Moonshine
70
August
2004
www.linux-magazine.com
Lua
PROGRAMMING
www .  ph   o t   o c  a s  e . d   e
TypeIdentifierName for lua_is
type
etc
NilLUA_TNILnilNumberLUA_TNUMBERnumberBoolLUA_TBOOLEANbooleanStringLUA_TSTRINGstringTableLUA_TTABLEtableFunctionLUA_TFUNCTIONcfunctionUserdataLUA_TUSERDATAuserdata
Notes
The identifier can be used to translate the constantinto a string inside C,using
lua_typename(lua_State *L,int type)lua_isnumber 
accepts both numbers (123) and numerical strings (“123”)
lua_toboolean
returns 0 for
 false
and
nil 
,and 1 for everything else
Table 1:Lua Types
A comment, about a wry comment,commenting about programmeroriginality!function hello()write(“Hello, Lua!“)endhello()
Listing 1:hello.lua
 
Nothing unusual there, although Cprogrammers should be aware that the‘end’ value is also evaluated in the
for 
loop. Note that all statements use theword
end
as a block terminator, insteadof the more traditional brace. This sim-plicity is a very obvious attempt to coaxnon-programmers into the world of scripting. The preference of words oversymbols is also apparent when you real-ize the operators !, && and || have beenreplaced with their alphabetic counter-parts,
not 
,
and
, and
or 
.The syntax also removes some of therestrictions found in other languages. Forexample, two (or more) parameters canbe returned from functions, without anyproblem or esoteric magic.
function onetwo()return 1,2endone,two = onetwo()
Finally, Lua contains local and anony-mous functions. Taking these in order, alocal function is one that can only becalled from within the function it isdeclared in. This is uncommon to C pro-grammers, but fairly familiar toeverybody else. Secondly, anonymousfunctions mean we can embed an entirefunction in the place we would place acallback. This prevents additional, arbi-trary, functions within the code.For more detailed information on thesyntax, you’d do well to read the originalversion available at [2]. For an interac-tive experience, the message boards at[3] are available.However, Lua’s features as a languageare not what sells it to developers. It ismore its use as a configuration tool thatis considered its killer app. It is so easyfor an application developer to add Luascripting support that one wonders whyit’s not more prevalent. It can be used tocreate plug-in modules for software, oras a configuration file. This need not be astatic configuration, like most otherapplications. You can create somethingmuch more powerful and flexible. Some-thing dynamic!Dynamic configurations have beensomething of a rarity. Only the morecomplex applications, such as Apache,have them. Even then, directives such as
 IfModule
are fairly minimal, and havelimited scope. A truly dynamic configu-ration can ease the install process bypreparing itself when the program is run,and adapt itself according the directorystructure, number of users, currentbandwidth, processor load, and so on.
 Lua
also provides a method to addhooks into software for customization.We shall look at this, adding some sim-ple hooks into the text-browser
elinks
.
Dancing in the Moonlight
Hooks are a method whereby a program(in this case,
elinks
) calls a special func-tion every time it is about to dosomething important. This ‘somethingimportant’ might be when jumping to aURL, or downloading a page of HTMLfrom the server. Under normal, non-hooked, circumstances, this specialfunction will do nothing! Nada. Zip. Itwill simply return control back to themain program and let it jump to the URLit was going to jump to in the first place.However, when a hook is placed intothis special function, control is passedout of the main program into the hookfunction. At this point, the hook functionhas control of the data and can re-writethe URL, for instance. As these hooks areprogrammed from a Lua program –
our 
Lua program – we can re-write themaccording to our personal preferences.For example, I may wish to visit one of my own web sites,
www.BlueDust.com
,by typing
bd
. I could do this by creatinga simple hook into the ‘jump to URL’routine with:
if (url == “bd“) thenreturn “www.bluedust.com“end
Lo and behold, instant configuration!The demonstration program for thisarticle,
elinks
, has a number of differenthooks, and these are given in Table 2:Hooks and Crannies. We can use some of these to customize the application.As well as
elinks
calling our script, it ispossible for our script to call
elinks
through callbacks. This lets us retrieveinformation, such as the title page, thatisn’t passed through as a parameter. Thisis useful with key shortcuts as whatparameters should be passed in to them?URLs? Bookmark lists? This is where thecallback functions come into play.These callbacks are specific functionsthat
elinks
has decided that we (as ascript) may use. It allows us to call themas if they were part of the Lua scriptitself. They include functions such as
current_url
and
current_title
. A list is
71
www.linux-magazine.com
August
2004
PROGRAMMING
Lua
Hook functionCalled whenShould returnNotes
goto_url_hook(url,current_url)A URL is entered in the A new URL,or nil to cancel“Go to URL”dialogfollow_url_hook(url)A URL has been selectedA new URL,or nil to cancelpre_format_html_hook(url,html)Documenthas been Modified string,or nil if no Can remove adverts/junkdownloadedchanges were madefrom badly designed webpageslua_console_hook(string)Something is entered into A command (run,eval,the Lua console (type
 ,
goto-url,or nil) followed byin
elinks
)an appropriate argument(the program to run,Lua codeto evaluate,a URL to go to,ornil,respectively)quit_hook()
elinks
is aboutto exitNothingFor tidying up resources
Table 2:Hooks and Crannies
function goto_url_hook (url,current_url)if url == “tiny“ thenreturn“http://tinyurl.com/create.php?url=“..current_urlendreturn urlend
Listing 2:
goto_url_hook 
bind_key (“main“, “Ctrl-T“,function ()return “goto_url“,“http://tinyurl.com/create.php?url=“..current_url()end)
Listing 3:
bind_key 
function
 
our code is contained within
function
s, nothing shouldappear to happen on screen.The first of our functionswill include the code for
 goto_url_hook
. As previouslymentioned, this gets calledwhenever the user hits ‘g’ tochange web page. It is there-fore a simple matter to writeListing 2.It really is as easy as that!Reload
elinks
and visit yourleast unfavorite web site.Then press ‘g’, followed bythe keyword
tiny
, andreturn. If you’re like me andchose Google as your testsite, you’ll be taken to a webpage at
tinyurl.com
, asshown in figure 1.We can see the new url given as
http:// tinyurl.com/161
, which can then becopied, pasted, emailed, and generallymisused. If we knew how to add short-cuts to
elinks
we could save ourselvesfour keystrokes. Those of you who readTable 3: Odds and Sods earlier, alreadyknow about the function called
bind_key
. Yes! It is the right one, so we canadd the code as in Listing 3.This example demonstrates the useful-ness of anonymous functions, and theease by which two values can bereturned from a function. In this case,the command
 goto_url
, and the URLparameter for that command.To add some final polish we will eradi-cate the duplicate URL information bywriting our
hooks.lua
file as Listing 4.As you can see, Lua makes it very easyfor the end user to add functionality to apiece of software. You need nothingmore than the methods provided here,and a little imagination, to add a wholehost of other functionality. Generallyspeaking, adding flexibility for the enduser means complexity for the program-mer. With Lua, this is not the case! Let’slook at why…
Moonraker
In any extensible system like this, thereare three basic components. The initial-ization (and de-initialization), thecommunication in (where the scripttalks to our C program), and the commu-nication out (where C talks to the script).All three areas are very simple, andcan use the basic templates presentedhere. This simplicity has kept the Luainterpreter small, and encouraged pro-grammers to use it for configuration.Let us start at the beginning,
#include <lua.h>int main(int argc, char *argv[]){lua_State *pLua;pLua = lua_open();printf(“Hello, World!“);lua_close(pLua);return 0;}
given in Table 3: Odds and Sods. Weshall now employ both ideas to create asimple hook for
elinks
that creates a tinyurl for the current page.
Moondance
Our first task (to save headaches later) isto make sure
elinks
has actually beencompiled with Lua scripting support.You can check this by opening the
 About 
box by pressing
 Alt+H 
(to open the helpmenu), followed by the letter
 A
. Hereshould be the words,
Scripting (Lua)
This is included by default with mostdistros (and downloadable from [4]), if not, it can be rectified by a simple,
$./configure —with-lua$ make# make install
This will also create a sample
hooks.lua
file in the
elinks/contrib/lua
directory.We then need to create a script for
elinks
to run when it starts. This isplaced in
~/.elinks/hooks.lua
and is runin its entirety at startup. So provided all
72
August
2004
www.linux-magazine.com
Lua
PROGRAMMING
openfile,closefile,readfrom,writeto,appendto,pipe_read,remove,rename,flush,seek,tmpname,read,write execute,exit,clock,date,getenv,setlocale.
Box 1:enable_systems_functions
function get_tiny(url)return“http://tinyurl.com/create.php?url=“..urlendfunction goto_url_hook (url,current_url)if url == “tiny“ thenreturn get_tiny(current_url)endreturn urlendbind_key (“main“, “Ctrl-T“,function () return “goto_url“,get_tiny( current_url() ) end )
Listing 4:
hooks.lua
file
Figure 1:The resultof our hook function.
int compute(int n) { returnn<2?1:n*compute(n-1); }int c_factorial(lua_State *pLua){int params = lua_gettop(pLua);int n, result;int answers = 0;for(n=1; n<=params; n++) {if (lua_isnumber(pLua, n)) {result = compute(lua_tonumber(pLua, n) );lua_pushnumber(pLua,result);answers++;} else {// Error!break;}}return answers;}
Listing 5:
factorial 
routine

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->