diff --git a/stdlib/stdlib.go b/stdlib/stdlib.go index 83f40fd..fcd0b30 100644 --- a/stdlib/stdlib.go +++ b/stdlib/stdlib.go @@ -143,6 +143,13 @@ func GenFuncTable() ast.FuncTable { Args: -1, }, + "join": &ast.Function{ + Function: Join, + Name: "join", + TimesCalled: 0, + Args: 2, + }, + "split": &ast.Function{ Function: Split, Name: "split", diff --git a/stdlib/string.go b/stdlib/string.go index e9f00be..0cfe9f0 100644 --- a/stdlib/string.go +++ b/stdlib/string.go @@ -100,6 +100,50 @@ func Split(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { return res } +/* Takes two args, a delimiter and a list of strings + * Returns the list of strings concatenated together with the delimiter in between each element + * On error returns nil + * + * Example: (join ", " ("apple" "ananas" "pear")) -> "apple, ananas, pear" + */ +func Join(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { + in = in.Eval(ft, vt, false) + if in == nil || in.Next == nil { + log.Log(log.ERR, + "one or more arguments evaluated to nil", + "join") + return nil + } + + delim := in + strs := in.Next + if delim.Tag != ast.STRING || strs.Tag != ast.LIST { + log.Log(log.ERR, + "first argument must be a string (delimiter) and second argument must be a list (strings)", + "join") + return nil + } + + de := delim.Value() + res := "" + for i := strs.Expand(); i != nil; i = i.Next { + if i.Tag != ast.STRING { + log.Log(log.ERR, + "all items to be joined must be strings", + "join") + return nil + } + + res += i.Value() + if i.Next != nil { + res += de + } + } + + ret := &ast.Token{Tag: ast.STRING} + ret.Set(res) + return ret +} /* Takes one arg, returns nil * Prints a string to stdout