예제 #1
0
파일: lists.go 프로젝트: raoulvdberge/stak
func list(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "list", parser.VALUE_FUNCTION)

	if err != nil {
		return err
	}

	if values[0].F.Type != parser.FUNCTION_LAMBDA {
		return util.NewInvalidArgumentError("list", "expected a lambda", context.Token.Line, context.Token.Column, context.Token.File)
	}

	err = values[0].F.L.Exec()

	if err != nil {
		return err
	}

	var data []*parser.Value

	list := parser.NewListValue()

	for values[0].F.L.Stack.Len() > 0 {
		data = append(data, values[0].F.L.Stack.Pop().(*parser.Value))
	}

	for i := len(data) - 1; i >= 0; i-- {
		list.L = append(list.L, data[i])
	}

	context.Block.Stack.Push(list)

	return nil
}
예제 #2
0
파일: lists.go 프로젝트: raoulvdberge/stak
func listFilter(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "list-filter", parser.VALUE_FUNCTION, parser.VALUE_LIST)

	if err != nil {
		return err
	}

	list := parser.NewListValue()

	for _, item := range values[1].L {
		block, err := execFunctionWithArguments(context, values[0].F, "list-filter", false, item)

		if err != nil {
			return err
		}

		if block.Stack.Len() == 1 {
			b := block.Stack.Pop().(*parser.Value)

			if b.Type != parser.VALUE_BOOL {
				return util.NewInvalidArgumentError("list-filter", "callback function should have a boolean value on the stack, found "+b.Type.String(), context.Token.Line, context.Token.Column, context.Token.File)
			}

			if b.B {
				list.L = append(list.L, item)
			}
		} else {
			return util.NewInvalidArgumentError("list-filter", fmt.Sprintf("callback function needs to exactly have 1 boolean value on top of the stack, found %d", block.Stack.Len()), context.Token.Line, context.Token.Column, context.Token.File)
		}
	}

	context.Block.Stack.Push(list)

	return nil
}
예제 #3
0
파일: lists.go 프로젝트: raoulvdberge/stak
func listSeq(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "list-seq", parser.VALUE_NUMBER, parser.VALUE_NUMBER)

	if err != nil {
		return err
	}

	newList := parser.NewListValue()

	min, _ := values[1].N.Float64()
	max, _ := values[0].N.Float64()

	if int(min) > int(max) {
		for i := int(min); i >= int(max); i-- {
			newList.L = append(newList.L, parser.NewValueFromInt64(int64(i)))
		}
	} else {
		for i := int(min); i <= int(max); i++ {
			newList.L = append(newList.L, parser.NewValueFromInt64(int64(i)))
		}
	}

	context.Block.Stack.Push(newList)

	return nil
}
예제 #4
0
파일: lists.go 프로젝트: raoulvdberge/stak
func listMap(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "list-map", parser.VALUE_FUNCTION, parser.VALUE_LIST)

	if err != nil {
		return err
	}

	list := parser.NewListValue()

	for _, item := range values[1].L {
		block, err := execFunctionWithArguments(context, values[0].F, "list-map", false, item)

		if err != nil {
			return err
		}

		for block.Stack.Len() > 0 {
			list.L = append(list.L, block.Stack.Pop().(*parser.Value))
		}
	}

	context.Block.Stack.Push(list)

	return nil
}
예제 #5
0
파일: std.go 프로젝트: raoulvdberge/stak
func keep(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "keep", parser.VALUE_NUMBER)

	if err != nil {
		return err
	}

	n, _ := values[0].N.Float64()

	if int(n) < 0 || int(n) > context.Block.Stack.Len() {
		return util.NewInvalidArgumentError("keep", fmt.Sprintf("cannot keep %d values while stack height is %d", int(n), context.Block.Stack.Len()), context.Token.Line, context.Token.Column, context.Token.File)
	}

	var kept []*parser.Value

	for i := 0; i < int(n); i++ {
		kept = append(kept, context.Block.Stack.Pop().(*parser.Value))
	}

	for context.Block.Stack.Len() > 0 {
		context.Block.Stack.Pop()
	}

	for i := len(kept) - 1; i >= 0; i-- {
		context.Block.Stack.Push(kept[i])
	}

	return nil
}
예제 #6
0
func stringFormat(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "string-format", parser.VALUE_STRING)

	if err != nil {
		return err
	}

	format := values[0].S
	count := strings.Count(format, "{}")

	if count > context.Block.Stack.Len() {
		return util.NewArgumentCountError("string-format", count, context.Block.Stack.Len(), context.Token.Line, context.Token.Column, context.Token.File)
	}

	var items []*parser.Value

	for i := 0; i < count; i++ {
		items = append(items, context.Block.Stack.Pop().(*parser.Value))
	}

	for i := count - 1; i >= 0; i-- {
		format = strings.Replace(format, "{}", items[i].String(), 1)
	}

	context.Block.Stack.Push(parser.NewValueFromString(format))

	return nil
}
예제 #7
0
func stringRange(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "string-range", parser.VALUE_NUMBER, parser.VALUE_NUMBER, parser.VALUE_STRING)

	if err != nil {
		return err
	}

	beginf, _ := values[1].N.Float64()
	endf, _ := values[0].N.Float64()

	begin := int(beginf)
	end := int(endf)

	s := values[2].S

	if begin < 0 || begin > len(s)-1 {
		return util.NewInvalidArgumentError("string-range", fmt.Sprintf("%d out of range (string length is: %d)", begin, len(s)), context.Token.Line, context.Token.Column, context.Token.File)
	}

	if end < begin {
		return util.NewInvalidArgumentError("string-range", fmt.Sprintf("%d must be bigger then %d", end, begin), context.Token.Line, context.Token.Column, context.Token.File)
	}

	if end < 0 || end > len(s)-1 {
		return util.NewInvalidArgumentError("string-range", fmt.Sprintf("%d out of range (string length is: %d)", end, len(s)), context.Token.Line, context.Token.Column, context.Token.File)
	}

	context.Block.Stack.Push(parser.NewValueFromString(s[begin : end+1]))

	return nil
}
예제 #8
0
파일: std.go 프로젝트: raoulvdberge/stak
func while_(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "while", parser.VALUE_FUNCTION, parser.VALUE_FUNCTION)

	if err != nil {
		return err
	}

	check := values[0].F

