2 -- Copyright (C) 2008-2009 Matthew Wild
3 -- Copyright (C) 2008-2009 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
13 local function read(expected)
16 ch = last; last = nil;
17 else ch = file:read(1); end
18 if expected and ch ~= expected then error("expected: "..expected.."; got: "..(ch or "nil")); end
21 local function pushback(ch)
22 if last then error(); end
26 if not last then last = read(); end
30 local _A, _a, _Z, _z, _0, _9, __, _at, _space = string.byte("AaZz09@_ ", 1, 9);
31 local function isLowerAlpha(ch)
32 ch = string.byte(ch) or 0;
33 return (ch >= _a and ch <= _z);
35 local function isNumeric(ch)
36 ch = string.byte(ch) or 0;
37 return (ch >= _0 and ch <= _9);
39 local function isAtom(ch)
40 ch = string.byte(ch) or 0;
41 return (ch >= _A and ch <= _Z) or (ch >= _a and ch <= _z) or (ch >= _0 and ch <= _9) or ch == __ or ch == _at;
43 local function isSpace(ch)
44 ch = string.byte(ch) or "x";
48 local function readString()
49 read("\""); -- skip quote
54 if ch == "\"" and not slash then break; end
57 str = str:gsub("\\.", {["\\b"]="\b", ["\\d"]="\d", ["\\e"]="\e", ["\\f"]="\f", ["\\n"]="\n", ["\\r"]="\r", ["\\s"]="\s", ["\\t"]="\t", ["\\v"]="\v", ["\\\""]="\"", ["\\'"]="'", ["\\\\"]="\\"});
60 local function readAtom1()
62 while isAtom(peek()) do
67 local function readAtom2()
68 local str = read("'");
73 if ch == "'" and not slash then break; end
77 local function readNumber()
79 while isNumeric(peek()) do
85 local function readTuple()
87 local s = ""; -- string representation
88 read(); -- read {, or [, or <
90 local item = readItem();
91 if not item then break; end
92 if type(item) ~= type(0) or item > 255 then
95 s = s..string.char(item);
97 table.insert(t, item);
99 read(); -- read }, or ], or >
100 if s and s ~= "" then
106 local function readBinary()
108 local t = readTuple();
111 if type(t) == type("") then
112 -- binary is a list of integers
114 elseif type(t) == type({}) then
116 -- binary contains string
126 readItem = function()
128 if ch == nil then return nil end
129 if ch == "{" or ch == "[" then
131 elseif isLowerAlpha(ch) then
133 elseif ch == "'" then
135 elseif isNumeric(ch) then
137 elseif ch == "\"" then
139 elseif ch == "<" then
141 elseif isSpace(ch) or ch == "," or ch == "|" then
145 --print("Unknown char: "..ch);
149 local function readChunk()
150 local x = readItem();
151 if x then read("."); end
154 local function readFile(filename)
155 file = io.open(filename);
156 if not file then error("File not found: "..filename); os.exit(0); end
158 local x = readChunk();
159 if not x and peek() then error("Invalid char: "..peek()); end
166 function parseFile(file)
167 return readFile(file);