# The EVE Language

EVE is the pattern-matching engine behind the Verité chat filter. It ships with its own small language for authoring filter files. This page is the top-level guide: what EVE is, how a filter file is structured, and the directives that make up a document. The two dialects each have their own page:

- [ExpandaEVE](page:eve/expanda) is the spelled-out form you write by hand. It uses words like `HEAR`, `SUFFIX`, `NEVER` and `PLURAL`.
- [CompactaEVE](page:eve/compacta) is the terse compiled form and the matcher semantics underneath it. Every ExpandaEVE construct lowers to a CompactaEVE symbol before it runs.

## What EVE is

EVE reads a filter document and produces a set of compiled rules. Each rule is a pattern that decides whether a candidate word (or, for some rule kinds, a whole message) is a match. The engine is deliberately tolerant of evasion: a fuzzy rule matches through vowel swaps, inserted gaps, stretched letters, and similar tricks, so a single authored root catches many spellings without the author listing each one.

A filter file is plain UTF-8 text. Lines that are blank or begin with `#` are ignored, so `#` starts a whole-line comment.

## The two forms and how they relate

You author in ExpandaEVE. When a document is loaded, each statement is translated into CompactaEVE, and the CompactaEVE is compiled into the runnable matcher. The flow is:

```text
ExpandaEVE source  ->  CompactaEVE source  ->  compiled rules
     (authoring)          (terse form)          (the matcher)
```

The translation is purely a rewrite. Anything you can express in ExpandaEVE becomes real CompactaEVE, and every matching decision is made by the compiled form. A document may also be written directly in CompactaEVE: the statement verbs are the same words in lower case (`hear`, `match`, `let`, `define`, `realm`, and so on), and a statement that uses no ExpandaEVE-only construct passes through the translator almost verbatim.

!!! note "Which form should I read?"
    If you are writing or reading `.eve` files, start with [ExpandaEVE](page:eve/expanda). Read [CompactaEVE](page:eve/compacta) when you want to understand exactly how a pattern matches, or when you are reading the compiled output.

## Document structure

A document is a sequence of statements, one per logical line. The recognized statement keywords are `DEFINE`, `LET`, `REALM`, `HEAR`, `FIND`, `MATCH`, `ANYWHERE`, and `SEQUENCE`, plus the `eve:` header line. Any line that is not blank, not a comment, and does not begin with a recognized keyword raises an error rather than being skipped.

### The eve: header

An optional first line declares the version and language:

```text
eve: 1.0 English
```

The text after `eve:` up to the first space is the version. The remainder is the language name. Both are recorded on the compiled program. A header with only a version and no language is accepted.

### DEFINE: declaring flag ids

`DEFINE` registers a flag name and the id it maps to. Every flag a rule sets with `FLAG(...)` must be declared, or the document fails to load.

```text
DEFINE sh AS selfharm
DEFINE ea AS abuse
DEFINE pf AS profanity
```

The name on the left is what rules reference. The id on the right is the category the filter reports. See [Flags](page:eve/expanda#flag-conditional-rules-and-category-tagging) for how rules use them.

### LET: defining a function (named class)

`LET function(name) BE ...` declares a named class: a list of interchangeable words or fragments a rule can pull in by name. In CompactaEVE the same class is written `let &name be ...`.

```text
LET function(genderword) BE female OR girl OR woman OR male OR guy OR guys OR men OR man
```

Members are separated by `OR`. Once declared, a class is referenced elsewhere with `function(name)` in ExpandaEVE or `&name` in CompactaEVE. A class reference expands to all of its members. Classes may carry a default `(WHOLE)` or `(ROOT)` marker on the name, which is inherited by references unless the reference overrides it:

```text
LET function(frenchstuff) (WHOLE) BE franger OR frenchie OR jizzbag
```

See [Functions and classes](page:eve/expanda#function-named-classes) for the full reference, including how a class is used as a root, as a group, as an alias, and inside a skeleton.

!!! note "Numbered classes and vowels"
    A class whose name is made entirely of digits contributes its single-character members to the built-in vowel set that relaxed matching uses. This is how the vowel alphabet for leetspeak tolerance is assembled. See [Skeletons](page:eve/expanda#skeleton-exact-spellings) and the [character-class list](page:eve/expanda#inline-choice-lists).

### REALM: grouping rules

`REALM` sets the realm that every following rule belongs to, until the next `REALM`. A realm is a label used to organize and scope rules. It does not change how a rule matches.

```text
REALM racial_and_ethnic_slurs
```

Every `HEAR`, `FIND`, `MATCH`, `ANYWHERE`, and `SEQUENCE` rule that follows carries that realm name until you declare a different realm.

### The rule statements

Five statements declare rules. Each is written as the verb, a name, the keyword `AS`, and a body. The name and body may span multiple lines: the body runs until the next statement keyword at the start of a line.

| Statement | Rule kind | Matches |
|-----------|-----------|---------|
| `HEAR name AS ...` | Fuzzy | A single word, tolerant of evasion. This is the common case. |
| `FIND name AS ...` | Fuzzy | Identical to `HEAR`. An alternate spelling of the same verb. |
| `MATCH name AS ...` | Strict | The whole input, with exact classes and captures. See [Strict rules](page:eve/compacta#strict-rules-match). |
| `ANYWHERE name AS ...` | Anywhere | Fires when every listed group appears somewhere in the message. |
| `SEQUENCE name AS ...` | Sequence | An ordered run of glyphs appearing in order across the message. |

`HEAR` and `FIND` are the same rule kind, so this guide uses `HEAR` throughout. A fuzzy rule body is a full ExpandaEVE pattern: a root plus any of the constructs on the [ExpandaEVE page](page:eve/expanda).

!!! note "ANYWHERE and SEQUENCE"
    `ANYWHERE` builds a co-occurrence rule: the body is a list of groups separated by `WITH`, and the rule fires only when at least one member of every group is found somewhere in the message. Each member is compiled as its own whole-word fuzzy matcher, so members still tolerate evasion. An `ANYWHERE` rule needs at least two groups.

    `SEQUENCE` is used for ordered symbol and emoji patterns and is documented with the symbol board, which is covered separately. It fires when its glyph steps all appear in order across the message, and a `mirror` prefix also accepts the reversed order. A `SEQUENCE` rule needs at least two glyphs.

## A complete minimal file

```text
eve: 1.0 English

DEFINE pf AS profanity

REALM profanity

HEAR rule
AS
  shit(WHOLE)
  suffix(NONE OR s OR ty OR head OR heads)
  NEVER(shitake OR shiitake OR mishit)
  FLAG(pf YES)
```

This declares one flag, opens a realm, and adds one fuzzy rule. The rule matches the whole word `shit` with any of the listed endings, refuses the listed innocent words, and reports the `profanity` category. Read the [ExpandaEVE reference](page:eve/expanda) for every construct used here.
