Pxem

From Esolang
Jump to navigation Jump to search
Pxem
Paradigm(s) Imperative paradigm
Designed by ぬこ/nk.[1]
Appeared in 2008
Type system none
Memory system stack-based
Dimensions one-dimentional
Computational class Turing complete
Reference implementation (Original ("ぬこ"/nk's)) pxemi.7z, text2pxem.pl
(wktk's) rpxem
File extension(s) .pxe, .pxem

Pxem(pronounced "ペクシム" [pekushimu] by the creator[2]) is a programming language designed by "ぬこ" [nuko] or "nk."[1]. According to nk, "Pxem" is only named as such because "it's easy to type with a keyboard."[3]

History

Pxem used to be published in author's own website before, which does not exist anymore. According to their new blog[2], they used to compete in coding-golf held on anarchy golf using Perl, PHP, and brainfuck. One day, shinh, the host of the site, introduced GolfScript, which is designed for coding-golf. In some courses, the script enables you to code with only one-byte files. This inspired them to design a new language for coding-golf working with zero-byte files.

Specifications

Virtual machine

Pxem interpreter works with a virtual machine with a stack ― stores values as integer type ―, a buffer ― stores a string for stacking into the stack ―, a temporary memory ― stores only a value at the same time, as integer type. The stack and the temporary memory will be initialized with no values.

According to original interpreter, it is distinguished whether temporary memory has been used or not.

File name and contents

Pxem interpreter recognizes file name mainly as a source code of program. Contents of file, on the other hand, will be ignored unless file name includes either .e or .f, which is described in further sections.

How the code gets read

At first content of file name will be read from beginning to end. When it reaches to .d or end, the program terminates. When it reaches to .e, the interpreter begins to read content of file as the new process, which will be interpreted as part of Pxem code, from beginning to end. When it reaches to .d or end of file, the process ends, then original process gets continued. Vice versa when it reaches to .e inside file.

Instructions

Each command is a . (dot), and a case-insensitive ASCII character. Before the pointer reaches to the command, the character currently read will be added to the buffer as a character code. When the pointer reaches to the command, the content in the buffer gets pushed into the stack before the command gets operated.

For example, the file abcd.stuv.pxe can be separated into 5 parts: abcd, .s, tuv, .p, and xe. Before reaching to the first instruction .s, the four characters d, c, b, and a get stacked in those order, which d is in bottom while a is in top. Then, by .s instruction, the top value 'a' gets popped. Later, the three characters v, u, and t get stacked in that order. By .p, the stack will be empty, because each content gets outputted as an ASCII character. Finally, two characters get pushed in following order then the program terminates: e, and x.

Output

Command Description
.p Pops and outputs as a character, then repeats until the stack gets empty.[ins 1]
Example
hello world.pxe
Output
hello world (without newline at end)
.o Pops once and outputs as a character.[ins 1]
Example
hello world.o.pxe
Output
h
.n Pops once and outputs as an integer value.[ins 1]
Example
hello world.n.pxe
Output
104 (h values 104 in ASCII)

Input

Command Description
.i User inputs a character of a byte to stack. EOF values -1.
Example
hello.iworld.pxe
Input example
3
Output
world3hello
._ User inputs a signed integer to stack.
Example
hello._world.pxe
Input example
95 (values _ in ASCII)
Output
world_hello

Operating stack

Command Description
.c Duplicate: Pops once, then pushes the popped item twice.[ins 1]
Example
hello world.c.pxe
Output
hhello world
.s Drop: Pops once and discards the item.[ins 1]
Example
hello world.s.pxe
Output
ello world
.v Reverses content of the stack.
Example
hello world.v.pxe
Output
dlrow olleh

Operating content of file

Command Description
.f Stacks content of file as a string. This command never erases content of file.
Example
Filename
world.f.pxe
Content of file
hello,
Output
hello,world
.e Execution: Recognizes content of file as a part of Pxem code and begins new process there, making a new stack memory(items in original stack will be copied) and a temporary register (empty)[2]. After the process ends,
  • Content of the stack will be stacked to original one.
  • Content of the temporary register will be lost[ins 2].

You may run this command as many times as you'd like.

Example 1
hello.e.world.pxe (content is none)
Output
worldhellohello
Example 2
Filename
hello.e.world.pxe
Content
.v.c
Output
worldllehhello

Random value

Command Description
.r Pops an item x, then pushes a signed random integer between 0 and (x-1). For example, if x were 10, one of 0-9 would be generated.[ins 1][ins 3]
Example
0.r.n.pxe
Output
One of 0-47 (character 0 values 48 in ASCII)

Conditional looping

All of the following instructions may be nested.

Command Description
.w Loop while not zero: Pops top value and tests if it is 0 or not[ins 4]. If it's zero, skip to the matching .a instruction.[ins 5]
.x Loop while less: Pops two top values. If firstly popped value is equal or greater than secondly popped one[ins 6], skip to the matching .a instruction.[ins 5]
.y Loop while greater: Pops two top values. If firstly popped value is equal or less than secondly popped one[ins 7], skip to the matching .a instruction.[ins 5]
.z Loop while not equal: Pops two top values. If they are equal, skip to the matching .a instruction.[ins 5]
.a End of loop: Jumps back to corresponding one of four above. If there are not, the program results in an error[2].
Note
Five commands above can be nested.
Example 1
Hello, world.w.pxe
Hello, world.a.pxe
Both two above results in an error during running. Former one is because of reaching to no .a's while other is because of reaching .a before four others.
Example 2
abcdeffggghijj.z.a.pxe
Output
hijj
Example 3
abcdeffggghijj.x.a.pxe
Output
hijj
Example 4
abcdeffggghijj.y.a.pxe
Output
cdeffggghijj
Example 5
a.w.a.pxe
This program will never terminate, for causing an infinite loop.

Temporary memory

Command Description
.t Pops top value. The value gets stored in temporary register.[ins 8][ins 9]
.m Pushes content in temporary register.[ins 10] If the register is empty, nothing happens.

Termination

Command Description
.d Return[ins 11]. This instruction works differently on either file name or content.
In file name
The program gets terminated.
In content of file
The subprocess gets terminated, then content of stack gets stacked to parent one, and the temporary register gets destroyed.

Arithmetic operation

Command Description
.+ Addition operation: Pops two top values, then pushes sum of them.[ins 12]
.- Subtraction operation: Pops two top values, then substrates smaller one from larger one. Pushes the result.[ins 12]
.! Multiplication operation: Pops two top values, then pushes their product.[ins 12]
.$ Division operation: Pops two top values, then divides larger one by smaller one. Pushes the quotient.[ins 12][ins 13]
.% Modulo operation: Pops two top values, then divides larger one by smaller one. Pushes the remainder.[ins 12][ins 13]
  1. 1.0 1.1 1.2 1.3 1.4 1.5 If stack is empty, nothing happens
  2. This is not officially documented, but pxem.h of pxemi.7z satisfies this specification.
  3. It was not originally specified what would happen if top value were either 0 or -1 on original description page, but according to pxem.h of pxemi.7z, the original interpreter, it is implemented in following function:
    inline void Pxem::getRand(){
    	int aaa = rand() % pStack.top();
    	pStack.pop();
    	pStack.push(aaa);
    }
    

    Therefore the program would result in an error by dividing by 0.

  4. It won't test if stack is empty.
  5. 5.0 5.1 5.2 5.3 It was not specified on original description page, but according to revival blog page, the author clarified what would happen the number of values in the stack were not enough: nothing would happen to content of the stack. However, it was not clarified whether the program loops or not. But according to the original interpreter pxem.h of pxemi.7z, the program will loop.
  6. Original description said: if first-popped item is NOT smaller than the other.
  7. Original description said: if first-popped item is NOT greater than the other.
  8. Old content in the register will be lost.
  9. It is not clarified what would happen if the stack were empty.
  10. The content of the register will not be lost.
  11. Original description just says to stop execution.
  12. 12.0 12.1 12.2 12.3 12.4 If the stack has less than two values, nothing happens.
  13. 13.0 13.1 The program would result in an error if top value were 0, according to pxem.h of pxemi.7z, the original interpreter.

Examples

Hello, world!

To output Hello, world!, the filename should be:

Hello, world!.pxe

while the contents of file is arbitrary.

Other example

This alternative example is efficient if you prefer not to use symbols other than period and hyphen. This program outputs a newline, too.

Hello.pAa.-Am.-.pworld.pak.-Ab.-.pxe

Echo (or cat program in exact)

Filename
1.w.o.i.c12.-.+.a.s.pxe
File Contents
(none)

Ultimate problem

Filename
42.pxe
File Contents
(none)

delete last line

Filename
1.w.i.c12.-.+.a1.zak.-.a.v.pxe
File Contents
(none)

FizzBuzz

Filename
ak.-akbuzz.-ak4.-akfizz.-ak2.-1.p05.-.tab.z01.-.c.m.+.c.t05.-.%.w.s01.-.m03.-.%.W.s.m.nak.-.p00.-.c.c.c.a.wak.-fizz.p00.-.c.c.a.a.w01.-.m03.-.%.w.sak.-buzz.p00.-.c.c.a.wak.-fizzbuzz.p00.-.c.a.a.md2.-02.-.!.a.d.pxe
File Contents
(none)

Prints 10 one-digit random numbers

Filename
ak.-.z.tak.-.c.r.n.p.m01.-.-.c00.-.a.pxe

Implementations

By original designer

pxemi.exe (original)

Original author used to publish its interpreter named "pxemi.exe", which was developed in C++ and would work on Windows only.

Lost code generator

On original page there used to be a code generator, which seems to be lost.

pxemi.7z

After ten years, its original interpreter got published again on original author's blog[2]. In this page the interpreter is distributed as pxemi.7z, zipping two files pxem.h and pxemInterpreter.cpp.

Bug

As on January 1st, 2020, the header file pxem.h has a following bug:

  • inline void Pxem::copy() — a method for command .c — is missing the procedure for an empty stack; the specification supposes the command works like an NOP in the case, but the actual implementation is missing the part.

text2pxem.pl

There's also a simple supportive kit text2pxem.pl. It compiles a text file into Pxem code file and emulates with text file. The usage is:

  1. Put pxemi.exe[4] and text2pxem.pl in the same directory.
  2. Make a text file with any name (name does not matter).
  3. Write filename first. You can separate into lines. You put any horizontal tab characters at the beginning of a line, they are ignored. You put a tab in the end, you can write a comment followed by the character.
  4. If you'd like to write content of the file, you have to put one line of __EOF__ to imply the end of filename. Then following contents are recognized as contents.
  5. Run text2pxem.pl with following arguments:
    • 1st argument must be filename for text file you made. With no 2nd argument, it compiles into Pxem file.
    • You specify 2nd argument -e, it does not only compile, but also execute with the file.
Usage example
Your file
n4-).-	mk ':-)'
ak.-	mk '\n'
n4-.-	mk ':-'
ak.-	mk '\n'
n4.-.p	mk ':'
01.-.t	mk 0 and toreg
.z	loop A
	n4-).-	mk ':-)'
	ak.-	mk '\n'
	.p	print
	.m	fromreg
	.e	exec file
	.v.s.v	delete flag
	.p	print
	.m	fromreg
	12.-.+	mk 1 and add
	.t	toreg
	 .m	
.a	end loop A
.d.pxe
__EOF__
.t	toreg
.z	loop B
	01)).-.m.-.t
	00.-.m
