Phi Lho Soft Lua 示例

lua-users home
wiki

一些 Lua 4.0 示例,由 PhilippeLhoste 编写,用于教育目的,也许,对某些人来说,也用于实际应用... 所有这些都过时了...

[!] 版本说明: 以下代码适用于旧版本的 Lua,Lua 4。它不能在 Lua 5 下运行。

99 Bottles of Beer.lua

-- 99 Bottles of Beer.lua
-- http://www.ionet.net/~timtroyr/funhouse/beer.html
-- Tim Robinson
-- timtroyr(a)ionet.net

-- Inspiration...

-- 10 REM Basic version of 99 bottles of beer
-- 20 FOR X=99 TO 1 STEP -1
-- 30 PRINT X;"bottle(s) of beer on the wall,";X;"bottle(s) of beer"
-- 40 PRINT "Take one down and pass it around,"
-- 50 PRINT X-1;"bottle(s) of beer on the wall"
-- 60 NEXT
-- Added. Shouldn't display 0 bottles(s), above...
-- 70 PRINT "No bottles of beer on the wall"
-- 80 PRINT "Go to the store and buy some more"

-- #!/bin/csh
-- # Version #2.1 C-Shell version of 99 Bottles of Beer
-- #
-- # overhauled 1997-19-3 by Ken Bateman (kbateman(a)esinet.net)
-- #
-- foreach i (9 8 7 6 5 4 3 2 1 " ")
--   foreach j (9 8 7 6 5 4 3 2 1 0)
--   if ( $i$j != "99" ) echo $i$j " bottles of beer on the wall"
--   echo -n $i$j "bottles of beer on the wall, "
--   echo $i$j "bottles of beer"
--   echo -n "Take one down, pass it around..."
--   end
-- end
-- echo "no more bottles of beer on the wall"
-- echo "No more bottles of beer on the wall, no more bottles of beer"
-- echo "Go to the store, buy some more,"
-- echo "99 bottles of beer on the wall"
-- #end of script

-- Lua 99 Bottles of Beer
-- by Philippe Lhoste <PhiLho(a)GMX.net> http://Phi.Lho.free.fr

function PrintBottleNumber(n)
  local bs
  if n == 0 then
    bs = "No more bottles"
  elseif n == 1 then
    bs = "One bottle"
  else
    bs = n .. " bottles"
  end
  return bs .. " of beer"
end

for bn = 99, 1, -1 do
  write(PrintBottleNumber(bn), " on the wall, \n")
  write(PrintBottleNumber(bn), "\n")
  write("Take one down and pass it around,\n")
  write(PrintBottleNumber(bn-1), " on the wall, \n\n")
end
write("No more bottles of beer on the wall,\nNo more bottles of beer\n")
write("Go to the store, buy some more!\n")

gcd.lua

-- gcd.lua
-- Greatest common divisor

-- Unnecessary, here just to test argument passing
-- use lua -f gcd.lua 1233 12, for example
if arg then
  print("Arguments:")
  for i, v in arg do
    print(i, v)
  end
  print""
end

-- Take numerical arguments if exists,
-- then check if there is a value, otherwise take default value
local v1 = tonumber((arg and arg[1])) or (v1 or 121)
local v2 = tonumber((arg and arg[2])) or (v2 or 1221)

function gcd_plain(m, n)
  -- Using classical temporary variable
  local t
  while m ~= 0 do
    t = m
    m = mod(n, m)
    n = t
  end
  return n
end

function gcd_hip(m, n)
  -- Using parallel assignment
  while m ~= 0 do
    m, n = mod(n, m), m
  end
  return n
end

write(format("Greatest common divisor of %d and %d is %d\n", v1, v2, gcd_plain(v1, v2)))
write(format("Greatest common divisor of %d and %d is %d\n", v1, v2, gcd_hip(v1, v2)))

Process File.lua

-- Process File.lua
-- Process a file
-- by Philippe Lhoste <PhiLho(a)GMX.net> http://Phi.Lho.free.fr
-- v. 1.2 -- 2001/07/27 -- Sample processing a bit smarter :-)
-- v. 1.1 -- 2001/06/07 -- Standard I/O use
-- v. 1.0 -- 2001/06/06

