Word count (Lua)

From LiteratePrograms

Jump to: navigation, search
Other implementations: Assembly Intel x86 Linux | C | C++ | Forth | Haskell | J | Lua | OCaml | Perl | Python | Python, functional | Rexx

An implementation of the UNIX wc tool in Lua.

The wc tool counts characters, words and lines in text files or stdin. When invoked without any options, it will print all three values. These options are supported:

  • -c - Only count characters
  • -w - Only count words
  • -l - Only count lines

If the tool is invoked without any file name parameters, it will use stdin.

<<wc.lua>>=
#!/usr/bin/env lua
tot_chars=0
tot_words=0
tot_lines=0
opts=""
printwc
wc

Command line

First we read all options (arguments starting with '-'). Unrecoginzed options are ignored.

If the user did not provide any options, we use the default, "lwc", so that line-, word- and character-count are printed.

<<wc.lua>>=
nfiles=0
for i=1,table.getn(arg) do 
	if(nfiles==0 and string.sub(arg[i], 1, 1)=='-') then
		opts=opts .. arg[i]
	else
		if(string.len(opts)==0) then opts="lwc" end
		wc(arg[i])
		nfiles=nfiles+1
	end
end

If no files where specified nfiles<1, we call wc() with "-", indicating we want to read from stdin. If there was more than one file, the sum of all files are printed.

<<wc.lua>>=
if(string.len(opts)==0) then opts="lwc" end
if nfiles<1 then wc("-") end
if nfiles>1 then printwc(tot_lines, tot_words, tot_chars, "total") end

wc()

The wc() function does the counting work. It takes a file name as it only argument.

<<wc>>=
function wc(fname)
	chars=0
	words=0
	lines=0
	if(fname=="-") then it=io.lines()
	else it=io.lines(fname) end
	for line in it do
		lines=lines+1
		for word in string.gfind(line, "[^%s]+") do words=words+1 end
		chars=chars+string.len(line)+1
	end

When the counting is done, the the printwc() is used to print the result, and the global tot_... variables are updated.

<<wc>>=
	printwc(lines, words, chars, fname)
	tot_chars=tot_chars+chars
	tot_words=tot_words+words
	tot_lines=tot_lines+lines
end

printwc()

printwc() uses the global opts variable to decide which values to print.

<<printwc>>=
function printwc(lines, words, chars, fname)
	if(string.find(opts, "l")) then io.write(string.format("% 8d", lines)) end
	if(string.find(opts, "w")) then io.write(string.format("% 8d", words)) end
	if(string.find(opts, "c")) then io.write(string.format("% 8d", chars)) end
	if(fname~="-") then io.write(" "); print(fname)
	else print() end
end
Download code
Views