FOS-X
- This is still a work in progress. It may be changed in the future.
This is a standard for developing for the FOS system so you can create compilers for other languages to develop with. This is developed by Darkrifts (talk) and is currently a work in progress. Supply suggestions in the talk page.
Documentation
Documentation for each command will follow the design <value> - <operation> with hexadecimal values, from 00 - FF
All values are stored as bytes, written to a file with each byte written as a character.
Any value not documented is assumed to be a NOP and is ignored. There is no comment notation, short of writing a program to never execute a section.
00 - No operation. Useful for alignment and 1D/1E operations 01 - Push 1 onto the stack 02 - Enqueue 1 03 - Set mem to 0 04 - Increment the top of the stack 05 - Decrement the top of the stack 06 - Square the top of the stack 07 - Increment the front of the queue (pushes to the back) 08 - Decrement front of queue (pushes to the back) 09 - Square front of queue (pushes to the back) 0A - Move the top of the stack to the mem register (pops) 0B - Move the front of the queue to mem (dequeues) 0C - Push mem onto the stack 0D - Enqueue mem 0E - Increment mem 0F - Decrement mem 10 - Square mem 11 - If the top of the stack is less than the second number, skip an instruction (pops) 12 - Above but with the queue (dequeues) 13 - Jump forward N operations. N = top of stack (pops) 14 - Above but front of queue (dequeues) 15 - Pop a value and discard it. 16 - Dequeue a value and discard it. 17 - Pops a value and output it 18 - Dequeue a value and output it 19 - Pop a value and output as character. 1A - Dequeue value and output as character. 1B - If the top of the stack is greater than the second number, skip an instruction (pops) 1C - Above but with queue (dequeues) 1D - Change operation A (position) to B (byte value). A = top of stack, B = second in stack. Cannot append instructions to end of file. Must change instruction present in code. Use 00 (NOP) to help align values. 1E - Same as above, but with queue 1F - Pop a value off the stack and wait that many milliseconds 20 - Above with queue 21 - Wait for a key press and push the result as an ASCII value. Doesn't show 22 - Above with queue 23 - Exit program and return control to caller 24 - Pops N characters off the stack and combines them into a string and calls that file as a FOS-X program. N = top of stack 25 - Above with queue 26 - Pops N characters off the stack and combines them into a string and calls that file as a FOSCode program. N = top of stack 27 - Above with queue 28 - Pops N characters off the stack and combines them into a string and calls that file as a .exe program. Arguments are passed by spaces. N = top of stack 29 - Above with queue 2A - Reset stack 2B - Reset queue 2C - If A = B, skip one instruction. A = top of stack, B = second in stack 2D - Above with queue 2E - Jump to instruction N. N = top of stack 2F - Above with queue 30 - Invert direction (Allows for reverse code execution) 31 - Set mem to a random number from A to B. A = top of stack, B = second in stack 32 - Above with queue 33 - Send the front of the queue to the back with no change 34 - Duplicate the top value of the stack 35 - Above with queue (new copy pushed to back, original still in front) 36 - Swap top of stack with second in stack 37 - Add top 2 values of stack together and pushes the result (pops) 38 - Above with queue 39 - Subtract top 2 values of stack and push the result. Top - 2nd. (Pops) 3A - Above with queue 3B - Multiply top 2 values of stack & pushes result. (pops) 3C - Above with queue 3D - Divide top 2 values of stack & pushes result. Top / 2nd. (pops) 3E - Above with queue 3F - Modulo top 2 values of stack & pushes result. Top mod 2nd. (pops) 40 - Above with queue 41 - Pushes the program's length 42 - Above with queue 43 - Push byte N of the program. N = value of mem register. 1-indexed (first byte is accessed by 1, not 0) 44 - Above with queue 45 - Pop N numbers off the stack, concatenates them together into a string (based on ASCII values), and opens that file for reading. N = top of stack. 46 - Above with queue 47 - Same as 44, but for writing instead. 48 - Above with queue 49 - Write a value from the mem register as an ASCII character to the writing file currently open 4A - Read a character from the current reading file to the mem register. -1 means end of file has been reached. 4B - Close current reading file. (Auto invoked when opening a new file, but should be done anyway) 4C - Close current writing file. (Auto invoked when opening a new file, but should be done anyway) 4D - Accesses value N from the stack and pushes it to the front (leaves a copy where it was). N = value of mem 4E - Above, but with queue 4F - Moves forward 1 command, saves its value to the mem register, and does not perform that command's operation. 4F 03 OC pushes the value 3 to the stack, for example 50 - Clear the output screen More coming later
The stack, queue, and mem registers don't have to be of a specific size, though there must be 1 stack, 1 queue, and 1 single value register. In the FOS, the stack is of 2^16 32bit integers, the queue is of 2^16 32bit integers, and the mem is a 32bit integer.
Storing more values
Since you only have 1 register, 1 stack, and 1 queue, it can be difficult to do some things.
One potential solution is to store data as bytes in the program with 1D/1E, or to access the stack/queue with 4D/4E. The problem with the first is the potential to execute arbitrary commands (which may be what you want to do).
It could be used to create an array by having an unreachable NOP (00) section and rewriting values there, with the indexer having some value added to it to read certain bytes. One problem is writing outside of such a dedicated memory section and potentially corrupt the program (Runtime byte changing does not persist after restarting a program), such as turning a random operation to a 23 (Exit) operation.
Unexpected behavior
Popping a value from an empty stack/queue returns -1. This can cause some operations to fill the stack with -1 values. Pushing/enqueueing to a full structure doesn't write a value. Stack, queue, and mem is preserved across applications, so you may wish to reset them before beginning an app.
The instruction pointer moves 1 in the current direction AFTER jumps ( i.e. -1 relative reruns the jump operation. To start operation from the beginning, jump to 0, which would be 00. To go back N steps, jump -(N+1) steps). Jumping negative absolute jumps (2E/2F) jumps to 0, which starts execution at 1.
In getting bytes from the source code, it is 1-indexed, but 0-indexed when jumping and when changing bytes in the source code.
Sample programs/functions
This will use values to represent operations.
"hello" program. No comma or punctuation of any kind
68 65 6C 6C 6F 03 0E 43 19 0E 43 19 0E 43 19 0E 43 19 0E 43 19 Length: 21 bytes
Cat program
21 19 Length: 2 bytes
This checks for the press of the 1 key on the keyboard as input for 1. All else assumed 0. 01 05 05 05 05 05 4F 31 21 2C 23 01 17 34 13 Length: 15 characters
Compiling
This part is up to whatever you're compiling to FOS-X, as it is less of a true language and more like machine code readable by the FOS system.
All byte values have their character representations written onto the file, which is later read and interpreted. An official direct FOS-X IDE that turns hex values as text (like "24") into their counterparts and allows for interpretation on the spot is currently in the works.
Reductions from other languages
FOS-X is designed to allow other languages to be ported down to it.
Rulesets are defined like "<originalValue>: <replacementValues>", with special symbols "begin" meaning to prepend a series of bytes, and "end" to append a series of bytes.
Deadfish
Note: Does not wrap to 0 at 256 and -1. Creation of an interpreter for an arbitrary Deadfish program with FOS-X is possible though, including wrapping.
'i': 0E 'd': 0F 's': 10 'o': 0C 17 begin: 03 end: 03 (Recommended for memory to be reset each time. Not required)
Calcutape
'0': 01 05 '1': 01 '2': 01 04 '3': 01 04 04 '4': 01 04 06 '5': 4E 05 0C '6': 4E 06 0C '7': 4E 07 0C '8': 43 08 0C '9': 4E 09 0C '+': 37 '-': 39 '*': 3B '/': 3D ':': 4E 64 4E 0A 3B 01 31 0C (Changes mem, but not used in Calcutape) '%': 17 '@': 19 '|': 36 '_': 34 '&': 4D '^': 1F '=': 50 '?': 23 'V': 21 '#': Not gonna even try to reduce this one. Should involve 30, 1B, 2C (probably), and 13. Good luck. I'd recommend forgetting about reversing, and just use 01 05 11 13 (01 05 11 to check if negative/ is 0)