local string = string local table = table local io = io local lyaml = require("lyaml") local M = {} -- Parameters that do not get inherited. local NO_INHERIT = {abstract = true} local MODEL_PATH = "./config/model/" local function camel2snake(src) return string.lower( string.gsub( string.gsub (src, "^pas:", ""), -- Strip namespace. "([^^])(%u)", "%1_%2" -- Uppercase (except initial) to underscore. ) ) end M.parse_model = function(mod_id) local hierarchy = {} local function traverse(mod_id) print("traversing:", mod_id) local fname = camel2snake (mod_id) local fh = assert(io.open(MODEL_PATH .. fname .. ".yml"), "r") local yml_data = fh:read("a") fh:close() local model = lyaml.load(yml_data) model.id = mod_id --print("Model: ") --for k, v in pairs(model) do print (k, v) end -- Prepend to hierarchy. table.insert(hierarchy, 1, model) if model.broader then traverse(model.broader) end end traverse(mod_id) local lineage = {} -- Config ID lineage, from ancestor to leaf. for _, mod in ipairs(hierarchy) do table.insert(lineage, mod.id) end --[[ for k, v in ipairs(hierarchy) do for kk, vv in pairs(v) do print(k, kk, vv) end end --]] local function merge(src, dest) for k, v in pairs(src) do if NO_INHERIT[k] then goto continue end if type(v) == "table" then dest[k] = dest[k] or {} assert(type(dest[k]) == "table") merge(v, dest[k]) else dest[k] = v end ::continue:: end end local config = {} for _, src_config in ipairs(hierarchy) do merge(src_config, config) end return config end return M