Example #1
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
}
Example #2
0
func ValidateArguments(context *FunctionCallContext, name string, types ...ValueType) ([]*Value, error) {
	if context.Block.Stack.Len() >= len(types) {
		var values []*Value

		for _, t := range types {
			value := context.Block.Stack.Pop().(*Value)

			if value.Type != t && t != VALUE_ANY {
				return nil, util.NewArgumentTypeError(name, t, value.Type, context.Token.Line, context.Token.Column, context.Token.File)
			}

			values = append(values, value)
		}
		return values, nil
	}
	return nil, util.NewArgumentCountError(name, len(types), context.Block.Stack.Len(), context.Token.Line, context.Token.Column, context.Token.File)
}
Example #3
0
func (f *Function) Exec(block *Block, token *lexer.Token) error {
	switch f.Type {
	case FUNCTION_LAMBDA:
		lambda := f.L
		err := lambda.Exec()

		lambda.Stack.PopAllToOtherStack(block.Stack)

		return err
	case FUNCTION_BUILTIN:
		return f.B(&FunctionCallContext{Block: block, Token: token})
	case FUNCTION_DECLARED:
		if block.Stack.Len() < len(f.Args) {
			return util.NewArgumentCountError(f.Name, len(f.Args), block.Stack.Len(), token.Line, token.Column, token.File)
		}

		for i := len(f.Args) - 1; i >= 0; i-- {
			f.D.Scope.SetSymbolLocally(f.Args[i], NewSymbol(block.Stack.Pop().(*Value), false, false))
		}

		err := f.D.Exec()

		if f.Name[len(f.Name)-1] == '?' {
			if err != nil {
				return err
			}

			if f.D.Stack.Len() != 1 {
				return util.NewReturnCountError(f.Name, 1, f.D.Stack.Len(), token.Line, token.Column, token.File)
			}

			top := f.D.Stack.Peek(0).(*Value)

			if top.Type != VALUE_BOOL {
				return util.NewReturnTypeError(f.Name, VALUE_BOOL, top.Type, token.Line, token.Column, token.File)
			}
		}

		f.D.Stack.PopAllToOtherStack(block.Stack)

		return err
	default:
		panic("cannot execute function")
	}
}