diff --git a/compiler/parser/parser.go b/compiler/parser/parser.go index 1c30cb5..144bb2c 100644 --- a/compiler/parser/parser.go +++ b/compiler/parser/parser.go @@ -32,6 +32,12 @@ type Parser struct { errors []Error file string GoDumps []string // inline Go code blocks from PP + // lastClassName tracks the most recent `CLASS X` / `CREATE CLASS X` + // declaration at file scope. Standalone `METHOD foo(...)` decls + // without an explicit `CLASS Y` clause default to this name — + // matches classic Clipper/Harbour where method bodies follow the + // class declaration and bind implicitly. + lastClassName string } // Error represents a parse error with position. @@ -522,6 +528,7 @@ func (p *Parser) parseVarDecl() *ast.VarDecl { func (p *Parser) parseClassDecl() *ast.ClassDecl { classPos := p.expect(token.CLASS).Pos name := p.expect(token.IDENT).Literal + p.lastClassName = name var parent string if p.match(token.INHERIT) { @@ -1020,6 +1027,12 @@ func (p *Parser) parseMethodDecl() *ast.MethodDecl { var className string if p.match(token.CLASS) { className = p.expect(token.IDENT).Literal + } else if p.lastClassName != "" { + // Implicit binding to the most recent `CREATE CLASS` / `CLASS` + // declaration — classic Clipper/Harbour form. Real code uses + // `CREATE CLASS CLSX ... ENDCLASS` followed by a bare + // `METHOD TestX() ... RETURN Self` without restating the class. + className = p.lastClassName } p.expectEndOfStmt()