HolyPy

= HolyPy =
This page is written up on the HolyPy version: HolyPy Stable-Closed v5.7.
Associated file extensions	Descriptor
.hpy 	The non-compiled extension type recognised by HolyPy.
.hpyc 	The compiled extension type recognised by HolyPy.
== HolyPy - What is it? ==
HolyPy is a language created by User: Alx as a homage to Terry A. Davis' HolyC. HolyPy is Python-like programming language, following standard Python3 syntax, has a number of differences, and improvements from standard Python3. HolyPy has most Python semantics, and allows nearly all standard Python builtins, as well as all Python builtin types. HolyPy serves as a portal from the physical realm to talk to The Lord in an abstracted environment.
== Differences and Features ==
=== 1. Classes ===
Class construction in HolyPy is different to Python. It is not constructed by the class keyword but invoked by the Class function. The Class function expects at least 2 arguments, being the INIT, and at least one method. The INIT should be a dictionary, holding the INIT variable names and default values. HolyPy class valuescannot be indexed, only methods can, and only from methods can you update and set class values. Classes support metamethods. Class methods are determined by the 'ClassMethod' type indicator (or decorator) at the definition of a function. Examples:
==== 1. Non-metamethod class ====
def increment_class(i) -> ClassMethod:
 a += i
 "%s\n", a
def decrement_class(i) -> ClassMethod:
 a -= i
 "%s\n", a
test = Class({"a": ...}, increment_class, decrement_class)
v = test(0)
v.increment_class(5)
v.decrement_class(1)
==== 2. Metamethod class ====
def __add__(i) -> ClassMethod:
 return a + i
test = Class({"a": ...}, __add__)
"%d", test(5) + 5
=== 2. Importation rules ===
In HolyPy, there is no import statement, as they are function calls instead. HolyPy has two ways to import and both of these import functions will load all attributes of the module into the current namespace.
==== Method 1: The AdamImport() function ====
The AdamImport function imports a HolyPy module in the current directory. It takes one argument, and the argument must be a string, being the module name. The module filename must end in either .hpy, or .hpyc. 
==== Method 2: The PythonImport() function ====
The PythonImport function calls back to the __import__ Python function, and takes 3 arguments, being the module name string, a tuple of strings as the fromlist, and an integer determining the import level. The last 2 arguments default to an empty tuple, and 0.
=== 3. If statements ===
If statements in HolyPy do not allow other clauses, there must only be one clause. Example of a valid if-statement:
if (this == that) & (that > this):
 doThis()
=== 4. Returns Outside Function Bodies ===
HolyPy allows the use of the return statement outside a function body.
=== 5. Break keyword ===
HolyPy disallows the usage of the break keyword in loops.
=== 6. Function specifics ===
In HolyPy, functions MUST be explicitly declared, so anonymous functions are not allowed. Functions can be either vararg, (method) or positional, but must be one. You may also declare that a functions' variables are to be on the global scope when defined. Default function values are not allowed. Here is an example:
def f() -> ClassMethod:
 pass # this is a class method
def f() -> Global:
 c = 1 # this is a global variable
def f():
 c = 1 # this is a local variable
def f(*args):
 pass # this is a vararg function
