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

[edit] 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

[edit] 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

[edit] 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
hijacker
hijacker
hijacker
hijacker