예제 #1
0
func builtinString(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.AnyValue); err != nil {
		return nil, err
	}

	return runtime.NewStringValue(context.Args[0].String()), nil
}
예제 #2
0
func stringsUpper(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.StringValue); err != nil {
		return nil, err
	}

	return runtime.NewStringValue(strings.ToUpper(context.Args[0].Str)), nil
}
예제 #3
0
func builtinMath(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.NumberValue, runtime.NumberValue); err != nil {
		return nil, err
	}

	base := big.NewRat(0, 1)

	var callback func(*big.Rat, *big.Rat) *big.Rat

	switch context.Name {
	case "+":
		callback = base.Add
	case "-":
		callback = base.Sub
	case "*":
		callback = base.Mul
	case "/":
		if context.Args[1].Number.Cmp(base) == 0 {
			return nil, runtime.NewRuntimeError(context.Pos, "division by zero")
		}

		callback = base.Quo
	}

	return runtime.NewNumberValueFromRat(callback(context.Args[0].Number, context.Args[1].Number)), nil
}
예제 #4
0
func stringsReverse(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.StringValue); err != nil {
		return nil, err
	}

	return runtime.NewStringValue(util.ReverseString(context.Args[0].Str)), nil
}
예제 #5
0
func stringsContains(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.StringValue, runtime.StringValue); err != nil {
		return nil, err
	}

	return runtime.BooleanValueFor(strings.Contains(context.Args[0].Str, context.Args[1].Str)), nil
}
예제 #6
0
func mathRad2Deg(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.NumberValue); err != nil {
		return nil, err
	}

	return runtime.NewNumberValueFromFloat64((context.Args[0].NumberToFloat64() * 180) / math.Pi), nil
}
예제 #7
0
func mathSimpleMath(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.NumberValue); err != nil {
		return nil, err
	}

	var callback func(float64) float64

	switch context.Name {
	case "sqrt":
		callback = math.Sqrt
	case "sin":
		callback = math.Sin
	case "cos":
		callback = math.Cos
	case "tan":
		callback = math.Tan
	case "ceil":
		callback = math.Ceil
	case "floor":
		callback = math.Floor
	case "abs":
		callback = math.Abs
	case "log":
		callback = math.Log
	case "log10":
		callback = math.Log10
	}

	return runtime.NewNumberValueFromFloat64(callback(context.Args[0].NumberToFloat64())), nil
}
예제 #8
0
func mathPow(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.NumberValue, runtime.NumberValue); err != nil {
		return nil, err
	}

	return runtime.NewNumberValueFromFloat64(math.Pow(context.Args[0].NumberToFloat64(), context.Args[1].NumberToFloat64())), nil
}
예제 #9
0
func listSize(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.ListValue); err != nil {
		return nil, err
	}

	return runtime.NewNumberValueFromInt64(int64(len(context.Args[0].List))), nil
}
예제 #10
0
func mathMod(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.NumberValue, runtime.NumberValue); err != nil {
		return nil, err
	}

	return runtime.NewNumberValueFromInt64(context.Args[0].NumberToInt64() % context.Args[1].NumberToInt64()), nil
}
예제 #11
0
func stringsLength(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.StringValue); err != nil {
		return nil, err
	}

	return runtime.NewNumberValueFromInt64(int64(len(context.Args[0].Str))), nil
}
예제 #12
0
func stringsCharacterCheck(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.StringValue); err != nil {
		return nil, err
	}

	s := context.Args[0].Str

	if len(s) != 1 {
		return nil, runtime.NewRuntimeError(context.Pos, "expected string that has 1 character, got %d character(s)", len(s))
	}

	var callback func(rune) bool

	switch context.Name {
	case "is-digit":
		callback = unicode.IsDigit
	case "is-letter":
		callback = unicode.IsLetter
	case "is-lower":
		callback = unicode.IsLower
	case "is-upper":
		callback = unicode.IsUpper
	}

	return runtime.BooleanValueFor(callback(rune(s[0]))), nil
}
예제 #13
0
func builtinNot(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.BooleanValue); err != nil {
		return nil, err
	}

	return runtime.BooleanValueFor(!context.Args[0].Boolean), nil
}
예제 #14
0
func builtinEval(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.QuotedValue); err != nil {
		return nil, err
	}

	return context.Block.EvalNode(context.Args[0].Quoted)
}
예제 #15
0
func builtinPass(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.AnyValue); err != nil {
		return runtime.Nil, nil
	}

	return context.Args[0], nil
}
예제 #16
0
func listPushLeft(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.ListValue, runtime.AnyValue); err != nil {
		return nil, err
	}

	context.Args[0].List = append([]*runtime.Value{context.Args[1]}, context.Args[0].List...)

	return context.Args[0], nil
}
예제 #17
0
func stringsTrim(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.StringValue, runtime.StringValue); err != nil {
		return nil, err
	}

	source := context.Args[0].Str
	cutset := context.Args[1].Str
	return runtime.NewStringValue(strings.Trim(source, cutset)), nil
}
예제 #18
0
func stringsRuneAt(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.StringValue, runtime.NumberValue); err != nil {
		return nil, err
	}

	source := context.Args[0].Str
	index := context.Args[1].NumberToInt64()
	return runtime.NewStringValue(string([]rune(source)[index])), nil
}
예제 #19
0
func listJoin(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.ListValue, runtime.ListValue); err != nil {
		return nil, err
	}

	for _, item := range context.Args[1].List {
		context.Args[0].List = append(context.Args[0].List, item)
	}

	return context.Args[0], nil
}
예제 #20
0
func stringsReplace(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	n := -1

	err := runtime.ValidateArguments(context, runtime.StringValue, runtime.StringValue, runtime.StringValue, runtime.NumberValue)

	if err != nil {
		optionalErr := runtime.ValidateArguments(context, runtime.StringValue, runtime.StringValue, runtime.StringValue)

		if optionalErr != nil {
			return nil, err
		}
	} else {
		n = int(context.Args[3].NumberToInt64())
	}

	source := context.Args[0].Str
	search := context.Args[1].Str
	replace := context.Args[2].Str

	return runtime.NewStringValue(strings.Replace(source, search, replace, n)), nil
}
예제 #21
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
}
예제 #22
0
func listContains(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.ListValue, runtime.AnyValue); err != nil {
		return nil, err
	}

	for _, item := range context.Args[0].List {
		if item.Equals(context.Args[1]) {
			return runtime.True, nil
		}
	}

	return runtime.False, nil
}
예제 #23
0
func listGet(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.ListValue, runtime.NumberValue); err != nil {
		return nil, err
	}

	size := int64(len(context.Args[0].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)
	}

	return context.Args[0].List[index], nil
}
예제 #24
0
func builtinAssert(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	optionalError := runtime.ValidateArguments(context, runtime.BooleanValue)

	if optionalError != nil {
		err := runtime.ValidateArguments(context, runtime.BooleanValue, runtime.StringValue)

		if err != nil {
			return nil, err
		}
	}

	if !context.Args[0].Boolean {
		message := "assertion failed"

		if len(context.Args) == 2 {
			message += ": " + context.Args[1].Str
		}

		return nil, runtime.NewRuntimeError(context.Pos, message)
	}

	return runtime.Nil, nil
}
예제 #25
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
}
예제 #26
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
	}
}
예제 #27
0
func listDropLeft(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.ListValue); err != nil {
		return nil, err
	}

	l := context.Args[0]

	if len(l.List) == 0 {
		return nil, runtime.NewRuntimeError(context.Pos, "empty list")
	}

	l.List = l.List[1:]

	return context.Args[0], nil
}
예제 #28
0
func listContainsKey(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.ListValue, runtime.KeywordValue); err != nil {
		return nil, err
	}

	l := context.Args[0].List

	for i := 0; i < len(l); i++ {
		if l[i].Type == runtime.KeywordValue && l[i].Keyword == context.Args[1].Keyword && i+1 < len(l) {
			return runtime.True, nil
		}
	}

	return runtime.False, nil
}
예제 #29
0
func listGetKey(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.ListValue, runtime.KeywordValue); err != nil {
		return nil, err
	}

	l := context.Args[0]

	for i := 0; i < len(l.List); i++ {
		if l.List[i].Type == runtime.KeywordValue && l.List[i].Keyword == context.Args[1].Keyword && i+1 < len(l.List) {
			return l.List[i+1], nil
		}
	}

	return runtime.Nil, nil
}
예제 #30
0
func listRemoveKey(context *runtime.FunctionCallContext) (*runtime.Value, error) {
	if err := runtime.ValidateArguments(context, runtime.ListValue, runtime.KeywordValue); err != nil {
		return nil, err
	}

	l := context.Args[0]

	for i := 0; i < len(l.List); i++ {
		if l.List[i].Type == runtime.KeywordValue && l.List[i].Keyword == context.Args[1].Keyword && i+1 < len(l.List) {
			l.List = append(l.List[:i], l.List[i+1:]...)
			l.List = append(l.List[:i], l.List[i+1:]...)
		}
	}

	return l, nil
}