feat: SET DELETED filtering, SEEK/LOCATE/CONTINUE, SET command codegen
- skipFilter: skip deleted records in GoTop/GoBottom/Skip when SET DELETED ON - hbrdd.IsSetDeleted callback: avoids circular import hbrdd→hbrtl - Parser: capture ON/OFF for boolean SET commands (DELETED, EXACT, SOFTSEEK, etc.) - Parser: capture TO expr for SET DATE/DECIMALS/EPOCH - Gengo: emit proper t.Do() calls for 11 SET toggles + 3 value SETs - stmtSet: was stub (skipToEOL), now calls parseSet() - RTL: register 11 SET toggle functions (SETDELETED, SETEXACT, etc.) - RTL: DBLOCATE/DBCONTINUE for sequential search - RTL: DBSETFILTER/DBCLEARFILTER/DBFILTER - PadL/PadR: support 3rd param fill character - Area interface: added SetFound, SetLocate, LocateBlock, filter methods - MemRDD: implements new Area interface methods - Comprehensive PRG test: test_search.prg (7 test suites all pass) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1706,10 +1706,23 @@ func (p *Parser) parseSet() *ast.SetCmd {
|
||||
var extra string
|
||||
|
||||
// SET commands: consume everything until end of line.
|
||||
// Values like "GR+/B, W+/BG" can't be parsed as expressions.
|
||||
// SET FILTER TO is special — the condition IS an expression.
|
||||
// Boolean toggles: SET DELETED ON/OFF, SET EXACT ON/OFF, etc.
|
||||
// Value settings: SET FILTER TO expr, SET ORDER TO n, SET DATE TO fmt
|
||||
upperSetting := strings.ToUpper(setting)
|
||||
if p.match(token.TO) {
|
||||
|
||||
// Check for ON/OFF boolean toggle
|
||||
booleanSets := map[string]bool{
|
||||
"DELETED": true, "EXACT": true, "SOFTSEEK": true, "EXCLUSIVE": true,
|
||||
"FIXED": true, "CANCEL": true, "BELL": true, "CONFIRM": true,
|
||||
"INSERT": true, "ESCAPE": true, "WRAP": true, "INTENSITY": true,
|
||||
"SCOREBOARD": true, "CONSOLE": true, "ALTERNATE": true, "PRINTER": true,
|
||||
}
|
||||
|
||||
if booleanSets[upperSetting] {
|
||||
if p.current.Kind != token.NEWLINE && p.current.Kind != token.EOF {
|
||||
extra = strings.ToUpper(p.expectMethodName().Literal)
|
||||
}
|
||||
} else if p.match(token.TO) {
|
||||
if upperSetting == "FILTER" || upperSetting == "RELATION" || upperSetting == "ORDER" || upperSetting == "INDEX" {
|
||||
if p.current.Kind != token.NEWLINE && p.current.Kind != token.EOF {
|
||||
expr = p.parseExpr()
|
||||
@@ -1718,6 +1731,10 @@ func (p *Parser) parseSet() *ast.SetCmd {
|
||||
p.advance()
|
||||
extra = p.expectMethodName().Literal
|
||||
}
|
||||
} else if upperSetting == "DATE" || upperSetting == "DECIMALS" || upperSetting == "EPOCH" {
|
||||
if p.current.Kind != token.NEWLINE && p.current.Kind != token.EOF {
|
||||
expr = p.parseExpr()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -241,10 +241,7 @@ func (p *Parser) stmtRecallPackZap() ast.Stmt {
|
||||
}
|
||||
|
||||
func (p *Parser) stmtSet() ast.Stmt {
|
||||
// SET command — skip to EOL (SET COLOR, SET FILTER, SET ORDER, etc.)
|
||||
p.skipToEndOfLine()
|
||||
p.expectEndOfStmt()
|
||||
return &ast.ExprStmt{X: &ast.LiteralExpr{Kind: token.NIL_LIT, Value: "NIL"}}
|
||||
return p.parseSet()
|
||||
}
|
||||
|
||||
func (p *Parser) stmtDefer() ast.Stmt { return p.parseDefer() }
|
||||
|
||||
Reference in New Issue
Block a user