diff --git a/src/plc_json.lua b/src/plc_json.lua index 27797f2..f03c7bb 100644 --- a/src/plc_json.lua +++ b/src/plc_json.lua @@ -84,6 +84,7 @@ local function parse_scl_type_file(content) local in_struct = false local current_type_name = nil local pending_type_name = nil + local pending_type_comment = nil local in_fb = false local fb_name = nil @@ -132,7 +133,7 @@ local function parse_scl_type_file(content) current_fb_section = "output" elseif trimmed:match("^VAR_IN_OUT") then current_fb_section = "inout" - elseif trimmed:match("^VAR%s") or trimmed:match("^VAR%s*$") then + elseif trimmed:match("^VAR%s") or trimmed:match("^VAR%s$") then current_fb_section = nil elseif trimmed:match("^VAR_TEMP") then current_fb_section = nil @@ -169,33 +170,42 @@ local function parse_scl_type_file(content) in_struct = false current_type_name = nil pending_type_name = nil + pending_type_comment = nil local type_name = trimmed:match('TYPE%s+"([^"]+)"') or trimmed:match("^TYPE%s+(%w+)") if type_name then pending_type_name = type_name end - in_struct = false - current_type_name = nil - pending_type_name = nil elseif trimmed:match("^END_TYPE") then in_type = false in_struct = false current_type_name = nil pending_type_name = nil + pending_type_comment = nil elseif in_type then - if trimmed:match("^END_STRUCT") or trimmed:match("^END_STRUCT;") then + -- Capture comments before STRUCT + if trimmed:match("^//") then + local comment = trimmed:match("^//%s*(.+)$") + if comment and pending_type_name then + pending_type_comment = comment + end + elseif trimmed:match("^END_STRUCT") or trimmed:match("^END_STRUCT;") then in_struct = false current_type_name = nil pending_type_name = nil + pending_type_comment = nil elseif trimmed:match("^STRUCT") then if pending_type_name then current_type_name = pending_type_name in_struct = true - types[pending_type_name] = { name = pending_type_name, kind = "struct", fields = {}, source = "data_types_folder" } + types[pending_type_name] = { name = pending_type_name, kind = "struct", fields = {}, source = "data_types_folder", comment = pending_type_comment } pending_type_name = nil + pending_type_comment = nil end elseif not in_struct and trimmed:match("^%w+%s*:") and not trimmed:match("^STRUCT") then + -- This is an alias type declaration (TypeName : BaseType;) + -- NOT VERSION, TITLE, etc. local type_name = trimmed:match("^(%w+)%s*:") - if type_name then + if type_name and type_name ~= "VERSION" and type_name ~= "TITLE" then local next_line = lines[i + 1] local next_trimmed = next_line and next_line:gsub("^%s+", ""):gsub("%s+$", "") if next_trimmed and next_trimmed:match("^STRUCT") then @@ -209,9 +219,16 @@ local function parse_scl_type_file(content) end end elseif in_struct and current_type_name and types[current_type_name] then - local field_name = line:match("^%s*(%w+)%s*:") + local field_name = line:match("^%s*(%w+)%s*{") or line:match("^%s*(%w+)%s*:") if field_name and field_name ~= "END_STRUCT" then - local field_type = line:match(":%s*([%w_]+)") + -- Remove attribute blocks before extracting type + local clean_line = line:gsub("%b{}", "") + -- Extract field type - handle both quoted and unquoted types + local field_type = clean_line:match(':%s*"([^"]+)"') or clean_line:match(":%s*([%w_]+)") + -- Also handle array types + if not field_type then + field_type = clean_line:match(":%s*(ARRAY.+)") + end local field_comment = line:match("//%s*(.+)$") or line:match("%(%*(.-)%*%)") table.insert(types[current_type_name].fields, { name = field_name,