filenameIn  = (arg and arg[1]) or "-"  -- If absent, use standard input
filenameOut = (arg and arg[2]) or "-"  -- If absent, use standard output

-- This version lowercases CSS identifiers as long as they are
-- alone on a line, preceded by a tab.
function ProcessLine(line)
  if not line then
    return nil
  end
  line = gsub(line, "^\t([%u-]*):", function(p) return '\t' .. strlower(p) .. ':' end)
  return line .. '\n'
end

function ProcessFile()
  if filenameIn ~= "-" then
    if not readfrom(filenameIn) then
      return nil, filenameIn
    end
  end
  if filenameOut ~= "-" then
    if not writeto(filenameOut) then
      return nil, filenameOut
    end
  end
  local processedLine
  -- Loop on the lines and process them
  repeat
    processedLine = ProcessLine(read())
    if processedLine then  -- ProcessLine returns nil if read line is nil (EOF)
      write(processedLine)
    end
  until processedLine == nil
-- OR:
--    while (ProcessLine(read())) do
--      -- Do nothing, output is done in ProcessLine
--    end
--  write"That's all folks!"
  readfrom()  -- Restore default reading
  writeto()    -- Restore default writing
  return 0, nil
end

result, fn = ProcessFile()
if not result then
  print("Error in parameter: " .. (fn or 'nil'))
end

Split Long Lines.lua

-- Split Long Lines.lua
-- Process a file to split long lines at blanks
-- by Philippe Lhoste <PhiLho(a)GMX.net> http://Phi.Lho.free.fr
-- v. 1.1 -- 2001/06/07 -- Standard I/O use
-- v. 1.0 -- 2001/06/06

filenameIn  = (arg and arg[1]) or "-"  -- If absent, use standard input
filenameOut = (arg and arg[2]) or "-"  -- If absent, use standard output
cutAt   = (arg and arg[3] and tonumber(arg[3])) or 80
method = (arg and arg[4]) or "w"  -- Values: "w" (white space) or "r" (raw)
lineNb = 0  -- For debug purpose

-- Cut at a separator before the cutAt length, or at cutAt size if no separator is found.
-- Return the remainder of the line.
function CutAtWhiteSpace(chunk)
  if chunk and chunk ~= "" then
    local len = min(strlen(chunk), cutAt)
--D--print("---" .. lineNb .. "-" .. "len: " .. len)
    local i, c, remainder
    local splitPos = 0
    -- Search a separator from the end of the chunk
    for i = len, 1, -1 do
      c = strsub(chunk, i, i)
      -- Separators = white space, tabulation, carriage return or line feed
      if c == ' ' or c == '\t' or c == '\r' or c == '\n' then
        splitPos = i
        break
      end
    end
    if splitPos ~= 0 then
--D--print("splitPos: " .. splitPos)
      -- Found, split here
      write(strsub(chunk, 1, splitPos - 1) .. "\n")
      remainder = strsub(chunk, splitPos + 1)
    else
      -- No separator found
--D--print("Dump")
      write(strsub(chunk, 1, cutAt) .. "\n")  -- Arbitrary cut at given size
      remainder = strsub(chunk, cutAt + 1)
    end
--D--print("remainder len: " .. strlen(remainder))
    return remainder
  else
    return nil  -- chunk is nil or an empty string: EOF
  end
end

-- Just dump the chunk, which has already the right size
function CutAtLength(chunk)
  if chunk and chunk ~= "" then
    write(chunk .. "\n")
    return ""
  else
    return nil
  end
end

if method == "r" then
  ProcessChunk = CutAtLength
else
  ProcessChunk = CutAtWhiteSpace
end

function ProcessFile()
  if filenameIn ~= "-" then
    if not readfrom(filenameIn) then
      return nil, filenameIn
    end
  end
  if filenameOut ~= "-" then
    if not writeto(filenameOut) then
      return nil, filenameOut
    end
  end
  local chunk
  local remainder = ""
  -- Loop on the lines and process them
  chunk = read(cutAt)
  repeat
