some rudimentary list operations
This commit is contained in:
parent
5d538d4a0b
commit
15e294085c
2 changed files with 98 additions and 0 deletions
|
|
@ -18,6 +18,7 @@
|
|||
package stdlib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitlab.com/whom/shs/ast"
|
||||
"gitlab.com/whom/shs/log"
|
||||
)
|
||||
|
|
@ -28,6 +29,7 @@ import (
|
|||
* in event a not-list is passed in, returns the arg.
|
||||
*/
|
||||
func Expand(input *ast.Token, vars ast.VarTable, funcs ast.FuncTable) *ast.Token {
|
||||
input = input.Eval(funcs, vars, false)
|
||||
if input.Tag != ast.LIST {
|
||||
log.Log(log.INFO, "expand called on not a list", "expand")
|
||||
return input
|
||||
|
|
@ -42,6 +44,7 @@ func Expand(input *ast.Token, vars ast.VarTable, funcs ast.FuncTable) *ast.Token
|
|||
* if no args are a list, a list is made from all args
|
||||
*/
|
||||
func L_append(input *ast.Token, vars ast.VarTable, funcs ast.FuncTable) *ast.Token {
|
||||
input = input.Eval(funcs, vars, false)
|
||||
src := input
|
||||
|
||||
if input.Tag != ast.LIST {
|
||||
|
|
@ -68,3 +71,76 @@ func L_append(input *ast.Token, vars ast.VarTable, funcs ast.FuncTable) *ast.Tok
|
|||
|
||||
return src
|
||||
}
|
||||
|
||||
/* Len
|
||||
* Returns length of list as a number
|
||||
* Returns nil if not a list
|
||||
*
|
||||
* Example: () -> 0
|
||||
* Example: (1 2 3) -> 3
|
||||
*/
|
||||
func Len(input *ast.Token, vars ast.VarTable, funcs ast.FuncTable) *ast.Token {
|
||||
input = input.Eval(funcs, vars, false)
|
||||
if input.Tag != ast.LIST {
|
||||
log.Log(log.ERR,
|
||||
"non-list as parameter to head",
|
||||
"head")
|
||||
return nil
|
||||
}
|
||||
|
||||
length := 0
|
||||
for iter := input.Expand(); iter != nil; iter = iter.Next {
|
||||
length += 1
|
||||
}
|
||||
|
||||
ret := &ast.Token{Tag: ast.NUMBER}
|
||||
ret.Set(fmt.Sprintf("%d", length))
|
||||
return ret
|
||||
}
|
||||
|
||||
/* Head
|
||||
* Returns first element in the list
|
||||
* Returns nil if input is not a list or if list is empty
|
||||
*
|
||||
* Example: (head (2 3 4)) -> 2
|
||||
*/
|
||||
func Head(input *ast.Token, vars ast.VarTable, funcs ast.FuncTable) *ast.Token {
|
||||
input = input.Eval(funcs, vars, false)
|
||||
if input.Tag != ast.LIST {
|
||||
log.Log(log.ERR,
|
||||
"non-list as parameter to head",
|
||||
"head")
|
||||
return nil
|
||||
}
|
||||
|
||||
li := input.Expand().Copy()
|
||||
if li != nil {
|
||||
li.Next = nil
|
||||
}
|
||||
|
||||
return li
|
||||
}
|
||||
|
||||
/* Tail
|
||||
* Returns last element in a list
|
||||
* Returns nil if not a list
|
||||
*
|
||||
* Example: (tail (2 3 4)) -> 4
|
||||
*/
|
||||
func Tail(input *ast.Token, vars ast.VarTable, funcs ast.FuncTable) *ast.Token {
|
||||
input = input.Eval(funcs, vars, false)
|
||||
if input.Tag != ast.LIST {
|
||||
log.Log(log.ERR,
|
||||
"non-list as parameter to head",
|
||||
"head")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
iter := input.Expand()
|
||||
for iter != nil && iter.Next != nil {
|
||||
iter = iter.Next
|
||||
}
|
||||
|
||||
return iter.Copy()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue