Commit f6cbe842 authored by Eric Myhre's avatar Eric Myhre

More DRY'ing efforts in codegen.

Some are easier than others.

I'm starting to evolve a (still ad-hoc) naming convention for the
extracted functions in order to provide some cues for how common you can
expect the thing to be.  Scalars have a lot more commonizable stuff
than non-scalars, for example.
parent 8d848edd
......@@ -67,3 +67,60 @@ func emitTypicalTypedNodeMethodRepresentation(w io.Writer, adjCfg *AdjunctCfg, d
}
`, w, adjCfg, data)
}
// Turns out basically all builders are just an embed of the corresponding assembler.
func emitEmitNodeBuilderType_typical(w io.Writer, adjCfg *AdjunctCfg, data interface{}) {
doTemplate(`
type _{{ .Type | TypeSymbol }}__Builder struct {
_{{ .Type | TypeSymbol }}__Assembler
}
`, w, adjCfg, data)
}
// Builder build and reset methods are common even when some parts of the assembler vary.
// We count on the zero value of any addntl non-common fields of the assembler being correct.
func emitNodeBuilderMethods_typical(w io.Writer, adjCfg *AdjunctCfg, data interface{}) {
doTemplate(`
func (nb *_{{ .Type | TypeSymbol }}__Builder) Build() ipld.Node {
if *nb.m != schema.Maybe_Value {
panic("invalid state: cannot call Build on an assembler that's not finished")
}
return nb.w
}
func (nb *_{{ .Type | TypeSymbol }}__Builder) Reset() {
var w _{{ .Type | TypeSymbol }}
var m schema.Maybe
*nb = _{{ .Type | TypeSymbol }}__Builder{_{{ .Type | TypeSymbol }}__Assembler{w: &w, m: &m}}
}
`, w, adjCfg, data)
}
// emitNodeAssemblerType_scalar emits a NodeAssembler that's typical for a scalar.
// Types that are recursive tend to have more state and custom stuff, so won't use this
// (although the 'm' and 'w' variable names may still be presumed universally).
func emitNodeAssemblerType_scalar(w io.Writer, adjCfg *AdjunctCfg, data interface{}) {
doTemplate(`
type _{{ .Type | TypeSymbol }}__Assembler struct {
w *_{{ .Type | TypeSymbol }}
m *schema.Maybe
}
func (na *_{{ .Type | TypeSymbol }}__Assembler) reset() {}
`, w, adjCfg, data)
}
/*
Some things that might make it easier to DRY stuff, if they were standard in the 'data' obj:
- KindUpper
- e.g. makes it possible to hoist out 'AssignNull', which needs to refer to a kind-particular mixin type.
- also usable for to make 'AssignNode' hoistable for scalars.
- works purely textually for scalars, conveniently.
- maps and lists would need to branch entirely for the bottom half of the method.
- IsRepr
- ...? Somewhat unsure on this one; many different ways to cut this.
- Would be used as `{{if .IsRepr}}Repr{{end}}` in some cases, and `{{if .IsRepr}}__Repr{{end}}` in others...
which is viable, but somewhat disconcerting? I dunno, maybe it's fine.
- Also would be sometimes used as `{{if .IsRepr}}.Repr{{end}}`, in the middle of some help and error texts.
*/
......@@ -141,36 +141,13 @@ type intBuilderGenerator struct {
}
func (g intBuilderGenerator) EmitNodeBuilderType(w io.Writer) {
doTemplate(`
type _{{ .Type | TypeSymbol }}__Builder struct {
_{{ .Type | TypeSymbol }}__Assembler
}
`, w, g.AdjCfg, g)
emitEmitNodeBuilderType_typical(w, g.AdjCfg, g)
}
func (g intBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) {
doTemplate(`
func (nb *_{{ .Type | TypeSymbol }}__Builder) Build() ipld.Node {
if *nb.m != schema.Maybe_Value {
panic("invalid state: cannot call Build on an assembler that's not finished")
}
return nb.w
}
func (nb *_{{ .Type | TypeSymbol }}__Builder) Reset() {
var w _{{ .Type | TypeSymbol }}
var m schema.Maybe
*nb = _{{ .Type | TypeSymbol }}__Builder{_{{ .Type | TypeSymbol }}__Assembler{&w, &m}}
}
`, w, g.AdjCfg, g)
emitNodeBuilderMethods_typical(w, g.AdjCfg, g)
}
func (g intBuilderGenerator) EmitNodeAssemblerType(w io.Writer) {
doTemplate(`
type _{{ .Type | TypeSymbol }}__Assembler struct {
w *_{{ .Type | TypeSymbol }}
m *schema.Maybe
}
func (na *_{{ .Type | TypeSymbol }}__Assembler) reset() {}
`, w, g.AdjCfg, g)
emitNodeAssemblerType_scalar(w, g.AdjCfg, g)
}
func (g intBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) {
doTemplate(`
......
......@@ -196,26 +196,10 @@ type listBuilderGenerator struct {
}
func (g listBuilderGenerator) EmitNodeBuilderType(w io.Writer) {
doTemplate(`
type _{{ .Type | TypeSymbol }}__Builder struct {
_{{ .Type | TypeSymbol }}__Assembler
}
`, w, g.AdjCfg, g)
emitEmitNodeBuilderType_typical(w, g.AdjCfg, g)
}
func (g listBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) {
doTemplate(`
func (nb *_{{ .Type | TypeSymbol }}__Builder) Build() ipld.Node {
if nb.state != laState_finished {
panic("invalid state: assembler for {{ .PkgName }}.{{ .Type.Name }} must be 'finished' before Build can be called!")
}
return nb.w
}
func (nb *_{{ .Type | TypeSymbol }}__Builder) Reset() {
var w _{{ .Type | TypeSymbol }}
var m schema.Maybe
*nb = _{{ .Type | TypeSymbol }}__Builder{_{{ .Type | TypeSymbol }}__Assembler{w: &w, m: &m, state: laState_initial}}
}
`, w, g.AdjCfg, g)
emitNodeBuilderMethods_typical(w, g.AdjCfg, g)
}
func (g listBuilderGenerator) EmitNodeAssemblerType(w io.Writer) {
// - 'w' is the "**w**ip" pointer.
......
......@@ -269,26 +269,10 @@ type mapBuilderGenerator struct {
}
func (g mapBuilderGenerator) EmitNodeBuilderType(w io.Writer) {
doTemplate(`
type _{{ .Type | TypeSymbol }}__Builder struct {
_{{ .Type | TypeSymbol }}__Assembler
}
`, w, g.AdjCfg, g)
emitEmitNodeBuilderType_typical(w, g.AdjCfg, g)
}
func (g mapBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) {
doTemplate(`
func (nb *_{{ .Type | TypeSymbol }}__Builder) Build() ipld.Node {
if nb.state != maState_finished {
panic("invalid state: assembler for {{ .PkgName }}.{{ .Type.Name }} must be 'finished' before Build can be called!")
}
return nb.w
}
func (nb *_{{ .Type | TypeSymbol }}__Builder) Reset() {
var w _{{ .Type | TypeSymbol }}
var m schema.Maybe
*nb = _{{ .Type | TypeSymbol }}__Builder{_{{ .Type | TypeSymbol }}__Assembler{w: &w, m: &m, state: maState_initial}}
}
`, w, g.AdjCfg, g)
emitNodeBuilderMethods_typical(w, g.AdjCfg, g)
}
func (g mapBuilderGenerator) EmitNodeAssemblerType(w io.Writer) {
// - 'w' is the "**w**ip" pointer.
......
......@@ -151,36 +151,13 @@ type stringBuilderGenerator struct {
}
func (g stringBuilderGenerator) EmitNodeBuilderType(w io.Writer) {
doTemplate(`
type _{{ .Type | TypeSymbol }}__Builder struct {
_{{ .Type | TypeSymbol }}__Assembler
}
`, w, g.AdjCfg, g)
emitEmitNodeBuilderType_typical(w, g.AdjCfg, g)
}
func (g stringBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) {
doTemplate(`
func (nb *_{{ .Type | TypeSymbol }}__Builder) Build() ipld.Node {
if *nb.m != schema.Maybe_Value {
panic("invalid state: cannot call Build on an assembler that's not finished")
}
return nb.w
}
func (nb *_{{ .Type | TypeSymbol }}__Builder) Reset() {
var w _{{ .Type | TypeSymbol }}
var m schema.Maybe
*nb = _{{ .Type | TypeSymbol }}__Builder{_{{ .Type | TypeSymbol }}__Assembler{&w, &m}}
}
`, w, g.AdjCfg, g)
emitNodeBuilderMethods_typical(w, g.AdjCfg, g)
}
func (g stringBuilderGenerator) EmitNodeAssemblerType(w io.Writer) {
doTemplate(`
type _{{ .Type | TypeSymbol }}__Assembler struct {
w *_{{ .Type | TypeSymbol }}
m *schema.Maybe
}
func (na *_{{ .Type | TypeSymbol }}__Assembler) reset() {}
`, w, g.AdjCfg, g)
emitNodeAssemblerType_scalar(w, g.AdjCfg, g)
}
func (g stringBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) {
doTemplate(`
......
......@@ -238,26 +238,10 @@ type structBuilderGenerator struct {
}
func (g structBuilderGenerator) EmitNodeBuilderType(w io.Writer) {
doTemplate(`
type _{{ .Type | TypeSymbol }}__Builder struct {
_{{ .Type | TypeSymbol }}__Assembler
}
`, w, g.AdjCfg, g)
emitEmitNodeBuilderType_typical(w, g.AdjCfg, g)
}
func (g structBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) {
doTemplate(`
func (nb *_{{ .Type | TypeSymbol }}__Builder) Build() ipld.Node {
if nb.state != maState_finished {
panic("invalid state: assembler for {{ .PkgName }}.{{ .Type.Name }} must be 'finished' before Build can be called!")
}
return nb.w
}
func (nb *_{{ .Type | TypeSymbol }}__Builder) Reset() {
var w _{{ .Type | TypeSymbol }}
var m schema.Maybe
*nb = _{{ .Type | TypeSymbol }}__Builder{_{{ .Type | TypeSymbol }}__Assembler{w: &w, m: &m, state: maState_initial}}
}
`, w, g.AdjCfg, g)
emitNodeBuilderMethods_typical(w, g.AdjCfg, g)
}
func (g structBuilderGenerator) EmitNodeAssemblerType(w io.Writer) {
// - 'w' is the "**w**ip" pointer.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment