Proof

From Esolang
Jump to navigation Jump to search

Proof stands for Processor of files. It serves a similar purpose to sed, although the language is more powerful. The language was invented by User:revcompgeek.

Regex syntax

Proof is based on the basic regular expression syntax that is used in most regex libraries. Most characters simply match themselves. The character . matches any character. Parenthesis are used for grouping. + matches 1 or more of the preceding element, * matches 0 or more, and ? matches 0 or 1. Adding a ? after any of those three makes it non-greedy instead of greedy. Character classes also work the same as in most regular expressions.

There are also several important differences. Groups are non-capturing by default, and (+name+...) is a capturing group named name. The ! operator is a negative look-ahead match. It doesn't consume any characters, but it will cause the expression to fail if the element before it can be matched.

Language syntax

Match -> Replace

There is one extensions to the group syntax. The simplest one allows modifying of the matched text in a group. The group is divided into two sections by a ->. The left part is a normal match. The right part is the replacement section. Examples will be given below.

Expression groups

Expression groups of the form {...} evaluate their contents and either try to match it or are replaced by it depending on where they appear. Alphanumeric names are replaced with the output of a previously matched group by the same name. When the expression group appears in the match side of a group, then the output it produces is used to match in its current location in the stream. For example:

(+d+[0-9]){d}

Matches any two identical digits in a row, i.e. 11, 22, 33, etc. This one:

([0-9](+num+[0-9])[0-9]->{num})

Uses the replace syntax to extract the middle number from 3 in a row. If it was given 853 as input, the output would be 5. When an expression group appears in the replacement section, the output it produces is inserted into the replacement string. The following also does the same thing:

([0-9]->)[0-9]([0-9]->)

As the name implies, expression groups also allow primitive expressions inside them. For instance, the following will do Rot13 on lowercase characters (another replacement group would be needed to handle uppercase chars):

(([a-z]->{(_-'a'+13)%26+'a'})|.)*

The underscore variable represents the match text of the nearest match group.

Note: The expression syntax may change at some point.

Function groups

Groups of the form {name(args):...} define a function that can be called later.

Note: Examples are needed

Piping

When the pipe symbol | is used inside an expression group, the output of the left side is "piped" to the right side.

Conditional groups

A conditional group looks like {?{condition}result} It can appear in either the match or replace section, and if the condition is true (non-zero and non-empty) then the result will be evaluated as if the condition wasn't there.

Tricks

Setting variables

Variables can be assigned to an expression either in a match expression with the form

(+var+->expression)

Note that this does not match anything, the only effect is creating a match named var and setting it to expression. This is also possible in a replace expression with the form

{|+''var''+->''expression''}