From d3148268857e01116d5d3c99ac0a43bc6a54b13c Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Wed, 29 Dec 2010 16:26:25 +0100 Subject: initial checkin (v0.1 release) --- samples/exp2bf.lua | 48 ++++++++++++++++++++++++++++++++ samples/regexp.lua | 26 ++++++++++++++++++ samples/wave.lua | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100755 samples/exp2bf.lua create mode 100644 samples/regexp.lua create mode 100755 samples/wave.lua (limited to 'samples') diff --git a/samples/exp2bf.lua b/samples/exp2bf.lua new file mode 100755 index 0000000..dac59d4 --- /dev/null +++ b/samples/exp2bf.lua @@ -0,0 +1,48 @@ +#!/usr/bin/lua + +require "lspipat" + +function EXIT(...) + io.stderr:write(string.format(...)) + os.exit() +end + +stack = {} +function push(val) table.insert(stack, val) end +function binop() + table.insert(stack, { + l = table.remove(stack), + type = table.remove(stack), + r = table.remove(stack) + }) +end + +function compile(node) + if type(node) ~= "table" then return string.rep("+", tonumber(node)) end + + local ret = compile(node.l)..">"..compile(node.r) + node.type:smatch( Any("+-") % function(o) ret = ret.."[<"..o..">-]<" end + + "*" * -function() ret = ">>"..ret.."[<[<+<+>>-]<[>+<-]>>-]<[-]<<" end + + "/" * -function() ret = ">"..ret.."<[->->+>>+<<<[>>+>[-]<<<-]>>".. + "[<<+>>-]>[-<<[<+>-]<<<+>>>>>]<<<<]>[-]>[-]<<<" end, + spipat.match_anchored ) + + return ret +end + +if #arg ~= 1 then EXIT("Invalid number of parameters\n") end + +space = NSpan(" ") +pre = space * ("(" * -"exp" * space * ")" + Span("0123456789") % push) +post = space * ( Any("+-") % push * -"exp" * -binop + + Any("*/") % push * pre * -binop * -"post" ) + "" +exp = pre * post + +if not arg[1]:smatch(exp * RPos(0), spipat.match_anchored) then EXIT("Invalid expression!\n") end + +src = compile(stack[1]).. + "[>++++++++++<[->->+>>+<<<[>>+>[-]<<<-]>>[<<+>>-]".. + ">[-<<[<+>-]>>>+<]<<<<]>>>>>[<<<<<+>>>>>-]>[>]"..string.rep("+", string.byte("0")).. + "[<]<<<[>>>>[>]<+[<]<<<-]<[-]<]>>>>>>[>]<[.<]" + +print(src) diff --git a/samples/regexp.lua b/samples/regexp.lua new file mode 100644 index 0000000..b9b1da2 --- /dev/null +++ b/samples/regexp.lua @@ -0,0 +1,26 @@ +-- Parse IP address using regular expression compiler + +require "lspipat" + + +exp = [=[^([[:digit:]]{1,3})(\.([[:digit:]]{1,3})){3,3}$]=] + +ip1 = RegExp(exp) +print(ip1) + +local captures = {} +ip2 = RegExp(exp, captures) +print(ip2) + +print(spipat.smatch("192.168.0.1", ip1)) +print(spipat.smatch("192.168.000.001", ip1)) +print(spipat.smatch("192.168.0.XXX", ip1)) + +print(spipat.smatch("192.168.0.1", ip2)) + +-- remove captures due to grouping around "." +table.remove(captures, 3) +table.remove(captures, 5) +table.remove(captures, 7) + +print(table.concat(captures, ".")) diff --git a/samples/wave.lua b/samples/wave.lua new file mode 100755 index 0000000..9fd5adb --- /dev/null +++ b/samples/wave.lua @@ -0,0 +1,81 @@ +#!/usr/bin/lua + +require "lspipat" + +function uint(bytes, val) -- binary integer decoding + return Len(bytes) % function(bin) + bin = littleEndian and bin or bin:reverse() + + local n = 0 + local base = 1 + + for _, c in ipairs{bin:byte(1, bytes)} do + n = n + base * c + base = base * 256 + end + + val(n) + end +end + +function _uint(bytes, name) return uint(bytes, function(n) _G[name] = n end) end +function _uint16(name) return _uint(2, name) end +function _uint32(name) return _uint(4, name) end + +hnd = assert(io.open(arg[1])) + +file = hnd:read("*a") + +hnd:close() + +-- WAVE file "grammar" + +format = "fmt " + * _uint32 "FmtChunkSize" + * _Setcur "FmtStartPos" + * _uint16 "AudioFormat" + * _uint16 "NumChannels" + * _uint32 "SampleRate" + * _uint32 "ByteRate" + * _uint16 "BlockAlign" + * _uint16 "BitsPerSample" + * ( -function() return AudioFormat == 1 end + + _uint16 "ExtraParamSize" + * _Len "ExtraParamSize" ) + * Pos(function() return FmtStartPos + FmtChunkSize end) + * -function() return BitsPerSample % 8 == 0 and + BlockAlign == NumChannels * BitsPerSample/8 and + ByteRate == SampleRate * BlockAlign end + +data = "data" + * _uint32 "DataChunkSize" + * _Len "DataChunkSize" + +misc = Len(4) + * _uint32 "MiscChunkSize" + * _Len "MiscChunkSize" + +wave = (topattern("RIFF") + "RIFX") + % function(id) littleEndian = id == "RIFF" end + * _uint32 "ChunkSize" + * _Setcur "StartPos" + * "WAVE" + * Arbno(format + data + misc) + * Pos(function() return StartPos + ChunkSize end) + * -function() return DataChunkSize % BlockAlign == 0 end + * RPos(0) + +assert(file:smatch(wave, spipat.match_anchored), + arg[1].." is not a valid WAVE file!") + +print(string.format( +"%s\ +Format: %u\ +Channels: %u\ +Samplerate: %u Hz\ +Byterate: %u Hz\ +Bits/Sample: %u\ +Samples: %u", +arg[1], +AudioFormat, NumChannels, SampleRate, ByteRate, BitsPerSample, DataChunkSize / BlockAlign)) +print(os.date("Length:\t\t%T", DataChunkSize / ByteRate + 60*60*23)) -- cgit v1.2.3