diff --git a/compiler/gengo/gengo.go b/compiler/gengo/gengo.go index 311e60f..b4b958f 100644 --- a/compiler/gengo/gengo.go +++ b/compiler/gengo/gengo.go @@ -1486,6 +1486,14 @@ func (g *Generator) emitAssign(a *ast.AssignExpr, locals localMap) { if aliasExpr, ok := a.Left.(*ast.AliasExpr); ok { if aliasIdent, ok2 := aliasExpr.Alias.(*ast.IdentExpr); ok2 { if fieldIdent, ok3 := aliasExpr.Field.(*ast.IdentExpr); ok3 { + upper := strings.ToUpper(aliasIdent.Name) + // `M->name := v` / `MEMVAR->name := v` are memvar writes, + // not workarea field writes. + if upper == "M" || upper == "MEMVAR" { + g.emitExpr(a.Right) + g.writeln(fmt.Sprintf(`t.PopMemvar(%q)`, fieldIdent.Name)) + return + } g.emitExpr(a.Right) g.writeln(fmt.Sprintf(`{ _wa := t.WA.(*hbrdd.WorkAreaManager); _wa.SetAliasField(%q, %q, t.Pop2()) }`, aliasIdent.Name, fieldIdent.Name)) return @@ -2716,6 +2724,16 @@ func (g *Generator) emitAssignExpr(e *ast.AssignExpr) { if aliasExpr, ok := e.Left.(*ast.AliasExpr); ok { if aliasIdent, ok2 := aliasExpr.Alias.(*ast.IdentExpr); ok2 { if fieldIdent, ok3 := aliasExpr.Field.(*ast.IdentExpr); ok3 { + upper := strings.ToUpper(aliasIdent.Name) + if upper == "M" || upper == "MEMVAR" { + // Memvar write — leaves a copy on the stack for the + // enclosing expression to pick up (matches Dup+SetAlias + // path). + g.emitExpr(e.Right) + g.writeln("t.Dup()") + g.writeln(fmt.Sprintf(`t.PopMemvar(%q)`, fieldIdent.Name)) + return + } g.emitExpr(e.Right) g.writeln("t.Dup()") g.writeln(fmt.Sprintf(`{ _wa := t.WA.(*hbrdd.WorkAreaManager); _wa.SetAliasField(%q, %q, t.Pop2()) }`, aliasIdent.Name, fieldIdent.Name)) @@ -3082,6 +3100,13 @@ func (g *Generator) emitAliasExpr(e *ast.AliasExpr) { // Case 1: alias->field (static alias, simple field name) if ident, ok := e.Alias.(*ast.IdentExpr); ok && isFieldIdent { + upper := strings.ToUpper(ident.Name) + // `M->name` / `MEMVAR->name` access the memvar namespace, not + // a database workarea. Harbour reserves both aliases for this. + if upper == "M" || upper == "MEMVAR" { + g.writeln(fmt.Sprintf(`t.PushMemvar(%q)`, fieldIdent.Name)) + return + } g.writeln(fmt.Sprintf(`t.PushAliasField(%q, %q)`, ident.Name, fieldIdent.Name)) return }