func listMap(context *runtime.MacroCallContext) (*runtime.Value, error) { list, err := context.Block.EvalNode(context.Nodes[0]) if err != nil { return nil, err } if list.Type != runtime.ListValue { return nil, runtime.NewRuntimeError(context.Nodes[0].Pos(), "expected a list") } ident := context.Nodes[1].(*parser.IdentifierNode).Token.Data callback := context.Nodes[2] mappedList := runtime.NewListValue() for _, item := range list.List { b := runtime.NewBlock([]parser.Node{callback}, runtime.NewScope(context.Block.Scope)) b.Scope.SetSymbolLocally(ident, runtime.NewSymbol(item)) result, err := b.Eval() if err != nil { return nil, err } mappedList.List = append(mappedList.List, result) } return mappedList, nil }
func builtinList(context *runtime.FunctionCallContext) (*runtime.Value, error) { l := runtime.NewListValue() for _, arg := range context.Args { l.List = append(l.List, arg) } return l, nil }
func stringsSplit(context *runtime.FunctionCallContext) (*runtime.Value, error) { if err := runtime.ValidateArguments(context, runtime.StringValue, runtime.StringValue); err != nil { return nil, err } parts := runtime.NewListValue() for _, item := range strings.Split(context.Args[0].Str, context.Args[1].Str) { parts.List = append(parts.List, runtime.NewStringValue(item)) } return parts, nil }
func listReverse(context *runtime.FunctionCallContext) (*runtime.Value, error) { if err := runtime.ValidateArguments(context, runtime.ListValue); err != nil { return nil, err } list := context.Args[0].List newList := runtime.NewListValue() for i := len(list) - 1; i >= 0; i-- { newList.List = append(newList.List, list[i]) } return newList, nil }
func builtinQuoted2List(context *runtime.FunctionCallContext) (*runtime.Value, error) { if err := runtime.ValidateArguments(context, runtime.QuotedValue); err != nil { return nil, err } quoted := context.Args[0].Quoted if list, isList := quoted.(*parser.ListNode); isList { l := runtime.NewListValue() for _, listNode := range list.Nodes { l.List = append(l.List, runtime.NewQuotedValue(listNode)) } return l, nil } else { return nil, runtime.NewRuntimeError(context.Pos, "expected a quoted list, not %s", quoted.Name()) } }
func listSeq(context *runtime.FunctionCallContext) (*runtime.Value, error) { if err := runtime.ValidateArguments(context, runtime.NumberValue, runtime.NumberValue); err != nil { return nil, err } low := context.Args[0].NumberToInt64() high := context.Args[1].NumberToInt64() if low > high { return nil, runtime.NewRuntimeError(context.Pos, "invalid argument(s), low can't be higher than high (%d > %d)", low, high) } l := runtime.NewListValue() for i := low; i <= high; i++ { l.List = append(l.List, runtime.NewNumberValueFromInt64(i)) } return l, nil }
func listRemove(context *runtime.FunctionCallContext) (*runtime.Value, error) { if err := runtime.ValidateArguments(context, runtime.ListValue, runtime.NumberValue); err != nil { return nil, err } list := context.Args[0].List size := int64(len(list)) index := context.Args[1].NumberToInt64() if index < 0 || index > size-1 { return nil, runtime.NewRuntimeError(context.Pos, "index %d out of bounds (list size is %d)", index, size) } newList := runtime.NewListValue() for i, item := range list { if int64(i) != index { newList.List = append(newList.List, item) } } return newList, nil }
func listRange(context *runtime.FunctionCallContext) (*runtime.Value, error) { var begin, end int64 err := runtime.ValidateArguments(context, runtime.ListValue, runtime.NumberValue, runtime.NumberValue) if err != nil { optionalErr := runtime.ValidateArguments(context, runtime.ListValue, runtime.NumberValue) if optionalErr == nil { begin = context.Args[1].NumberToInt64() end = int64(len(context.Args[0].List)) - 1 } else { return nil, optionalErr } } else { begin = context.Args[1].NumberToInt64() end = context.Args[2].NumberToInt64() } length := int64(len(context.Args[0].List)) if begin < 0 || begin > length-1 || begin > end || end < 0 || end > length-1 { return nil, runtime.NewRuntimeError(context.Pos, "invalid bounds %d and %d (list length is %d)", begin, end, length) } newList := runtime.NewListValue() for _, item := range context.Args[0].List[begin : end+1] { newList.List = append(newList.List, item) } if len(newList.List) == 1 { return newList.List[0], nil } else { return newList, nil } }