expr

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 19, 2026 License: MIT Imports: 5 Imported by: 0

README

internal/expr

Tiny parser and evaluator for the subset of FlexMatch property expressions used inside rule measurements and referenceValue strings.

Responsibility

Turn strings like

avg(flatten(players.skill))
set_intersection(players.modes)
teams[red].players.skill
avg(players.items[sword])

into an AST (Parse) and evaluate that AST against a player roster (Eval). Rule evaluators (internal/rule) compose these calls when they need to compute a number or a set from the candidate match.

Contents

  • Parse(src string) (Node, error) — recursive-descent parser. Recognised forms:
    • numeric and quoted-string literals
    • players.<attr> and players.<attr>[<key>] (the latter for string_number_map attributes)
    • teams[<name>].players.<attr>, including teams[*]
    • one-argument function calls: flatten, avg, min, max, sum, count, set_intersection
  • Eval(n Node, ctx *EvalContext) (Value, error) — evaluates a parsed node. EvalContext supplies the unsorted player pool plus a team-name → players map.
  • Value — tagged union returned by Eval. Notable kinds:
    • KindNumber, KindString
    • KindNumberList, KindStringList
    • KindStringMatrix (one string list per player, used by set_intersection)
    • KindNone — produced when an aggregate (avg, min, max) is applied to an empty list. Rule evaluators interpret this as "the rule is not yet evaluable" and skip the comparison rather than failing it, which is what lets the matchmaker grow a candidate match step by step.

Design notes

  • The grammar is intentionally narrow. The FlexMatch reference contains many more compositions than we strictly need; add them here as concrete rule examples motivate them, not speculatively.
  • The parser is hand-written and zero-dependency; benchmark before reaching for a parser generator.
  • Values share backing slices with the input where practical. Callers must not mutate slices read out of a Value.

Documentation

Overview

Package expr implements a small parser and evaluator for the subset of FlexMatch property expressions used inside rule measurements and reference values, e.g. "avg(flatten(players.skill))" or "teams[red].players.skill".

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type EvalContext

type EvalContext struct {
	Players     []core.Player
	TeamPlayers map[string][]core.Player
}

EvalContext supplies the player population an expression operates over.

Players is the full pool (used when a Scope is empty or "*"). TeamPlayers maps a team name to its members for `teams[<name>]` accesses.

type FuncCall

type FuncCall struct {
	Name string
	Arg  Node
}

FuncCall is a one-argument function such as avg / min / max / count / sum / flatten / set_intersection.

type Kind

type Kind int

Kind identifies a Value's variant.

const (
	KindNone Kind = iota
	KindNumber
	KindString
	KindNumberList
	KindStringList
	KindNumberMatrix // []NumberList - one entry per player (used by set/avg ops)
	KindStringMatrix // []StringList - one entry per player
)

type Node

type Node interface {
	// contains filtered or unexported methods
}

Node is a parsed property expression AST node.

func Parse

func Parse(src string) (Node, error)

Parse parses a FlexMatch property expression. Recognised forms:

NUMBER                            (e.g. 42, 3.14)
"STRING" / 'STRING'
players.<attr>
players.<attr>[<key>]
teams[<name>].players.<attr>
teams[*].players.<attr>
<func>(<expr>)                    where <func> in {flatten, avg, min, max,
                                  count, sum, set_intersection}

type NumberLit

type NumberLit struct{ V float64 }

NumberLit is a numeric literal.

type PlayerAccess

type PlayerAccess struct {
	Scope    string // "", team name, or "*"
	Attr     string
	MapKey   string // optional, for string_number_map
	HasIndex bool
}

PlayerAccess refers to a player attribute, optionally indexed for SDM types. Scope is the team name; "" means "all players" (no team scope), "*" means "every team".

type StringLit

type StringLit struct{ V string }

StringLit is a string literal (quoted with single or double quotes).

type Value

type Value struct {
	Kind Kind
	Num  float64
	Str  string
	NL   []float64
	SL   []string
	NM   [][]float64
	SM   [][]string
}

Value is the result of evaluating an expression node.

func Eval

func Eval(n Node, ctx *EvalContext) (Value, error)

Eval evaluates a parsed expression node against ctx.

func Number

func Number(v float64) Value

Number wraps a float64.

func NumberList

func NumberList(v []float64) Value

NumberList wraps a []float64 (no copy).

func String

func String(v string) Value

String wraps a string.

func StringList

func StringList(v []string) Value

StringList wraps a []string (no copy).

func (Value) AsNumber

func (v Value) AsNumber() (float64, bool)

AsNumber returns v as a float64 if it is numeric.

func (Value) AsString

func (v Value) AsString() (string, bool)

AsString returns v as a string if it is a string.

func (Value) FlattenNumbers

func (v Value) FlattenNumbers() ([]float64, bool)

FlattenNumbers turns a number-shaped value into a single []float64.

func (Value) FlattenStrings

func (v Value) FlattenStrings() ([]string, bool)

FlattenStrings turns a string-shaped value into a single []string.

func (Value) String

func (v Value) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL