Cours Programming in Lua Techniques for Writing C Functions, tutoriel & guide de travaux pratiques en pdf.
Types and Values
Lua is a dynamically typed language. There are no type de nitions in the language; each value carries its own type.
There are eight basic types in Lua: nil, boolean, number, string, userdata, function, thread, and table. The type function gives the type name of a given value:
print(type(« Hello world »)) –> string
print(type(10.4*3)) –> number
print(type(print)) –> function
print(type(type)) –> function
print(type(true)) –> boolean
print(type(nil)) –> nil
print(type(type(X))) –> string
The last line will result in string no matter the value of X, because the result of type is always a string.
Variables have no prede ned types; any variable may contain values of any type:
print(type(a)) –> nil (’a’ is not initialized)
a = 10
print(type(a)) –> number
a = « a string!! »
print(type(a)) –> string
a = print — yes, this is valid!
a(type(a)) –> function
Notice the last two lines: functions are rst-class values in Lua; so, we can manipulate them like any other value. (More about this facility in Chapter 6.)
Usually, when you use a single variable for different types, the result is messy code. However, sometimes the judicious use of this facility is helpful, for instance in the use of nil to differentiate a normal return value from an abnormal condition.
Nil
Nil is a type with a single value, nil, whose main property is to be different from any other value. As we have seen, a global variable has a nil value by default, before its rst assignment, and you can assign nil to a global variable to delete it. Lua uses nil as a kind of non-value, to represent the absence of a useful value.
Booleans
The boolean type has two values, false and true, which represent the tradi-tional boolean values. However, booleans do not hold a monopoly of condition values: in Lua, any value may represent a condition. Conditionals (such as the ones in control structures) consider both false and nil as false and anything else as true. Beware that, unlike some other scripting languages, Lua considers both zero and the empty string as true in conditional tests.
Numbers
The number type represents real (double-precision oating-point) numbers. Lua has no integer type, as it does not need it. There is a widespread misconception about oating-point arithmetic errors; some people fear that even a simple increment can go weird with oating-point numbers. The fact is that, when you use a double to represent an integer, there is no rounding error at all (unless the number is greater than 1014). Speci cally, a Lua number can represent any 32-bit integer without rounding problems. Moreover, most modern CPUs do oating-point arithmetic as fast as (or even faster than) integer arithmetic.
Nevertheless, it is easy to compile Lua so that it uses another type for numbers, such as longs or single-precision oats. This is particularly useful for platforms without hardware support for oating point. See le luaconf.h in the distribution for detailed instructions.
We can write numeric constants with an optional decimal part, plus an optional decimal exponent. Examples of valid numeric constants are:
4 0.4 4.57e-3 0.3e12 5e+20
Strings
Strings in Lua have the usual meaning: a sequence of characters. Lua is eight-bit clean and its strings may contain characters with any numeric code, including embedded zeros. This means that you can store any binary data into a string.
Strings in Lua are immutable values. You cannot change a character inside a string, as you may in C; instead, you create a new string with the desired modi cations, as in the next example:
a = « one string »
b = string.gsub(a, « one », « another ») — change string parts
print(a) –> one string
print(b) –> another string
Strings in Lua are subject to automatic memory management, like all other Lua objects (tables, functions, etc.). This means that you do not have to worry about allocation and deallocation of strings; Lua handles this for you. A string may contain a single letter or an entire book. Lua handles long strings quite ef ciently. Programs that manipulate strings with 100K or 1M characters are not unusual in Lua.
We can delimit literal strings by matching single or double quotes:
a = « a line »
b = ’another line’
As a matter of style, you should use always the same kind of quotes (single or double) in a program, unless the string itself has quotes; then you use the other quote, or escape these quotes with backslashes.
We can specify a character in a string also by its numeric value through the escape sequence \ddd, where ddd is a sequence of up to three decimal digits. As a somewhat complex example, the two literals « alo\n123\ » » and ’\97lo\10\04923″’ have the same value, in a system using ASCII: 97 is the ASCII code for ‘a’, 10 is the code for newline, and 49 is the code for the digit ‘1’. (In this example we must write 49 with three digits, as \049, because it is followed by another digit; otherwise Lua would read the number as 492.)
We can delimit literal strings also by matching double square brackets, as we do with long comments. Literals in this bracketed form may run for several lines and do not interpret escape sequences. Moreover, this form ignores the rst character of the string when this character is a newline. This form is especially convenient for writing strings that contain program pieces, as in the following example:
page = [[
<html>
<head>
<title>An HTML Page</title>
</head>
<body>
<a href= »http://www.lua.org »>Lua</a>
</body>
</html>
]]
write(page)
Sometimes, you may want to enclose a piece of code containing something like a=b[c[i]] (notice the ]] in this code). Or you may need to enclose some code that already has some code commented out. To handle such cases, you can add any number of equal signs between the two open brackets, as in [===[.2
After this change, the literal string ends only at the next closing brackets with the same number of equal signs in between (]===], in our example). Pairs of brackets with a different number of equal signs are simply ignored. By choosing an appropriate number of signs, you can enclose any literal string without having to add escapes into it.
This same facility is valid for comments, too. For instance, if you start a long comment with –[=[, it extends until the next ]=]. This facility allows you easily to comment out a piece of code that contains parts already commented out.
Lua provides automatic conversions between numbers and strings at run time. Any numeric operation applied to a string tries to convert the string to a number:
print(« 10 » + 1) –> 11
print(« 10 + 1 ») –> 10 + 1
print(« -5.3e-10″* »2 ») –> -1.06e-09
print(« hello » + 1) — ERROR (cannot convert « hello »)
Lua applies such coercions not only in arithmetic operators, but also in other places that expect a number.
Conversely, whenever Lua nds a number where it expects a string, it con-
verts the number to a string:
print(10 .. 20) –> 1020
(The .. is the string concatenation operator in Lua. When you write it right after a numeral, you must separate them with a space; otherwise, Lua thinks that the rst dot is a decimal point.)
Today we are not sure that these automatic coercions were a good idea in the design of Lua. As a rule, it is better not to count on them. They are handy in a few places, but add complexity to the language and sometimes to programs that use them. After all, strings and numbers are different things, despite these conversions. A comparison like 10== »10″ is false, because 10 is a number and 10 is a string. If you need to convert a string to a number explicitly, you can use the function tonumber, which returns nil if the string does not denote a proper number:
line = io.read() — read a line
n = tonumber(line) — try to convert it to a number if n == nil then
error(line .. » is not a valid number »)
else
print(n*2)
end
To convert a number to a string, you can call the function tostring, or concatenate the number with the empty string:
print(tostring(10) == « 10 ») –> true
print(10 .. « » == « 10 ») –> true
Such conversions are always valid.
In Lua 5.1, you can get the length of a string using the pre x operator ‘#’
(called the length operator):
a = « hello »
print(#a) –> 5
print(# »good\0bye ») –> 8
Tables
The table type implements associative arrays. An associative array is an array that can be indexed not only with numbers, but also with strings or any other value of the language, except nil. Moreover, tables have no xed size; you can add as many elements as you want to a table dynamically. Tables are the main (in fact, the only) data structuring mechanism in Lua, and a powerful one. We use tables to represent ordinary arrays, symbol tables, sets, records, queues, and other data structures, in a simple, uniform, and ef cient way. Lua uses tables to represent modules, packages, and objects as well. When we write io.read, we mean the read function from the io module . For Lua, this means index the table io using the string read as the key .
Tables in Lua are neither values nor variables; they are objects. If you are familiar with arrays in Java or Scheme, then you have a fair idea of what I mean. You may think of a table as a dynamically allocated object; your program manipulates only references (or pointers) to them. There are no hidden copies or creation of new tables behind the scenes. Moreover, you do not have to declare a table in Lua; in fact, there is no way to declare one. You create tables by means of a constructor expression
Notice the last line: like global variables, table elds evaluate to nil when they are not initialized. Also like global variables, you can assign nil to a table eld to delete it. This is not a coincidence: Lua stores global variables in ordinary tables. We will discuss this subject further in Chapter 14.
To represent records, you use the eld name as an index. Lua supports this representation by providing a.name as syntactic sugar for a[« name »]. So, we could write the last lines of the previous example in a cleaner manner as follows:
a.x = 10 — same as a[« x »] = 10
print(a.x) — same as print(a[« x »])
print(a.y) — same as print(a[« y »])
For Lua, the two forms are equivalent and can be intermixed freely; for a human reader, each form may signal a different intention. The dot notation clearly shows that we are using the table as a record, where we have some set of xed, pre-de ned keys. The string notation gives the idea that the table may have any string as a key, and that for some reason we are manipulating that speci c key.
A common mistake for beginners is to confuse a.x with a[x]. The rst form represents a[« x »], that is, a table indexed by the string x . The second form is a table indexed by the value of the variable x. See the difference:
a = {}
x = « y »
a[x] = 10 — put 10 in field « y »
print(a[x]) –> 10 — value of field « y »
print(a.x) –> nil — value of field « x » (undefined)
print(a.y) –> 10 — value of field « y »
To represent a conventional array or a list, you simply use a table with integer keys. There is neither a way nor a need to declare a size; you just initialize the elements you need:
— read 10 lines storing them in a table a = {}
for i=1,10 do a[i] = io.read()
end
Since you can index a table with any value, you can start the indices of an array with any number that pleases you. However, it is customary in Lua to start arrays with 1 (and not with 0, as in C) and several facilities stick to this convention.
I The Language 1
1 Getting Started
1.1 Chunks
1.2 Some Lexical Conventions
1.3 Global Variables
1.4 The Stand-Alone Interpreter
2 Types and Values
2.1 Nil
2.2 Booleans
2.3 Numbers
2.4 Strings
2.5 Tables
2.6 Functions
2.7 Userdata and Threads
3 Expressions
4 Statements
5 Functions
6 More About Functions
7 Iterators and the Generic for
8 Compilation, Execution, and Errors
9 Coroutines
10 Complete Examples
II Tables and Objects
11 Data Structures
12 Data Files and Persistence
13 Metatables and Metamethods
14 The Environment
15 Modules and Packages
16 Object-Oriented Programming
17 Weak Tables
III The Standard Libraries
18 The Mathematical Library
27 Techniques for Writing C Functions
28 User-Dened Types in C
29 Managing Resources
30 Threads and States
31 Memory Management
Index