<commit_before>package core

import (
	"github.com/karlseguin/gerb/r"
	"reflect"
)

type Value interface {
	Resolve(context *Context) interface{}
}

type StaticValue struct {
	value interface{}
}

func (v *StaticValue) Resolve(context *Context) interface{} {
	return v.value
}

type DynamicFieldType int

const (
	FieldType DynamicFieldType = iota
	MethodType
	IndexedType
)

type DynamicValue struct {
	names []string
	types []DynamicFieldType
	args [][]Value
}

func (v *DynamicValue) Resolve(context *Context) interface{} {
	var d interface{} = context.Data
	for i, l := 0, len(v.names); i < l; i++ {

		name := v.names[i]
		t := v.types[i]
		if t == FieldType || t == IndexedType {
			if d = r.ResolveField(d, name); d == nil {
				return nil
			}
			if t == IndexedType {
				if d = unindex(d, v.args[i], context); d == nil {
					return nil
				}
			}
		}
	}
	return r.ResolveFinal(d)
}


func unindex(container interface{}, params []Value, context *Context) interface{} {
	valueLength := len(params)
	if valueLength == 0 {
		return nil
	}

	value := reflect.ValueOf(container)
	kind := value.Kind()
	if kind == reflect.Array || kind == reflect.Slice || kind == reflect.String {
		first, ok := r.ToInt(params[0].Resolve(context))
		if ok == false {
			return nil
		}
		second := 0
		if valueLength == 2 {
			second, ok = r.ToInt(params[1].Resolve(context))
			if ok == false {
				return nil
			}
		} else {
			second = value.Len()
		}
		return value.Slice(first, second).Interface()
	} else if kind == reflect.Map {
		indexValue := reflect.ValueOf(params[0].Resolve(context))
		return value.MapIndex(indexValue).Interface()
	}
	return nil
}<commit_msg>allow out of limit array bounds and just put it to 0:len<commit_after>package core

import (
	"github.com/karlseguin/gerb/r"
	"reflect"
)

type Value interface {
	Resolve(context *Context) interface{}
}

type StaticValue struct {
	value interface{}
}

func (v *StaticValue) Resolve(context *Context) interface{} {
	return v.value
}

type DynamicFieldType int

const (
	FieldType DynamicFieldType = iota
	MethodType
	IndexedType
)

type DynamicValue struct {
	names []string
	types []DynamicFieldType
	args [][]Value
}

func (v *DynamicValue) Resolve(context *Context) interface{} {
	var d interface{} = context.Data
	for i, l := 0, len(v.names); i < l; i++ {

		name := v.names[i]
		t := v.types[i]
		if t == FieldType || t == IndexedType {
			if d = r.ResolveField(d, name); d == nil {
				return nil
			}
			if t == IndexedType {
				if d = unindex(d, v.args[i], context); d == nil {
					return nil
				}
			}
		}
	}
	return r.ResolveFinal(d)
}


func unindex(container interface{}, params []Value, context *Context) interface{} {
	valueLength := len(params)
	if valueLength == 0 {
		return nil
	}

	value := reflect.ValueOf(container)
	kind := value.Kind()
	if kind == reflect.Array || kind == reflect.Slice || kind == reflect.String {
		length := value.Len()
		first, ok := r.ToInt(params[0].Resolve(context))
		if ok == false {
			return nil
		}
		if first < 0 {
			first = 0
		}
		second := length
		if valueLength == 2 {
			second, ok = r.ToInt(params[1].Resolve(context))
			if ok == false {
				return nil
			}
			if second > length {
				second = length
			}
		}
		return value.Slice(first, second).Interface()
	} else if kind == reflect.Map {
		indexValue := reflect.ValueOf(params[0].Resolve(context))
		return value.MapIndex(indexValue).Interface()
	}
	return nil
}
{'fraction_non_alphanumeric': 0.14136125654450263, 'fraction_numerical': 0.004653868528214078, 'mean_word_length': 3.425997425997426, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5672808', 'n_tokens_mistral': 1308, 'n_tokens_neox': 1187, 'n_words': 328}