~mna/snow unlisted

snow/doc/go_backend_codegen.md -rw-r--r-- 2.7 KiB
424066c5Martin Angers doc: v0.0.5 9 months ago

#code generation for the Go backend

#name mangling

Name-mangling is required in the following cases:

  1. Top-level declarations, to make sure they are not exported unless requested
  2. All struct declarations
    1. a) Nested structs in top-level structs
    2. b) Any struct in function/method scope
  3. (Eventually) overloaded functions
  4. Go (but not Snow) keywords used as identifiers

#top-level declarations (1)

Top-level declarations are simply prefixed with($ represents the name-mangling separator rune):

  • _$ for non-exported symbols
  • X$ for exported symbols

For example:

let x: int 
pub let y: int

are generated as:

var _$x int
var X$y int

#nested structs in top-level structs (2a)

Nested structs that are nested in top-level structs apply the following rules (regarding export, if all parents are exported and the nested struct is also exported, then it is prefixed with X$, otherwise it is prefixed with _$):

  • _$ or X$
  • then the (unprefixed) name of all parent structs, separated by $
  • then the name of the nested struct

For example:

pub struct X {
  pub struct Y {
    struct Z {
    }
  }
}

Generates:

type X$X struct{}
type X$X$Y struct{}
type _$X$Y$Z struct{}

#structs or nested structs in function or method scopes (2b)

Go supports struct declarations inside functions, but it is impossible to define methods on them. So instead of defining some of those structs inside functions in the Go code, and some outside with mangling, all structs are declared outside the function in the top-level scope, and use the following name-mangling scheme:

  • _$ prefix (as those structs are necessarily unexported)
  • then the (possibly mangled, but unprefixed) name of the function followed by $
  • then the name of the struct (or nested struct) as defined in 2a

For example:

fn f() {
  struct X {
    struct Y {
      struct Z {
      }
    }
  }
}

Generates:

type _$f$X struct{}
type _$f$X$Y struct{}
type _$f$X$Y$Z struct{}
func _$f() {}

#overloaded functions and methods (3)

#Go keywords as identifiers (4)

Go and Snow use different keywords, and as such some Go keywords might be used as valid snow identifiers. To make it work in the generated backend code, those identifiers need to be mangled.

If the identifier is used in the context of a top-level declaration or function/method-scoped struct, then it follows the rules in 1, 2a or 2b. Same if the identifier is used as an overloaded method or function, it follows the rule in 3.

Otherwise, if it is used e.g. as a local variable (that would otherwise cause no name mangling), then the following rule is applied:

  • prefix the identifier with $