.a	end loop B

This file[2], for example, generates a file named n4-).-ak.-n4-.-ak.-n4.-.p01.-.t.zn4-).-ak.-.p.m.e.v.s.v.p.m12.-.+.t .m.a.d.pxe, with content .t.z01)).-.m.-.t00.-.m.a.

Using the tool
txt2pxem.pl filename
Just a compilation.
txt2pxem.pl filename -e
Not only compilation, but also execution.
You must put an -e exactly on the second argument.

By the way you have to replace every \r\n into \n if you're running text2pxem.pl on non-Windows environments.

Others

As on September 2018, there are three repositories for interpreter-development, which are on #External Links.

Turing-completeness

"nk." originally predicted Pxem is not Turing-complete because Pxem has no built-in command for "swap" operation of the stack[2].

In May 2020, several proofs of Turing-completeness of Pxem gets published on a personal blog [5].

External Links

References

  1. 1.0 1.1 The original document page is said to be written by "ぬこ" while this new blog is by "nk." This is because (s)he changed his/her name, which is explained on latter page. Therefore "ぬこ" is the original name and "nk." is the new one.
  2. 2.0 2.1 2.2 2.3 2.4 2.5 2.6 Pxemの思い出 — ビビビッ (Vivid Bit) (Japanese).
  3. No reliable sources about this origin known, as of 2019/08/04.
  4. It implies that interpreter's name must be "pxemi.exe". It seems that you have to change pxemi.exe of the file into appropriate name.
  5. Minimalization of Pxem — Acid Forums.