Irregular Expression

From Esolang
Jump to navigation Jump to search

Irregular Expression is an Esolang where there is input, but just one type of functional output: booleans. How the Esolang works is that you can get input from user, and evaluate a bunch of checks in the input, and returns true or false depending on if the conditions are satisfied. But there are also subexpressions, where stored values can be evaluated to output if they work. Full syntax will be denoted below, but be warned that it is not just syntax you'd normally see (infact its total gibberish if you try to do anything with it), Note that text can be obtained by adding ?*\ at the beginning of code, in which the 8 bit blocks of binary outputted are checked for ascii characters, and puts outputs corresponding text. This is also very painful and based on Regular expressions.

Syntax?

Syntax acts a little bit like just regular expressions (variant doesn't matter), but get ready as the syntax here has almost no correlation with that. The program, however, always starts by getting input and evaluating the rest of the expression, and outputting everything at the end, not outputting any text but rather a bunch of binary, only determined by if the expressions satisfy the regular expression only. (Even then explaining this is painful, see examples)

Non-check commands

The following commands are not used to check the initial input. Meaning they only affect tape and others, but aren't checked as a regex expression.

Non-checked non-modifier commands commands
Command Function
, Separator between expressions, doesn't affect the output in any way
i> Get input from user and store into the tape
${}> Store a string into the tape, string stored is in the {}.
#{}> Store a number into the tape, number stored is in the {}. (the number however is returned as a base 32 value if accessed as string)
?[ Marks the start of a sub-regex. You can nest this so long as you dont run out of RAM. Note that the inputted value is the selected value on tape, or the user's input if none found
]! Marks the end of a sub-regex, outputting the result when getting here.
~c Print the current state of the input. Meaning it will act like the end is reached, but outputted in the middle and let program continue. Can go anywhere so long as not skipped
~o Do not output the final result. Can go anywhere so long as not skipped
l< Go left on tape
r< Go right on tape

Checking input commands

The boring way

To check for a thing. Whether that'd be for a password locking system (???) or something else, you can check for a character like this:

?:{Character your checking for}

So:

?:{H},?:{I},?:{!}

Checks if you inputted "HI!"

The less boring way

You can also check for characters like this:

?:{~t}

Which checks for the character who's ASCII value is the selected number on tape, or

?:{~s}

Which checks for the character on the tape, or an entire string, so:

${HI!}>,?:{~s}

and

#{72}>,?:{~t},#{73}>,?:{~t},#{33}>,?:{~t}

Does the same thing as:

?:{H},?:{I},?:{!}

(If for any reason you did want a password checker, use the second option, its unreadable enough for most people right????)

The really weird way

There is STILL one last command that simply just checks for a random character given a category, listed as follows:

?:{~a}     Checks for a random ASCII character with a ASCII code above 31 (32+)
?:{~L}     Checks for capital letters
?:{~N}     Checks for numbers
?:{~l}     Checks for lowercase letters
?:{~P1}    Checks for ASCII characters 33-46
?:{~P2}    Checks for ASCII characters 58-64
?:{~S1}    Checks for ASCII characters 91-96
?:{~S2}    Checks for ASCII characters 123-126

This is basically a random password gen!

Special cases

The following will list special matching cases, listed below:

To match any character, use ?:{}

To match a set of characters you picked, do:

?:{[Setofchar]}

Which matches anything in the set, no separation needed, or:

?:{![Setofchar]}

To match anything NOT in the set

If a character results in a command, use a backslash (\) to escape it.

You can also use ranges of ASCII values, like this:

?:{#33-#46}

Which would match ASCII characters 33-46.

To have two alternative matches, do something like this:

?:{ThisOne|OtherGuy}

You can add many |s, to make many alternatives.

Flexible amounts

To match a thing a flexible amount of times, the following can be done:

To match Any amount of times, zero included, do this:

?+:{Matches}

To match atleast once:

??:{Matches}

To match OR not match:

?!:{Matches}

So:

${Colo}>,?:{~s},?!:{u},?:{r}

Matches both Color and Colour

Comparisons And arithmetic

Some commands can be used to modify the tape in some other way, they are listed below and are also not checked:

sl< is marked as the currently selected value on tape.

a:+{9,10} does addition on the two values

the + can be replaced with any of the following operators: - * / %


c:={yes,yes} can be used for comparison and only ever returns true/false, this one checks for equivalence. You can also replace it with:

!= (Not equal)

>

<

>=

<=

? (OR)

& (AND)

^ (XOR)

Control Flow

To control the flow of the command makes use of the while, for, if, and switch-case statements. Syntax is listed below, separate for each kind. But the ones shared for all of them are as follows:

n; Negates the conditional of the next statement, doing the command if false. c; Starts the area conditionals control. c*; Ends the area conditionals control.

While

To use a while loop, the following syntax is used:

w={c:={yes,yes}}

The conditional that needs to be met is placed inside the {}s. So if yes equals yes (which it does) then the while statement runs. The nested conditionals do not need separation as it is purely nesting. So:

n;,w={c:={1,0}},c;,?:{![HIhi]},c*;

Sees if you did not type any H's or I's in your string infinitely.

For

For statements are used like this:

f={111}

This means it will do the next part 111 times,

f={111:3}

Is the same but starting at 3

f={111:+5}

Increments the counter by 5 not one.

f={111:3:+5}

Starts at 3, ends at 111, increments by 5, And

f={inf=}

Is just a forever statement.

If

If statements are used like this:

i={c:={yes,yes}}

This is the same as While, but does only one not 100 times. Else statements, which do require the c* to first close off the original part:

!e:

And for an Else-if:

!e/i={c:={yes,yes}}

Switch case

To denote the start of a Switch-case:

s>{name:[parameter,anotherone]}

A case is marked as shown below, closing required if there’s another case before.

c;{identifier};

In order to call a switch-case:

s=name:{case::parameter:anotherone}

If a parameter needs usage in a switch case, use:

p=parameter:>

Sub-regex

A subregex is marked like this:

?[Code]!

A subregex normally does output its result, taking in the selected value on tape as input, the outputting can be disabled via adding ~!o at the beginning it, and changing the input is done by adding {:+Offset} to shift the tape first or use a set value by {::Value}. It uses the same syntax as all other parts of this Esolang. So that:

i>,~o,?[#{72}>,?:{~t},#{73}>,?:{~t},#{33}>,?:{~t}]!

Is the same thing as:

#{72}>,?:{~t},#{73}>,?:{~t},#{33}>,?:{~t}

But with one more input step.

More

#t:s>a(d=r) Takes a string and converts to 8 bit ASCII values going to the right of string... Wait... Text is finally easy.

#t:s>a(d=r,m1) Does the same, but moves the pointer to the last occupied cell with the ascii values (even if that bit is a zero)

#t:sk>a(d=r) Takes a string and converts to 8 bit ASCII values going to the right of string and keeps the original value.

#t:s>a(d=l) Takes a string and converts to 8 bit ASCII values going to the left of string

a;s,i[anchor] Sets an anchor point with the ID of anchor.

a;j>>[anchor] Jump to anchor point with the ID of anchor.

e:! Marks the start of a comment

e:^ Ends a comment (Alternatively using commands that dont exist work too)

?:{^e} Matches nothing. (but does match the null string.)

Examples

FINALLY its examples. that took forever! Unfortunately it doesn't get much better. You will see below:

Hello World!

(The program is so fat it goes off the screen)

?*\,~o,${Hello World!}>,l<,#{2}>,r<,#t:s>a(d=r,m1),#{2}>,l<,w={c:!={sl<,2}}
,c;,l<,c*;,r<,w={c:!={sl<,2}},c;,r<,?[?:{1}]!,c*;

Cat

?*\,~o,i>,l<,#{2}>,r<,#t:s>a(d=r,m1),#{2}>,l<,w={c:!={sl<,2}}
,c;,l<,c*;,r<,w={c:!={sl<,2}},c;,r<,?[?:{1}]!,c*;

Only Usable Quine

Nothing is being matched, therefore the output is always "True" so this works. This is also probably the second shortest Quine which is only four characters in comparison to HQ9+'s single character command Q. it cheats tho

True

Helpful Snippets

To make life easier ;)

Text output

l<,#{2}>,r<,#t:s>a(d=r,m1),#{2}>,l<,w={c:!={sl<,2}}
,c;,l<,c*;,r<,w={c:!={sl<,2}},c;,r<,?[?:{1}]!,c*;

This results in a weird tape like this:

Tape
2 ... The ASCII characters in order, left to right hopefully! ... 2

the 2's are used as endpoints, like this:

  • The program starts at the rightmost 2.
  • Travels to the leftmost
  • And starts outputting

Other things

Interpreters

...Who the heck would want to use this????????????


Derivatives

Luckily none exist. Yay!