feat(rtl): DO(xTarget, [args...]) — dynamic dispatch
Harbour's DO() accepts a string (looked up as a function name), a
code block (evaluated with args), or a symbol, and invokes it. Used
for plugin systems and dynamic dispatch idioms like
`DO(cHandler, oRequest)`.
Five already had stmtDo rewrite `DO(...)` at statement-level to a
function-call expression, so callers in expression position just
work — but gengo refused to emit DO as a function call because it
was on the reserved-word guard list (which existed to catch stray
ENDIF/ENDDO from bad IF nesting). Remove DO from that list; the
statement form is still handled upstream by parseDoProc, so the
guard loses nothing.
rtlDo implements the dispatch:
- String target → VM.FindSymbol + t.Function
- Block target → EvalBlock path (same as Eval)
- Anything else → NIL
Tested (/tmp/test_do.prg):
DO("Greet", "World") → "hello, World"
DO({|x,y| x*y+1}, 5, 6) → 31
DO(NIL) → NIL (ValType "U")
FiveSql2 43/43, Harbour compat 56/56, Go test ALL PASS.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2736,7 +2736,7 @@ func (g *Generator) emitAssignExpr(e *ast.AssignExpr) {
|
||||
func isReservedWord(name string) bool {
|
||||
switch name {
|
||||
case "IF", "ELSE", "ELSEIF", "ENDIF",
|
||||
"DO", "WHILE", "ENDDO",
|
||||
"WHILE", "ENDDO",
|
||||
"FOR", "NEXT", "TO", "STEP",
|
||||
"RETURN", "FUNCTION", "PROCEDURE",
|
||||
"LOCAL", "STATIC", "PRIVATE", "PUBLIC",
|
||||
|
||||
Reference in New Issue
Block a user