// Package rep implements representations of Forge code - internal ones // as slices and maps and corresponding external ones using serialization // formats like JSON and YAML. package rep import ( "fmt" "strings" "git.sr.ht/~cco/go-scopes/common/voc" "git.sr.ht/~cco/go-scopes/forge" "git.sr.ht/~cco/go-scopes/logging/log" ) // may be: code, module, string, int, float type citem interface{} type coderep interface { Compile(forge.FE) forge.FPtr } // code, represented by a slice type code []citem func Code(items ...citem) code { return code(items) } func (ci code) Compile(f forge.FE) forge.FPtr { c := f.Code() for _, item := range ci { switch i := item.(type) { case int: c.Append(i) case float64: c.Append(int(i)) case string: if v, err := compStr(f, i); err == nil { c.Append(v) } else { log.Error(err).Msg("rep.Compile") } case code: c.Append(i.Compile(f)) case []interface{}: c.Append(makeCode(i).Compile(f)) case module: c.Append(i.Compile(f)) case map[string]interface{}: c.Append(makeModule(i).Compile(f)) case record: c.Append(i.Compile(f)) default: c.Append(makeRecord(i).Compile(f)) } } return c.Reset() } func compStr(f forge.FE, s string) (forge.FItem, error) { if strings.HasPrefix(s, "'") { return forge.FItem(strings.Trim(s, "'")), nil } if v, ok := f.Voc().Lookup(s); ok { return forge.FItem(v), nil } return nil, fmt.Errorf("not found: '%s'", s) } func makeCode(ri []interface{}) code { c := code{} for _, it := range ri { c = append(c, it) } return c } // module - code definitions, represented by a map that is used as a forge vocabulary type module map[string]citem func (m module) Compile(f forge.FE) forge.FPtr { v := voc.NewVoc(f.Voc()) return f.Code(v) } func makeModule(ri map[string]interface{}) module { m := module{} for k, v := range ri { m[k] = v } return m } // record - some data structure, typically represented as struct type Record = record type record struct { data interface{} } func (r *record) Compile(f forge.FE) forge.FPtr { return nil } func (r *record) Data() interface{} { return r.data } func makeRecord(ri interface{}) *record { return &record{ri} }