Gecko

From Esolang
Jump to navigation Jump to search

Gecko is a language created by User:Silver where every statement is a regular expression substitution or a conditional based on a regex match, applied to a single global string. It aims to make the process of programming in regexes as pleasant as could reasonably be expected.

Syntax

A program is a series of newline-delimited transformations and named block declarations. A transformation may be a direct Substitution, a Block of transformations, or a Statement that takes transformations as arguments.

Substitutions

Substitutions can change the value of the global string. They work like so:

"<regex>" -> "<substitution>"

// current value is "hello world"
"([a-z]+) world" -> "\1 universe"
// now "hello universe"

The left hand part is a regular expression which will be applied to the current value. The right hand part is a substitution string, where \x will be replaced with the xth capture group from the left hand part. If the left hand part doesn't match then no transformation occurs. If not enough capture groups are provided the rest are replaced with empty strings.

There are a couple of special cases:

-> "to" // set the current value to "to", discarding whatever it was

// the . operator means 'everything'. on the left hand side of a transformation it's a shorthand for ".*", on the right "\0"
. -> "...\0..." // just capture the entire current value and use it whole to construct the new one
. -> . // do nothing
// you can say
"..." -> .
// but it's a nop too

"..." -> "\@" // \@ takes a line of user input and inserts it. more than one \@ in a single transform takes input once and replaces each one with the same thing

Statements

A Statement is one of three special compound forms, called if, while and map.

// if statements test a match and act conditionally
if "regex"
  "a" -> "b" // true (matches) branch
  "b" -> "c" // false branch

// while statements perform a transformation repeatedly as long as a regex matches:

// strip all a ... b pairs from around the current value
while "a.*b"
  "a(.*)b" -> "\1"

// map statements apply a transformation to each capture group before using them in the final substitution.
// this is the only time a transformation may apply to anything but the global string.

// maps hello:world to [world][hello]
map "(.*):(.*)"
  . -> "[\0]" // operation to perform on the capture groups
  "\2\1"


Blocks

A Block is a series of transformations wrapped in curly braces. This allows several transformations to be placed in a single slot in a Statement. Blocks can also be named, and those names referred to recursively.

// a single transformation that does two things
{ "a" -> "b"
  "b" -> "c" }

some_block: {
  . -> "b\0b"
  . -> "c\0c"
}

-> "a"
some_block
some_block

// string is now "cbcbabcbc"


// Blocks are expanded lazily, so they can refer to themselves recursively
recursive_block: {
  "a" -> "b"
  if "c"
    recursive_block
    "d" -> "e"
}

Computational Class

Gecko is Turing Complete, as demonstrated by the existence of this gecko program that implements brainfuck.

External Resources