Lua++
Lua++
Lua++: The (in-development) Lua 5.1 superset, made by User: Alx.
Associated file extensions | Descriptor |
---|---|
.lpp |
The non-compiled extension type recognised by the Lua++ interpreter. |
.lppc |
The compiled extension type recognised by the Lua++ interpreter. |
Lua++ - What is it?
Lua++ is a superset of Lua that changes the flow of how Lua programs are written to enhance readability and introduce new features into the language.
Lua++ - Types
The current implementation of Lua++ utilizes Python base types, being str
, dict
(as table), NoneType
and int
.
This may be changed in the future.
Lua++ - Features
1. Lua++ - Inplace operations
Lua++ introduces the ability to utilize inplace operators as shorthand alternative. Eg:
local ctr = 0 while ctr < 10 do ctr += 1 print(ctr) end
The existing inplace operators are:
Operator | Descriptor |
---|---|
+= |
Inplace add operator. |
-= |
Inplace sub operator. |
*= |
Inplace multiplication operator. |
/= |
Inplace true division operator. |
//= |
Inplace floor division operator. |
%= |
Inplace modulo operator. |
^= |
Inplace pow operator. |
&= |
Inplace bitwise AND operator. |
= | Inplace bitwise OR operator. |
>>= |
Inplace bitwise left-shift operator. |
<<= |
Inplace bitwise right-shift operator. |
#= |
Inplace length operator. Is equivalent to integer += #"example" .
|
2. Lua++ - Local initialization-as
In Lua++, you can initialize a local variable as an instance of a type, rather than it being none. Eg:
local int v for i=0, 10 do v += i end
It is syntaxically constructed as: local <T> <name> <, names>
It is NOT required for cases such as local v = 1
, etcetera. But, you must specify a type if you are just declaring a variable with no value. For nil/None, you can use local None v
.
3. Lua++ - Statement Scopes
In Lua++, statements, i.e the if-statement, while-statement and all other statements do not have scopes of their own. Eg:
if true then local int i end i += 1
4. Lua++ - Function call argument unpacking
Values can be unpacked as arguments in Lua++ via the *
symbol. The unpackable is expected to be a table/dict. Eg:
local args = {1, 2, 3, 4} local positional_argument = "I'm an argument" print(*args, positional_argument)
5. Lua++ - Varargs
Varargs are not notated by the ...
symbol. It is notated by the same symbol that unpacking is, and a name must be specified as the varargs variable, as it holds the varargs in a table. Eg:
local function f(pos1, pos2, *var) local int i local res = pos1 + pos2 for i=1, #var do print(var[i]) end return res end print(f(4, 10, 11, 12, 13))
6. Lua++ - String Slicing
String slicing in Lua++ is done by making a general index on a string, then specifying a start and stop seperated by two dots. Eg:
local string, start, stop = "hello world", 2, 7 print(string[start..stop])
7. Lua++ - String Indexing
Strings can be indexed to retrieve a character. String indexes start at 0, unlike tables, which start at 1. Eg:
local s = "example" print(s[0])
8. Lua++ - Additional Hexadecimal Literal Notation
In Lua++, hexadecimal literals can be written with an 0x / 0X
prefix, or end in h / H
. Eg:
local ints = { 80H, 4Eh, 0A3h, 0FEH }
Of course, leading 0's must be prefixed to a literal if using the latter syntax, to avoid confusion with an identifier.
9. Lua++ Classes, Class Inheritance
Classes in Lua++ are defined as a normal table, with an initializer. Class metamethods can be defined in the same table as normal methods. The &
symbol can be used before a class to perform a shallow copy of the class, and prepare it for instantiating. Eg:
class = { initialize = function(self) self.tbl = {} end; set = function(self, key, value) self.tbl[key] = value end } instance = &class instance2 = &class instance:initialize() instance2:initialize() instance:set(5, 10) instance2:set(5, 11) print(instance.tbl) print(instance2.tbl)
Class inheritance can be done by creating a class and then parenthesizing a class name as the class to inherit from. (Note that inherited classes are always local) Eg:
local basecls = { init = function(self, num) self.num = num end; add = function(self, num) self.num += num return self.num end; } extcls(basecls) = { mul = function(self, num) self.num *= num return self.num end } local instance = &extcls instance:init(5) print(instance:add(5)) print(instance:add(10)) print(instance:mul(15)) print(instance:mul(20))
10. Lua++ - Importing
Importing a module can be done with the import
or require
function. Both are aliases to the same function. Eg:
local module = import "mymodule" module.module_function()
11. Lua++ - break Keyword
The break
keyword does not exist in Lua++. Use goto
s instead.
12. Lua++ - Arithmetic Operators
All standard Lua 5.1 operators are supported, with the addition of the following operators:
Symbol | Descriptor |
---|---|
< |
Bitwise left-shift. |
>> |
Bitwise right-shift. |
// |
Floor division. |
I |
Bitwise OR. |
& |
Bitwise AND. |
~ |
Bitwise XOR. |
Lua++ - Builtins
The following table notates some Lua++ builtins and default variables as of Lua++ version Lua++ Stbl r2
.
Builtin Name | Descriptor |
---|---|
_G |
Contains the global scope table/dict. |
math |
Builtin library containing mathematical functions. |
io |
Builtin library containing IO-related functions. |
table |
Builtin library containing table-related functions. |
os |
Builtin library containing OS-related functions. |
_VERSION |
Current Lua++ version as a string. |
b |
Encodes a string into a bytes string. |
str |
String type object instantiator. |
type |
Returns type name of object as a string. |
dict |
Dict/table type object instantiator. |
int |
int type object instantiator. |
assert |
Assertion function. |
tostring |
Typecasts an object to a string. |
tonumber |
Typecasts a string to an integer. |
print |
Writes objects as strings to stdout. |
pcall |
Calls a function. If fails, returns False. Does not stop program. |
error |
Stops the program with an optional error note. |
require |
Module importer function. |
import |
Module importer function. |
input |
Retrieves input from stdin. |
LUAPP VM Notes
The Lua++ Virtual Machine operates on a CISC ISA and is a stack machine.
LUAPP VM Specs
Lua++ VM ISA
The Lua++ Instruction Format is notated as follows:
Instruction Size Type: Fixed Instruction Size: 40bi Instruction Type A: Opcode: 6bi Opmode: 2bi Operand A: 8bi Operand B: 8bi Operand C: 8bi Operand D: 8bi Instruction Type B: Opcode: 6bi Opmode: 2bi Operand A: 16bi Operand B: 16bi Instruction Type C: Opcode: 6bi Opmode: 2bi Operand A: 32bi
The following table notates all Lua++ instructions.
Opcode Name | Descriptor |
---|---|
LDVAR |
Loads a variable onto the stack. Checks locals before globals. |
GENSUB |
Performs subscription on values. If operand A is 0, the subscriptable is assumed to be the topmost stack item. The index is assumed to be a number as operand B. If operand A is 1, the subscriptable is also assumed to be the topmost stack item. Operand B points to a constant in the constants pool to be used as the index for the subscriptable. If operand A is 2, Both the subscriptable and the index is assumed to be on the stack. |
LDFLOAT |
Obselete opcode. Floats are stored in the constants pool. |
LDKST |
Loads a constant from the constants pool onto the stack. Operand A points to the index in the constants pool for the constant. |
LDULONG |
Loads operand A onto the stack, which is an unsigned 32-bit integer. |
SETVAR |
Pops an item off the stack as the value, and stores it under the name of the variable pointed to in the constants pool by operand A. Stores in the local scope if the name has been defined. Stored as a global if not. |
SETGENSUB |
Pops 3 items off the stack, being the index, subscriptable and finally the value. Stores the value under the key of the subscriptable. |
JMPABS |
Jumps to the offset pointed to by operand A. |
JMPTST |
Conditionally jumps to the offset pointed to by operand A if the topmost stack item is False. Topmost stack item is popped. |
CMPOP |
Pops two items off the stack, and compares them, the comparator being pointed to by operand A. |
AROP |
Arithmetic handler. If operand A is 0, the operands for the operation are stored as 8-bit integers in operand C and operand D. If operand A is 1, the operands for the operation are assumed to be on the stack and are popped off. Operand B points to the operation to do. |
LGOP |
Logical operator. If operand A is 0, handles unary operations. If unary and operand B is 0, pushes the unary negative of the topmost stack item. If unary and operand B is 1, pushes the logical unary NOT of the topmost stack item. If unary and operand B is 2, pushes the unary negative of the topmost stack item. If operand A is 1, the operation is no longer a unary operation. Operand A now points to the operands for the operation and decides if they are on the stack or as operand C or operand D. If operand B is 0, pushes a logical AND of the operands. If operand B is 1, pushes a logical OR of the operands. |
LDBOOL |
If operand A is 0, pushes False to the stack. If operand A is 1, pushes True to the stack. If operand A is 2, pushes nil/None to the stack. |
FORLOOP |
Pushes the next value from the assumed iterator on the top of the stack. If the iterator is exhausted, jumps to offset pointed to by operand A and pops the topmost stack item. |
SETUPFOR |
Creates an iterator on the top of the stack for an assumed for-loop. |
MKTABLE |
Creates a new table consuming x*2 amount of items from the stack pointed to by operand A, assumed to be the key and then the value. Pushes the created table once finished. |
ASMPROTO |
Assembles a proto into a closure, the proto assumed to be the topmost stack item. Operand A tells the proto assembler if it is varargs, or not. |
ALLOC |
Declares a local variable. If operand A is 0, initializes variable as nil/None. If operand A is 1, it is instantiated as an instance of a type pointed to by operand C in the constants pool. If the type is not found in either scopes, the variable is instantiated as nil/None. |
DISCARD |
Removes the topmost stack item. |
CALL |
First calling convention, consuming x amount of items from the stack pointed to by operand A. The callable, retrieved by its name in the scope, or in the global scope if it is not found in the local scope. |
CALLSAFE |
Second calling convention, also consuming stack items pointed to by operand A. The callable is assumed to be on the stack, and popped off. |
CALLSPLAT |
Third calling convention for splatting / unpacking an unpackable as arguments for a function call. The arguments are assumed to be on the stack as one table, and so is the callable. |
INSERT |
Pops two items off the stack, assumed to be a value and then a table. Inserts the value at the highest index +1 of the table. |
EXTEND |
Pops two items off the stack, assumed to be a two tables, and extends / combines them. |
SLICE |
Performs string slicing. If operand A is 0, the slices are assumed to be on the stack. If operand A is 1, the slices are assumed to be operand B and operand C. The sliceable is always assumed to be on the stack. |
GETLEN |
Pops an item off the stack and pushes back the length of it. |
RETURN |
If operand A is 0, pops an item off the stack and returns it. If operand A is 1, returns operand B as an integer. If operand A is 2, returns an item from the constants pool pointed to by operand B. |
INSTANTIATE |
Performs a shallow copy of the topmost stack item. |
MERGEMETH |
Pops two items off the stack, and merges them. Used for class inheritance. |