Pxem

Pxem(pronounced "ペクシム" [pekushimu] by the creator) is a programming language designed by "ぬこ" [nuko] or "nk.". According to nk, "Pxem" is only named as such because "it's easy to type with a keyboard."No reliable sources about this origin known, as of 2019/08/04.
== History ==
Pxem used to be published in author's own website before, which does not exist anymore. According to their new blogPxemの思い出 — ビビビッ (Vivid Bit) (Japanese)., 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.If stack is empty, nothing happens
;Example
:hello world.pxe
:;Output
::hello world (without newline at end)
.o 	Pops once and outputs as a character.
;Example
:hello world.o.pxe
:;Output
::h
.n 	Pops once and outputs as an integer value.
;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.
;Example
:hello world.c.pxe
:;Output
::hhello world
.s 	Drop: Pops once and discards the item.
;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). After the process ends, 
*Content of the stack will be stacked to original one.
*Content of the temporary register will be lostThis is not officially documented, but pxem.h of pxemi.7z satisfies this specification..
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.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.
;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 notIt won't test if stack is empty.. If it's zero, skip to the matching .a instruction.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.
.x 	Loop while less: Pops two top values. If firstly popped value is equal or greater than secondly popped oneOriginal description said: if first-popped item is NOT smaller than the other., skip to the matching .a instruction.
.y 	Loop while greater: Pops two top values. If firstly popped value is equal or less than secondly popped oneOriginal description said: if first-popped item is NOT greater than the other., skip to the matching .a instruction.
.z 	Loop while not equal: Pops two top values. If they are equal, skip to the matching .a instruction.
.a 	End of loop: Jumps back to corresponding one of four above. If there are not, the program results in an error.
;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.Old content in the register will be lost.It is not clarified what would happen if the stack were empty.
.m 	Pushes content in temporary register.The content of the register will not be lost. If the register is empty, nothing happens.
==== Termination ====
Command	Description
.d 	ReturnOriginal description just says to stop execution.. 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.If the stack has less than two values, nothing happens.
.- 	Subtraction operation: Pops two top values, then substrates smaller one from larger one. Pushes the result.
.! 	Multiplication operation: Pops two top values, then pushes their product.
.$ 	Division operation: Pops two top values, then divides larger one by smaller one. Pushes the quotient.The program would result in an error if top value were 0, according to pxem.h of pxemi.7z, the original interpreter.
.% 	Modulo operation: Pops two top values, then divides larger one by smaller one. Pushes the remainder.
== 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. 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:
#Put pxemi.exeIt implies that interpreter's name must be "pxemi.exe". It seems that you have to change pxemi.exe of the file into appropriate name. and text2pxem.pl in the same directory.
#Make a text file with any name (name does not matter).
#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.
#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.
#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, 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.
In May 2020, several proofs of Turing-completeness of Pxem gets published on a personal blog Minimalization of Pxem — Acid Forums..
== External Links ==
*
*The blog by original author (Japanese) ― Original interpreter source (and supportive tools) available! (Stated to be licensed under WTFPL)
*Pxemでネギを振ってみた - NicoNico Video ― The only video to try running Pxem.(Japanese)
*wktk/rpxem ― The interpreter developed in Ruby. Some commands (.d and some) doesn't work properly.
**wktk's blog ― Two programs are shown. One is to output whether the number is prime number or not and the other one is to calculate the factorial.
*rhwckl/pxem ― The compiler-time interpreter developed in C++. Two libraries:Boost and Sprout are necessary in order to compiler. The syntax is modified.
*GH-TpaeFawzen/Pxem2Cplusplus11 — Implemented in Bourne shell. Translates into C++11 program.
== References ==
Category:Languages
Category:Stack-based
Category:Implemented
Category:2008
Category:Probabilistic
Category:Nondeterministic
Category:Turing complete