In function calling, the rule applies here too. You may unpack an iterable as positional arguments, unpack keyword arguments, or manually write positional arguments. Example:
f(*args) # unpacking call
f(1, 2, 3) # positional call
f(**kwargs) # keyword call
=== 7. Print ===
In HolyPy, you can invoke a Print call by writing a string literal. This will compile to a Print call. Print in HolyPy follows C-formatting styles. Newlines are also not automatically appended to Printed strings. Example:
==== 1. The Hello World program ====
"Hello world\n"
==== 2. Formatting ====
fav_number = 14
my_list = [8, 8 , [5, 9], 1, [2]]
"My favorite number is %d! Here is a list of numbers, and lists: %s\n", fav_number, my_list
=== 8. Extra builtins ===
The following table displays all extra builtins.
Builtin 	Description
GodWord() 	This function returns a word selected by God, utilizing time to make the decision.
GodPassage() 	This function returns a Psalm selected by God, utilizing time to make the decision.
HappyWords[] 	An array of thousands of words to communicate with.
BibleVerses[]	An array of Bible Verses used by the GodPassage function.
Print() 	The Print function, used to send information to standard output.
Range() 	Serves as an alias for the range function, used in compilation.
Dir() 	Displays all files in the current directory. Only present in REPL/OS mode.
Cd() 	Changes the current directory. Only present in REPL/OS mode.
Echo() 	Takes one argument as the filename, and another argument as the contents to write into a file. Only present in REPL/OS mode.
Cat() 	Displays the contents of a file. Only present in REPL/OS mode.
RmDir() 	Removes a directory if the directory is empty. Only present in REPL/OS mode.
Remove() 	Takes one argument being the filename to remove in the current directory, or path specified. Only present in REPL/OS mode.
=== 9. Logical comparators ===
HolyPy disallows the [and, or] keywords. Instead, it is permitted to use the operators [&, |] to make logical comparisons.
=== 10. For-loops ===
Traditional for-loops are allowed, and a numerical C-style for-loops can also be written relative to the following manner:
for i in start, stop, ++i: # c-style for-loop
 doThis()
for i in [1, 2, 3]: # standard for-loop
 doThat()
