Update README.md

Dibyendu Majumdar 9 years ago
parent 1af7c28575
commit 06ab9868c0

@ -3,9 +3,9 @@ Ravi Programming Language
Experimental derivative of Lua. Ravi is a Sanskrit word that means the Sun.
Lua is perfect as a small embeddable dynamic language. So why a derivative? The reason is primarily to extend Lua with static typing for greater efficiency in performance. However, at the same time I would like to retain compatibility with Lua to the degree possible.
Lua is perfect as a small embeddable dynamic language. So why a derivative? The reason is primarily to extend Lua with static typing for greater performance. However, at the same time I would like to retain compatibility with standard Lua.
There are other attempts to add static typing to Lua but these efforts are mostly about adding static type checks in the language while leaving the VM unmodified. So the static typing is to aid programming - the code is eventually translated to standard Lua and executed in the unmodified Lua VM.
There are various attempts to add static typing to Lua but these efforts are mostly about adding static type checks in the language while leaving the VM unmodified. So the static typing is to aid programming - the code is eventually translated to standard Lua and executed in the unmodified Lua VM.
My motivation is somewhat different - I want to enhance the VM to support more efficient operations when types are known.
@ -45,7 +45,7 @@ function foo() : string
end
```
If no type is specified then then type will be `any` - however user cannot specify this - i.e. the lack of a type will imply this. The `any` type is essentially exactly what the Lua default is.
If no type is specified then then type will be dynamic - exactly what the Lua default is.
Tables and arrays need special syntax to denote the element / key types. The syntax might use the angle brackets similar to C++ template aruguments.
@ -71,7 +71,7 @@ local func_table : array<function> = {
end
}
```
Above the array of fuctions allows various function types - all it cares is that the element must be a functon.
Above the array of functions allows various function types - all it cares is that the element must be a functon.
When a typed function begins to execute the first step will be validate the input parameters against any explicit type specifications. Consider the function below:
@ -86,7 +86,7 @@ Implementation Strategy
-----------------------
I do not want to any new types to the Lua system as the required types already exist. However, to make the execution efficient I want to approach this by adding new type specific opcodes, and by enhancing the Lua parser/code generator to encode these opcodes when types are known. The new opcodes will execute more efficiently as they will not need to perform type checks.
My plan is to add new opcodes that cover arithmetic operations, array operations and table operations (this is lower priority).
My plan is to add new opcodes that cover arithmetic operations, array operations and table operations (latter is lower priority).
I will probably need to augment some existing types such as functions and tables to add the type signature so that at runtime when a function is called it can perform typechecks if a function signature is available.
@ -96,24 +96,16 @@ Challenges with Lua Bytecode structure
--------------------------------------
An immediate issue is that the Lua bytecode structure has a 6-bit opcode which is insufficient to hold the various opcodes that I will need. Simply extending the size of this is problematic as then it reduces the space available to the operands A B and C. Furthermore the way Lua bytecodes work means that B and C operands must be 1-bit larger than A - as the extra bit is used to flag whether the operand refers to a constant or a register. (Thanks to Dirk Laurie for pointing this out).
If I change the sizes of the components it will make the new bytecode incompatible with Lua. Although this doesn't matter so much as long as source level compatibility is retained - I would rather have a solution that allows me to maintain full compatibility at bytecode level. An obvious solution is to allow 64-bit instructions - while retaining the existing 32-bit instructions. So I will most likely need to use a technique similar to OP_LOADKX. I am worried though that this additional level of decoding will impact performance.
If I change the sizes of the components it will make the new bytecode incompatible with Lua. Although this doesn't matter so much as long as source level compatibility is retained - I would rather have a solution that allows me to maintain full compatibility at bytecode level. An obvious solution is to allow 64-bit instructions - while retaining the existing 32-bit instructions. So I investigated whether I could use a technique similar to OP_LOADKX.
New OpCodes
-----------
A new OpCode OP_RAVI acts as a way to introduce the 64-bit opcodes.
The new opcodes take up two 32-bit instructions as follows:
```
First 32-bit instruction contains:
<16 bits holding A register location> <10 bits holding type specific opcode> <6 bits holding OP_RAVI>
Unfortunately the way the Lua parser / byte-code generator works, it turns out that while expressions are being parsed, values may be held as bytecode instructions. So this makes it much more complex to implement the two instruction approach.
Second 32-bit instruction contains:
<16 bits holding B register location> <16 bits holding C register location>
```
For now therefore I am just amending the bit mapping in the 32-bit instruction to allow 9-bits for the byte-code, 7-bits for operand A, and 8-bits for operands B and C.
New OpCodes
-----------
The new instructions are specialised for types, and also for register/versus constant. So for example `OP_RAVI_ADDFIKK` means add `float` and `int` where both values are constants. And `OP_RAVI_ADDFFRR` means add `float` and `float` - both obtained from registers. The existing Lua opcodes that these are based on define which registers are used.

Loading…
Cancel
Save