Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
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
}
Пример #5
0
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())
	}
}
Пример #6
0
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
}
Пример #7
0
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
}
Пример #8
0
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
	}
}