diff --git a/compiler/pp/command.go b/compiler/pp/command.go index 0f30120..3199e17 100644 --- a/compiler/pp/command.go +++ b/compiler/pp/command.go @@ -680,13 +680,26 @@ func (r *Rule) applyResult(captures map[string]string) string { result = strings.ReplaceAll(result, "<."+name+".>", ".F.") } // <{name}> — blockify: wrap captured expression in {|| ... }. - // Empty capture → NIL so the call site sees a nil block, matching - // how Harbour's std.ch expects __dbLocate / dbEval to interpret a - // missing FOR/WHILE clause. - if val != "" { - result = strings.ReplaceAll(result, "<{"+name+"}>", "{|| "+val+" }") - } else { + // For list-typed markers (``) wrap *each* element so + // `{ <{v}> }` against `LIST id, name` expands to + // `{ {|| id }, {|| name } }`, matching Harbour's std.ch + // idiom for column blocks. Empty capture → NIL so the call + // site sees a nil block (missing FOR/WHILE clause). + if val == "" { result = strings.ReplaceAll(result, "<{"+name+"}>", "NIL") + } else if isList[name] { + parts := splitTopLevelCommas(val) + out := make([]string, 0, len(parts)) + for _, p := range parts { + t := strings.TrimSpace(p) + if t == "" { + continue + } + out = append(out, "{|| "+t+" }") + } + result = strings.ReplaceAll(result, "<{"+name+"}>", strings.Join(out, ", ")) + } else { + result = strings.ReplaceAll(result, "<{"+name+"}>", "{|| "+val+" }") } // — bare substitution (must be LAST, after all wrappers). result = strings.ReplaceAll(result, "<"+name+">", val)