diff --git a/dict-type.go b/dict-type.go new file mode 100644 index 0000000..4be213a --- /dev/null +++ b/dict-type.go @@ -0,0 +1,130 @@ +// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). +// All rights reserved. + +// dict-type.go +package expr + +import ( + "fmt" + "reflect" + "strings" +) + +type DictType map[any]any + +func newDict(dictAny map[any]*term) (dict *DictType) { + var d DictType + if dictAny != nil { + d = make(DictType, len(dictAny)) + for i, item := range dictAny { + d[i] = item + } + } else { + d = make(DictType) + } + dict = &d + return +} + +func (dict *DictType) toMultiLine(sb *strings.Builder, indent int) { + sb.WriteString(strings.Repeat("\t", indent)) + sb.WriteString("{\n") + + first := true + for name, value := range *dict { + if first { + first = false + } else { + sb.WriteByte(',') + sb.WriteByte('\n') + } + + sb.WriteString(strings.Repeat("\t", indent+1)) + if key, ok := name.(string); ok { + sb.WriteString(string('"') + key + string('"')) + } else { + sb.WriteString(fmt.Sprintf("%v", name)) + } + sb.WriteString(": ") + if f, ok := value.(Formatter); ok { + sb.WriteString(f.ToString(MultiLine)) + } else if _, ok = value.(Functor); ok { + sb.WriteString("func(){}") + } else { + sb.WriteString(fmt.Sprintf("%v", value)) + } + } + sb.WriteString(strings.Repeat("\t", indent)) + sb.WriteString("\n}") +} + +func (dict *DictType) ToString(opt FmtOpt) string { + var sb strings.Builder + if opt&MultiLine != 0 { + dict.toMultiLine(&sb, 0) + } else { + sb.WriteByte('{') + first := true + for key, value := range *dict { + if first { + first = false + } else { + sb.WriteString(", ") + } + if s, ok := key.(string); ok { + sb.WriteString(string('"') + s + string('"')) + } else { + sb.WriteString(fmt.Sprintf("%v", key)) + } + sb.WriteString(": ") + if formatter, ok := value.(Formatter); ok { + sb.WriteString(formatter.ToString(opt)) + } else if t, ok := value.(*term); ok { + sb.WriteString(t.String()) + } else { + sb.WriteString(fmt.Sprintf("%#v", value)) + } + } + sb.WriteByte('}') + } + return sb.String() +} + +func (dict *DictType) String() string { + return dict.ToString(0) +} + +func (dict *DictType) TypeName() string { + return "dict" +} + +func (dict *DictType) hasKey(target any) (ok bool) { + for key := range *dict { + if ok = reflect.DeepEqual(key, target); ok { + break + } + } + return +} + +func (dict *DictType) clone() (c *DictType) { + c = newDict(nil) + for k, v := range *dict { + (*c)[k] = v + } + return +} + +func (dict *DictType) merge(second *DictType) { + if second != nil { + for k, v := range *second { + (*dict)[k] = v + } + } +} + +func (dict *DictType) setItem(key any, value any) (err error) { + (*dict)[key]=value + return +} + diff --git a/operand-dict.go b/operand-dict.go index 2ff67fd..95b9463 100644 --- a/operand-dict.go +++ b/operand-dict.go @@ -4,124 +4,6 @@ // operand-dict.go package expr -import ( - "fmt" - "reflect" - "strings" -) - -type DictType map[any]any - -func newDict(dictAny map[any]*term) (dict *DictType) { - var d DictType - if dictAny != nil { - d = make(DictType, len(dictAny)) - for i, item := range dictAny { - d[i] = item - } - } else { - d = make(DictType) - } - dict = &d - return -} - -func (dict *DictType) toMultiLine(sb *strings.Builder, indent int) { - sb.WriteString(strings.Repeat("\t", indent)) - sb.WriteString("{\n") - - first := true - for name, value := range *dict { - if first { - first = false - } else { - sb.WriteByte(',') - sb.WriteByte('\n') - } - - sb.WriteString(strings.Repeat("\t", indent+1)) - if key, ok := name.(string); ok { - sb.WriteString(string('"') + key + string('"')) - } else { - sb.WriteString(fmt.Sprintf("%v", name)) - } - sb.WriteString(": ") - if f, ok := value.(Formatter); ok { - sb.WriteString(f.ToString(MultiLine)) - } else if _, ok = value.(Functor); ok { - sb.WriteString("func(){}") - } else { - sb.WriteString(fmt.Sprintf("%v", value)) - } - } - sb.WriteString(strings.Repeat("\t", indent)) - sb.WriteString("\n}") -} - -func (dict *DictType) ToString(opt FmtOpt) string { - var sb strings.Builder - if opt&MultiLine != 0 { - dict.toMultiLine(&sb, 0) - } else { - sb.WriteByte('{') - first := true - for key, value := range *dict { - if first { - first = false - } else { - sb.WriteString(", ") - } - if s, ok := key.(string); ok { - sb.WriteString(string('"') + s + string('"')) - } else { - sb.WriteString(fmt.Sprintf("%v", key)) - } - sb.WriteString(": ") - if formatter, ok := value.(Formatter); ok { - sb.WriteString(formatter.ToString(opt)) - } else if t, ok := value.(*term); ok { - sb.WriteString(t.String()) - } else { - sb.WriteString(fmt.Sprintf("%#v", value)) - } - } - sb.WriteByte('}') - } - return sb.String() -} - -func (dict *DictType) String() string { - return dict.ToString(0) -} - -func (dict *DictType) TypeName() string { - return "dict" -} - -func (dict *DictType) hasKey(target any) (ok bool) { - for key := range *dict { - if ok = reflect.DeepEqual(key, target); ok { - break - } - } - return -} - -func (dict *DictType) clone() (c *DictType) { - c = newDict(nil) - for k, v := range *dict { - (*c)[k] = v - } - return -} - -func (dict *DictType) merge(second *DictType) { - if second != nil { - for k, v := range *second { - (*dict)[k] = v - } - } -} // -------- dict term func newDictTerm(args map[any]*term) *term {