recheck:
	fakeBlock := parser.NewBlock(nil, nil, nil)

	checkErr := check.Exec(fakeBlock, context.Token)

	if checkErr != nil {
		return checkErr
	}

	if fakeBlock.Stack.Len() != 1 || fakeBlock.Stack.Peek(0).(*parser.Value).Type != parser.VALUE_BOOL {
		return util.NewInvalidArgumentError("while", "the callback function provided to while must return 1 boolean value", context.Token.Line, context.Token.Column, context.Token.File)
	}

	if fakeBlock.Stack.Peek(0).(*parser.Value).B {
		runErr := values[1].F.Exec(context.Block, context.Token)

		if runErr != nil {
			return runErr
		}

		goto recheck
	}

	return nil
}
예제 #9
0
파일: std.go 프로젝트: raoulvdberge/stak
func orN(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "or-n", parser.VALUE_FUNCTION)

	if err != nil {
		return err
	}

	fakeBlock := parser.NewBlock(nil, nil, nil)

	runErr := values[0].F.Exec(fakeBlock, context.Token)

	if runErr != nil {
		return runErr
	}

	result := false

	if fakeBlock.Stack.Len() >= 1 {
		for fakeBlock.Stack.Len() > 0 {
			value := fakeBlock.Stack.Pop().(*parser.Value)

			if value.Type != parser.VALUE_BOOL {
				return util.NewInvalidArgumentError("or-n", "expected a boolean in the function stack", context.Token.Line, context.Token.Column, context.Token.File)
			}

			result = result || value.B
		}
	} else {
		return util.NewInvalidArgumentError("or-n", "expected at least 2 values to compare in function stack", context.Token.Line, context.Token.Column, context.Token.File)
	}

	context.Block.Stack.Push(parser.NewValueFromBool(result))

	return nil
}
예제 #10
0
파일: lists.go 프로젝트: raoulvdberge/stak
func listRange(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "list-range", parser.VALUE_NUMBER, parser.VALUE_NUMBER, parser.VALUE_LIST)

	if err != nil {
		return err
	}

	newList := parser.NewListValue()
	list := values[2].L

	start, _ := values[1].N.Float64()
	end, _ := values[0].N.Float64()

	if int(start) > int(end) || int(end) >= len(list) || int(start) < 0 || int(end) < 0 {
		return util.NewInvalidArgumentError("list-range", "invalid bounds", context.Token.Line, context.Token.Column, context.Token.File)
	}

	for i := int(start); i <= int(end); i++ {
		newList.L = append(newList.L, list[i])
	}

	context.Block.Stack.Push(newList)

	return nil
}
예제 #11
0
파일: files.go 프로젝트: raoulvdberge/stak
func fileRemove(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "file-remove", parser.VALUE_STRING)

	if err != nil {
		return err
	}

	return os.Remove(values[0].S)
}
예제 #12
0
파일: std.go 프로젝트: raoulvdberge/stak
func call(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "call", parser.VALUE_FUNCTION)

	if err != nil {
		return err
	}

	return values[0].F.Exec(context.Block, context.Token)
}
예제 #13
0
파일: std.go 프로젝트: raoulvdberge/stak
func drop(context *parser.FunctionCallContext) error {
	_, err := parser.ValidateArguments(context, "drop", parser.VALUE_ANY)

	if err != nil {
		return err
	}

	return nil
}
예제 #14
0
파일: std.go 프로젝트: raoulvdberge/stak
func print_(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "print", parser.VALUE_ANY)

	if err != nil {
		return err
	}

	fmt.Print(values[0])

	return nil
}
예제 #15
0
func stringAt(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "string-at", parser.VALUE_STRING, parser.VALUE_STRING)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(parser.NewValueFromInt64(int64(strings.Index(values[1].S, values[0].S))))

	return nil
}
예제 #16
0
파일: std.go 프로젝트: raoulvdberge/stak
func clone(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "clone", parser.VALUE_ANY)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(values[0].Copy())

	return nil
}
예제 #17
0
func stringLength(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "string-length", parser.VALUE_STRING)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(parser.NewValueFromInt64(int64(len(values[0].S))))

	return nil
}
예제 #18
0
파일: files.go 프로젝트: raoulvdberge/stak
func fileCreate(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "file-create", parser.VALUE_STRING)

	if err != nil {
		return err
	}

	_, err = os.Create(values[0].S)

	return err
}
예제 #19
0
func stringUpper(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "string-upper", parser.VALUE_STRING)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(parser.NewValueFromString(strings.ToUpper(values[0].S)))

	return nil
}
예제 #20
0
파일: math.go 프로젝트: raoulvdberge/stak
func abs(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "abs", parser.VALUE_NUMBER)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(parser.NewValueFromRat(big.NewRat(0, 1).Abs(values[0].N)))

	return nil
}
예제 #21
0
파일: std.go 프로젝트: raoulvdberge/stak
func xor(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "xor", parser.VALUE_BOOL, parser.VALUE_BOOL)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(parser.NewValueFromBool(values[0].B || values[1].B && !(values[0].B && values[1].B)))

	return nil
}
예제 #22
0
func stringCat(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "string-cat", parser.VALUE_ANY, parser.VALUE_ANY)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(parser.NewValueFromString(values[1].String() + values[0].String()))

	return nil
}
예제 #23
0
파일: errors.go 프로젝트: raoulvdberge/stak
func err(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "err", parser.VALUE_ANY)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(parser.NewErrorValue(values[0]))

	return nil
}
예제 #24
0
func stringContains(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "string-contains?", parser.VALUE_STRING, parser.VALUE_STRING)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(parser.NewValueFromBool(strings.Contains(values[1].S, values[0].S)))

	return nil
}
예제 #25
0
파일: std.go 프로젝트: raoulvdberge/stak
func not(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "not", parser.VALUE_BOOL)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(parser.NewValueFromBool(!values[0].B))

	return nil
}
예제 #26
0
파일: files.go 프로젝트: raoulvdberge/stak
func fileMkdir(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "file-mkdir", parser.VALUE_STRING, parser.VALUE_NUMBER)

	if err != nil {
		return err
	}

	perms, _ := values[1].N.Float64()

	return os.Mkdir(values[0].String(), os.FileMode(perms))
}
예제 #27
0
파일: std.go 프로젝트: raoulvdberge/stak
func ne(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "ne?", parser.VALUE_ANY, parser.VALUE_ANY)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(parser.NewValueFromBool(!values[0].Equals(values[1])))

	return nil
}
예제 #28
0
파일: std.go 프로젝트: raoulvdberge/stak
func le(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "le?", parser.VALUE_NUMBER, parser.VALUE_NUMBER)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(parser.NewValueFromBool(values[1].N.Cmp(values[0].N) <= 0))

	return nil
}
예제 #29
0
파일: lists.go 프로젝트: raoulvdberge/stak
func listSize(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "list-size", parser.VALUE_LIST)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(parser.NewValueFromInt64(int64(len(values[0].L))))

	return nil
}
예제 #30
0
파일: files.go 프로젝트: raoulvdberge/stak
func fileBase(context *parser.FunctionCallContext) error {
	values, err := parser.ValidateArguments(context, "file-base", parser.VALUE_STRING)

	if err != nil {
		return err
	}

	context.Block.Stack.Push(parser.NewValueFromString(filepath.Base(values[0].S)))

	return nil
}