Unparseable

From Esolang
Jump to navigation Jump to search

Unparseable is a language designed to be hard (maybe impossible?) to parse. It is context-sensitive, it REQUIRES you to mix the parser and the interpreter, and it allows you to redefine commands while the program is running. It was created by User:TehZ. I am pretty sure it is multiprogramming.

Commands

 + Increment current memory cell
 - Decrement current memory cell
 > Select next memory cell
 < Select previous memory cell
 . Output current memory cell as an ASCII character
 , Input current memory cell as an ASCII character
 ( Start of loop type A, must be matched with a )
 ) End of loop type A, must be matched with a (
 [ Start of loop type B, must be matched with a ]
 ] End of loop type B, must be matched with a [
 ? Run next command if current memory cell is 0
 # Skip to the "matching" )
 @ Skip to the "matching" (
 ! Skip to the "matching" ]
 " Skip to the "matching" [
 = Overrides what the next character does, so it has the same meaning as the character after that
 / Swaps the meaning of commands with opposite meanings (like + and -, # and @, ( and ), [ and ] and so on)
 & Put all code after this character, until a matching |, at the start of the program (remember the commands ‘=’ and ‘/’, and this command behaves like it's moved too)
 | Must match with an &
 ' Turns all instructions between this and the next ' into a single instruction. '''' is how you describe ' to =, while '' is how you describe no-op.

Unmatched parens

The language must only try to match parentheses when it can without assuming anything. However, if there are any mismatched parentheses, the language has to report an error and halt. When the program is finished, however, it is expected to have reported things like these:

 [=A(!A]

I am not completely sure that not validating that program, while validating other example (ie. "(/(") is possible. If it isn't please tell me so I can loosen the restrictions a bit.

The commands #@!"

When you execute:

 (#(.).)

None of the .'s are executed, because the # jumps directly to the last ). When you execute:

 ((#.).)

The second . is executed, because the # jumped to the first ). The same counts for all of the other kinds of loops.

Examples

Lets start with some interestingly valid programs:

 ([)]
 )&(|
 (/(
 (=()(
 (=A)A
 &)&(||
 /&|

Now, as a contrast, here are some invalid programs that might be surprising:

 (/)
 (&)|
 )(=A)=B(=)B=(A
 |

Here is an example of running the = command multiple times with a different result:

 (=A>A=>+?#@)

What happens here? Well, the program enters the loop, it redefines A to mean "next command", then it executes A aka "next command". After that, it redefines > to mean "increment". Then it returns to the start of the loop, where it redefines A to mean "increment". Then it increments a cell and exits the loop.

Parseability

I don't know whether or not it is possible to parse this language into something meaningful, so I can't tell if it is possible to execute it. It might be possible to execute it while parsing it, but I can't say for sure.

Paradoxes

If you combine the = command and the &| block, it's possible to make a paradox:

 =A&A|

When directly parsed, it will be seen like this:

 &|

But the &| will be moved before the =A&:

 A|=A&

Now, since it's not an &| anymore, it'll be moved back:

 =A&A|

In case of a paradox, the characters in the program will have to be reversed, and if that makes a paradox too, the behavior is undefined. The interpreter is, however, encouraged to destroy your computer in case of a double paradox. If we use the example above, It should be interpreted like this:

 |A&A=

Now, this obviously doesn't work, but as you can see, it does remove the paradox.

Here are some programs that might look like paradoxes, but really aren't:

 =A&A||A&A=

This looks like a double paradox, but there's a syntax error.

 =A&&=A&=Q|QA|

This looks like a paradox too, but I've inserted a little code, so it's no longer a paradox.

Loops

A loop doesn't do anything special, unless there is a jump instruction inside of it (#@ for (), !" for []). Also, loops can be entered even though they aren't matched, but they need to be matched when you exit. So, here are some no-ops:

 []
 ()
 [!]

The following add one to the currently selected cell:

 [+]
 (+[!])

And these don't terminate and don't change anything:

 (@+)
 ["]
 ([@)+]

These count the current cell up forever:

 [+"]
 (+@)

These are like BF loops:

 (blabla?#@)
 [blabla?!"]

Clarifying =

The = command might seem a little strange, so this will explain it. Imagine you have a table of all legal symbols in this programming language, where the commands point to whatever the commands do, while the other symbols point to no-op.

 A nop
 B nop
 C nop
 + inc
 - dec
 > nex
 < pre
 ( lsa
 ) lea
 [ lsb
 ] leb
 @ lra
 " lrb
 # lna
 ! lnb

(reduced)

In this case, =A> will replace the line

 A nop

with

 A nex

Which means A gets the next memory cell. Now, what happens if we write =>(? The line

 > nex

will be replaced by

 > lsa

but the line

 A nex

will remain unchanged. If we write =BA, the line

 B nop

will turn into

 B nex

I hope this clarifies something.

Comments

While the language doesn't have comments, you can easely add them, as long as you don't use any of &|[]():

 [!insert comment here]

Proposed formula to syntax-check

The proposed formula to syntax-check is this: When you enter a loop, do nothing. When you reach an instruction, write that instruction in the program map. When you use the = command, update the program map. Start out by copying the program to the program map. When you exit a loop, match all of the contents of the loop IN THE RECORDED PROGRAM MAP. When the program is finished, check the program map again. Examples:

 (/( -- Program
 | (the ip is at the |)
 (/( -- Program map

---

 )/)
  |
 (/(

---

 )/)
   |
 (/)

Check that everything in (/) is matched: ok. Example 2:

 )(=A)=B(=)B=(A
 |
 )(=A)=B(=)B=(A

ERR: Didn't exit the loop successfully. Example 3:

 [=A(!A]
 |
 [=A(!A]

---

 [=A(!(]
  |||
 [=A(!(]

---

 [=A(!(]
     | |
 [=A(!(]

ERR: Didn't exit program successfully.

NOTE: This algorithm is not validated on all example programs.

's special cases

' is an interesting instruction. It can be used to compress code a lot. For example, turning {} into brainfuck loops:

 ={(=}'?#@)'

or, made readable: Make { mean (. Make } mean '?#@)'. The {} will not support code like {(}) (actually, it will, the code will just work differently), but it does support things like {[}]. Well, lets look at some special cases:

 =''+

will put a + in-between all of the next instructions. That can only be reversed if you have a noop-instruction, and we will assume A is a noop instruction for this example:

 =''A

The ' instruction probably allows for some pretty advanced stuff. Other special cases:

 ='A LOOP!'(

will turn

 A LOOP!

into

 (

which might be useful.

Computation class

Brainfuck is easily translated to Unparseable, so it is turing-complete. Using a few commands in the start of the program, you can actually modify Unparseable to be a superset of Brainfuck.