From fcdde50faaaac5e79a2de08b70de0ade9b190cd9 Mon Sep 17 00:00:00 2001 From: Aidan Date: Wed, 26 Aug 2020 23:45:02 -0700 Subject: [PATCH] added list index function --- stdlib/list.go | 39 +++++++++++++++++++++++++++++++++++++++ stdlib/stdlib.go | 9 +++++++++ 2 files changed, 48 insertions(+) diff --git a/stdlib/list.go b/stdlib/list.go index 13c1cdc..5e34364 100644 --- a/stdlib/list.go +++ b/stdlib/list.go @@ -96,6 +96,45 @@ func Len(input *ast.Token, vars ast.VarTable, funcs ast.FuncTable) *ast.Token { return ret } +/* Takes two arguments + * An index and a list + * Returns element indexed by index arg + * can return nil if index is out of bounds + * + * Example (index 2 (1 2 3)) -> 2 + */ +func Index(in *ast.Token, vars ast.VarTable, funcs ast.FuncTable) *ast.Token { + idx, err := strconv.ParseInt(in.Value(), 10, 64) + if err != nil || idx < 0 { + log.Log(log.ERR, + "index must be a positive integer: " + err.Error(), + "index") + return nil + } + + series := in.Next.Expand() + iter := &series + i := int64(0) + for i <= idx { + if *iter == nil { + log.Log(log.ERR, + "index out of bounds", + "index") + return nil + } + + if i < idx { + iter = &((*iter).Next) + } + + i += 1 + } + + ret := (*iter).Copy() + ret.Next = nil + return ret +} + /* Head * Returns first element in the list * Returns nil if input is not a list or if list is empty diff --git a/stdlib/stdlib.go b/stdlib/stdlib.go index 7f85b05..7781a96 100644 --- a/stdlib/stdlib.go +++ b/stdlib/stdlib.go @@ -72,6 +72,15 @@ func GenFuncTable() ast.FuncTable { ArgLazy: true, }, + "index": &ast.Function{ + Function: Index, + Name: "index", + Args: []ast.Token_t{ + ast.NUMBER, + ast.LIST, + }, + }, + "head": &ast.Function{ Function: Head, Name: "head",