Skip to content

Commit

Permalink
Merge pull request #94 from gekkowrld/strfmt
Browse files Browse the repository at this point in the history
Extend the string object to format code. Closes #81 .
  • Loading branch information
AvicennaJr authored Oct 30, 2024
2 parents f8d1a7d + aa194e8 commit e9c3aec
Showing 1 changed file with 94 additions and 0 deletions.
94 changes: 94 additions & 0 deletions object/strings.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package object

import (
"fmt"
"hash/fnv"
"strconv"
"strings"
)

Expand Down Expand Up @@ -39,6 +41,8 @@ func (s *String) Method(method string, args []Object) Object {
return s.lower(args)
case "gawa":
return s.split(args)
case "panga":
return s.format(args)
default:
return newError("Samahani, kiendesha hiki hakitumiki na tungo (Neno)")
}
Expand Down Expand Up @@ -81,3 +85,93 @@ func (s *String) split(args []Object) Object {
}
return &Array{Elements: elements}
}

func (s *String) format(args []Object) Object {
value, err := formatStr(s.Value, args)

if err != nil {
return newError(err.Error())
}

return &String{Value: value}
}

func formatStr(format string, options []Object) (string, error) {
var str strings.Builder
var val strings.Builder
var check_val bool
var opts_len int = len(options)

var escapeChar bool

type optM struct {
val bool
obj Object
}

var optionsMap = make(map[int]optM, opts_len)

for i, optm := range options {
optionsMap[i] = optM{val: false, obj: optm}
}

for _, opt := range format {

if !escapeChar && opt == '\\' {
escapeChar = true
continue
}

if opt == '{' && !escapeChar {
check_val = true
continue
}

if escapeChar {
if opt != '{' && opt != '}' {
str.WriteRune('\\')
}
escapeChar = false
}

if check_val && opt == '}' {
vstr := strings.TrimSpace(val.String())
arrv, err := strconv.Atoi(vstr)
if err != nil {
return "", fmt.Errorf(fmt.Sprintf("Ulichopeana si NAMBA, jaribu tena: `%s'", vstr))
}

oVal, exists := optionsMap[arrv]

if !exists {
return "", fmt.Errorf(fmt.Sprintf("Nambari ya chaguo unalolitaka %d ni kubwa kuliko ulizopeana (%d)", arrv, opts_len))
}

str.WriteString(oVal.obj.Inspect())
optionsMap[arrv] = optM{val: true, obj: oVal.obj}

check_val = false
val.Reset()
continue
}

if check_val {
val.WriteRune(opt)
continue
}

str.WriteRune(opt)
}

if check_val {
return "", fmt.Errorf(fmt.Sprintf("Haukufunga '{', tuliokota kabla ya kufika mwisho `%s'", val.String()))
}

for _, v := range optionsMap {
if !v.val {
return "", fmt.Errorf(fmt.Sprintf("Ulipeana hili chaguo (%s) {%s} lakini haukutumia", v.obj.Inspect(), v.obj.Type()))
}
}

return str.String(), nil
}

0 comments on commit e9c3aec

Please sign in to comment.