--D--lineNb = lineNb + 1
    if chunk and strlen(remainder) <= cutAt then
      -- Process remainder of previous line and current chunk
      remainder = ProcessChunk(remainder .. chunk)
      chunk = read(cutAt)
    else
      -- remainder growed too big, have to split it
      remainder = ProcessChunk(remainder)
    end
--D--print("%%" .. (remainder or "(nil)") .. "%% " .. lineNb)
  until not remainder
--D--write"That's all folks!"
  readfrom()  -- Restore default reading
  writeto()    -- Restore default writing
  return 0, nil
end

result, fn = ProcessFile()
if not result then
  print("Error in parameter: " .. (fn or 'nil'))
end

Hexa Dump.lua

-- Hexa Dump.lua
-- Dump a file in hexadecimal form.
-- by Philippe Lhoste <PhiLho(a)GMX.net> http://Phi.Lho.free.fr
-- v. 1.1 -- 2002/02/12 -- Moved the gsub(%c) out of write to avoid dumping the two return values
-- v. 1.0 -- 2001/07/27

filenameIn  = (arg and arg[1]) or "-"  -- If absent, use standard input
filenameOut = (arg and arg[2]) or "-"  -- If absent, use standard output

-- For debugging:
--filenameIn = "Fav.ubx"

-- My dumb dump
function PLDumpString(fileContent)
  local len = strlen(fileContent)
  local line = ""
  for i = 1, len do
    line = line .. format('%02X', strbyte(strsub(fileContent, i, i))) .. ' '
    if mod(i, 16) == 0 then
      write(line, '\n')
      line = ""
    end
  end
  if line ~= '' then
    write(line, '\n')
  end
end

-- Roberto Ierusalimschy's dump
-- with some "improvements" to make it more flexible.
-- Slighly faster despite dumping more data...
bytesPerLine = 16
bDumpOffset = 1
bDumpAscii = 1

function DumpString(fileContent)
  local offset = 0
  local line
  while 1 do
    line = strsub(fileContent, offset + 1, offset + bytesPerLine)
    if line == '' then break end
    if bDumpOffset then
      write(format("%08X", offset), "  ") -- Write offset of the line
    end
    -- Smart use of gsub: it doesn't do any replacement,
    -- but instead is used as an iterator over the string bytes.
    gsub(line, "(.)",
      function(byte) write(format("%02X ", strbyte(byte))) end
    )
    if bDumpAscii then
      write(strrep("   ", bytesPerLine - strlen(line) + 1)) -- align strings
      line = gsub(line, "%c", '.') -- replace control chars by dot
      write(line)
    end
    write('\n')
    offset = offset + bytesPerLine
  end
end

function ProcessFile()
  local fileInHandle
  if filenameIn ~= "-" then
    -- I must use openfile instead of readfrom because the later doesn't support binary mode
    fileInHandle = openfile(filenameIn, "rb")
    if not fileInHandle then
      return nil, filenameIn
    end
  else
    fileInHandle = _INPUT
  end
  if filenameOut ~= "-" then
    if not writeto(filenameOut) then
      return nil, filenameOut
    end
  end

  print("Files: ", filenameIn, filenameOut)
  local fileContent = read(fileInHandle, "*a")  -- Read the whole file
  closefile(fileInHandle)
  print("fileContent is " .. strlen(fileContent) .. " bytes long")
  t1 = clock()
  PLDumpString(fileContent)
  t2 = clock()
  print("Time: ", t2 - t1)
  writeto()
  if filenameIn ~= "-" then
    print(remove(filenameOut))
  end
  if filenameOut ~= "-" then
    if not writeto(filenameOut) then
      return nil, filenameOut
    end
  end
  t1 = clock()
  DumpString(fileContent)
  t2 = clock()
  print("Time: ", t2 - t1)
  writeto()    -- Restore default writing
  return 0
end

result, fn = ProcessFile()
if not result then
  print("Error in parameter: " .. (fn or 'nil'))
end

最近更改 · 偏好设置
编辑 · 历史记录
最后编辑于 2007 年 1 月 6 日凌晨 4:46 GMT (差异)