=== 11. Assigning ===
You can assign multiple variables to a single value in HolyPy. i.e:
a, b, c, d = 1 # a, b, c, and d are all assigned to 1
=== 12. Floor divide ===
There is no floor divide operator in HolyPy. It is best to use math's floor() function.
=== 13. Matmul operator ===
There is no need for a matmul operator, since it's only used with the numpy module as optimization, which is not a standard library. It has no use here.
=== 14. Extra operator for string operations ===
In HolyPy, you are permitted to use the subtraction operator as well as the standard Python operators on strings. The subtraction operator will subtract x-amount of characters from a string if the left operand is a string, or if the left operand is an integer, and the right operand is a string, it will get the length of the string, and subtract the left operand with the string's length.
== Implementation Details ==
=== 1. The HolyPy Virtual Machine ===
==== 1. HPYVM Bytecode Instruction Notation ====
The HolyPy bytecode instruction size is a fixed size of 4 bytes / 32 bits. Instruction notation is as follows:
Instruction Type A:
Byte 0: Operand A (8)
Byte 1: Operand B (8)
Byte 2: Opcode (8)
Byte 3: Opmode (8)
=====================
Instruction Type B:
Byte 0: Operand A (8) => (16) 
Byte 1: Operand A (8) -^
Byte 2: Opcode (8)
Byte 3: Opmode (8)
==== 2. HPYVM Bytecode Instruction Set ====
The HPYVM Instruction Set is as follows:
Opcode 	Description
ADD 	Pops two items off the stack, performs addition on them, and pushes the result.
SUB 	Pops two items off the stack, performs subtraction on them, and pushes the result.
MUL 	Pops two items off the stack, performs multiplication on them, and pushes the result.
DIV 	Pops two items off the stack, performs true division on them, and pushes the result.
MOD 	Pops two items off the stack, performs modulo on them, and pushes the result.
POW 	Pops two items off the stack, performs exponentiation on them, and pushes the result.
AND 	Obselete opcode.
OR 	Obselete opcode.
BAND 	Pops two items off the stack, performs a binary AND on them, and pushes the result.
BOR 	Pops two items off the stack, performs a binary OR on them, and pushes the result.
BXOR 	Pops two items off the stack, performs a binary XOR on them, and pushes the result.
FASTADD 	Performs addition on values in register A and B, and MOVs the result into register A.
FASTSUB 	Performs subtraction on values in register A and B, and MOVs the result into register A.
FASTMUL 	Performs multiplication on values in register A and B, and MOVs the result into register A.
FASTDIV 	Performs division on values in register A and B, and MOVs the result into register A.
FASTMOD 	Performs modulo on values in register A and B, and MOVs the result into register A.
FASTPOW 	Performs exponentiation on values in register A and B, and MOVs the result into register A.
FASTCALL 	Nearly-obselete opcode, calling a function with arguments inside registers A-C and pushing the result to the stack.
STDCALL 	The standard calling convention for HPY, which utilizes stack operations rather than register operations for calling.
JUMP 	Obselete opcode.
JUMP_TRUE 	Obselete opcode.
INVERT 	Inverts the topmost stack item.
NEGATIVE 	Makes the topmost stack item negative.
ASM_PROTO 	Pops an item off the stack, which is assumed to be the function proto, and turns it into a callable function. The operand is treated as a flag to treat the function variables as global or not.
ASM_PROTO_VARARGS	Same for the ASM_PROTO opcode, except turns the proto into a callable function with the varargs flag set to 1.
POP 	Pops an item off the stack, and moves it into a register pointed to by the instruction operand.
MOV 	Moves register contents into another register, pointed to by the instruction operands.
DISCARD 	Removes the topmost stack item, for stack flow optimization.
SUBSCR 	Pops two values off the stack, performs binary subscription, and pushes the result back to the stack.
STORE_SUBSCR 	Pops three values off the stack, performs binary subscription, and stores the third value in the subscripted first value.
LOAD 	Loads a global / local onto the stack.
STORE 	Stores a global / local into the current namespace.
PUSH 	Pushes register contents onto the stack.
GET_FORLOOP 	Turns the topmost stack item into an iterator, for a following for-loop.
FORLOOP 	Iterates through the topmost stack item, and once exhausted, jumps to offset stored in the instruction operand.
IJMP_TRUE 	Incremental conditional jump.
IJMP 	Incremental absolute jump.
DJMP_TRUE 	Decremental conditional jump.
DJMP 	Decremental absolute jump.
RETURN 	Pops the topmost stack item, and returns to caller.
LOADKST 	Loads a constant onto the stack, pointed to by the instruction operand as an index in a constants pool.
CMP 	Pops two items off the stack, performs a comparison (pointed to by operand) on them, and pushes the resulting boolean onto the stack.
GETATTR 	Pops two items off the stack, and returns the attribute under the attribute holder.
SETATTR 	Pops three items off the stack, and returns the attribute under the attribute holder.
NOT 	Performs a logical NOT on the topmost stack item.
BUILD_DICT 	Builds a dictionary consuming 2*operand counts of items frrom the stack. Pushes back dictionary.
BUILD_LIST 	Builds a list consuming operand counts of items frrom the stack. Pushes back list.
BUILD_TUPLE 	Builds a tuple consuming operand counts of items frrom the stack. Pushes back tuple.
BUILD_SET 	Builds a set consuming operand counts of items frrom the stack. Pushes back set.
BSHL 	Pops two items off the stack, performs a binary left-shift, and pushes back the result.
BSHR 	Pops two items off the stack, performs a binary right-shift, and pushes back the result.
UNPACKCALL 	Calling convention for unpacking function call.
MOVK 	Moves a constant from the constants pool into a register.
FASTBAND 	Performs a binary AND on values in register A and B, and MOVs the result into register A.
FASTBOR 	Performs a binary OR on values in register A and B, and MOVs the result into register A.
FASTBXOR 	Performs binary XOR on values in register A and B, and MOVs the result into register A.
KWSPLATCALL 	Calling convention for unpacking a dictionary of keyword arguments for a keyword function call.
==== 3. HPYVM Notes ====
The HolyPy Virtual Machine is a register-stack machine, though most register operations are obselete. This was written at version 3.8, where the only register operation was a specific fastcall. Constant arithmetic use these register operations in version 5.7, and most versions post 4.7. Functions with an argument count less than 4 also use the FASTCALL instruction.
There are 3 registers, notated as A, B and C, corresponding to HPYVM registers 0, 1 and 2.
With the version 5.7 update, arithmetic VM handlers were rewritten to allow HolyPy class metamethods.
Category:Languages
Category:Implemented
Category:Turing complete
Category:High-level