summaryrefslogtreecommitdiff
path: root/config.lua
blob: a8838c87d3e04d164ff9fc43ef846fe7257a2895 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
local function partial(f,x) return function(...) return f(x,...) end end

local function kv_syntax(block,line)
	local k,v = line:match"^([a-z0-9_-]+)%s*=%s*(.*)$"
	assert(k,"syntax error in kv line: "..line)
	k = k:gsub("-","_")
	block[k]=v
end

local function tuple_syntax(pattern) return function(block,line)
	local matches = {line:match(pattern)}
	assert(matches[1], "syntax error in tuple line: "..line)
	table.insert(block, matches)
end end 

local schema = {
	pylon = kv_syntax,
	bus = tuple_syntax"^(%S+)%s+(%S+)$",
}

local function parse_file(file)
	local blocks = {}
	for k in pairs(schema) do blocks[k] = {} end
	local line_handler = function() error("line outside of block") end

	for line in file:lines() do
		line = line:gsub("#.*$",""):gsub("^%s*",""):gsub("%s*$","")
		if line == '' then goto next end

		local block_type, block_name = line:match"%[%s*(%S+)%s+(%S+)%s*%]"
		if block_type then
			local blocks_of_this_type = assert(blocks[block_type],"no such block type "..block_type)
			local block = {}
			blocks_of_this_type[block_name] = block
			line_handler = partial(schema[block_type], block)
		else
			line_handler(line)
		end
		::next::
	end

	return blocks
end

return {parse=parse_file}