.
This commit is contained in:
35
lua-temp/doc/BYTECODE
Normal file
35
lua-temp/doc/BYTECODE
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
Bytecode format
|
||||||
|
---------------
|
||||||
|
|
||||||
|
The bytecode file is composed of the following sections:
|
||||||
|
|
||||||
|
* HEADER: 16-byte header
|
||||||
|
[0:3]: Magic
|
||||||
|
[4]: VM format
|
||||||
|
[rest]: Reserved for future use
|
||||||
|
* TABLE_OF_CONTENTS: list of 8 records pointing to each one of the sections
|
||||||
|
Each record (6 bytes):
|
||||||
|
- Pointer to section: 4 bytes
|
||||||
|
- Number of records in section: 2 bytes
|
||||||
|
* [0x0] Constants indexes: pointers to each of the constant locations
|
||||||
|
* Table of 4-byte constant indexes with pointer to constant
|
||||||
|
(counter start at beginning of raw constants)
|
||||||
|
* [0x1] Functions indexes: Pointer to functions within the code
|
||||||
|
[0:3]: function pointer (counter start at the beginning of executable code)
|
||||||
|
[4:5]: number of parameters
|
||||||
|
[6:7]: number of local variables
|
||||||
|
[8:b]: function size
|
||||||
|
* [0x2] Constants raw data
|
||||||
|
* [0x3] Code: executable code
|
||||||
|
* [0x4] Debugging info
|
||||||
|
???
|
||||||
|
|
||||||
|
The max file size is 2 Gb.
|
||||||
|
|
||||||
|
## Values can be encoded in the following ways:
|
||||||
|
* The type is defined by the operator.
|
||||||
|
* Encoding varies according to the type:
|
||||||
|
int: use protobuf format
|
||||||
|
float: 4-bit floating point
|
||||||
|
string: int-defined length, followed by the string proper - no null terminator
|
||||||
|
* Constant indexes and function ids are encoded as ints
|
||||||
93
lua-temp/doc/OPCODES
Normal file
93
lua-temp/doc/OPCODES
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
Operations
|
||||||
|
----------
|
||||||
|
|
||||||
|
Operations take either 0 or 1 parameter. The ones that take a parameter, it can be either a int8, int16 or int32.
|
||||||
|
|
||||||
|
Instructions follow this logic:
|
||||||
|
|
||||||
|
00 ~ 9F : no parameter
|
||||||
|
A0 ~ BF : int8 (1 byte)
|
||||||
|
C0 ~ DF : int16 (2 bytes)
|
||||||
|
E0 ~ FF : int32 (4 bytes)
|
||||||
|
|
||||||
|
The operations of 1, 2 and 4 bytes are always interchangeable by adding/subtracting 0x20.
|
||||||
|
|
||||||
|
,----------- no parameter
|
||||||
|
| ,-------- int8
|
||||||
|
| | ,----- int16
|
||||||
|
| | | ,-- int32
|
||||||
|
NP I8 I16 I32 Opc Instruction Description
|
||||||
|
|
||||||
|
Stack operations:
|
||||||
|
a0 c0 e0 pushi [int] Push int
|
||||||
|
a1 c1 e1 pushc [index] Push constant
|
||||||
|
a2 c2 e2 pushf [function] Push function id
|
||||||
|
00 pushz Push zero (or false)
|
||||||
|
01 pusht Push true
|
||||||
|
02 newa Push (create) empty array
|
||||||
|
03 newt Push (create) empty table
|
||||||
|
04 pop
|
||||||
|
05 dup
|
||||||
|
|
||||||
|
Local variables:
|
||||||
|
a3 c3 e3 pushv [int] Push n nil values into the stack (used to init local vars)
|
||||||
|
ab cb eb set [index] Set value in stack position (set local variable)
|
||||||
|
a4 c4 e4 dupv [index] Duplicate stack value (load local variable)
|
||||||
|
a5 c5 e5 setg [int] Set global variable
|
||||||
|
a6 c6 e6 getg [int] Get global variable
|
||||||
|
|
||||||
|
Function operations:
|
||||||
|
a7 c7 e7 call [n_pars] Enter function on stack toplevel (passing n next stack values as parameters)
|
||||||
|
10 ret Leave a function (return value in stack)
|
||||||
|
11 retn Leave a function (return nil)
|
||||||
|
|
||||||
|
Table and array operations:
|
||||||
|
16 getkv Get table's value based on key (pull 1 value, push 1 value)
|
||||||
|
17 setkv Set table's key and value (pull 2 values from stack)
|
||||||
|
18 geta Get array's position value
|
||||||
|
19 seta Set array's position value (pull 2 values from stack)
|
||||||
|
1a appnd Add value to the end of array
|
||||||
|
1b next Push the next pair into the stack (for loops)
|
||||||
|
1c smt Set value metatable
|
||||||
|
1d mt Get value metatable
|
||||||
|
|
||||||
|
Logical/arithmetic:
|
||||||
|
20 sum Sum top 2 values in stack
|
||||||
|
21 sub Subtract top 2 values in stack
|
||||||
|
22 mul Multiply top 2 values in stack
|
||||||
|
23 div Float division
|
||||||
|
24 idiv Integer division
|
||||||
|
25 eq Equality
|
||||||
|
26 neq Inequality
|
||||||
|
27 lt Less than
|
||||||
|
28 lte Less than or equals
|
||||||
|
29 gt Greater than
|
||||||
|
2a gte Greater than or equals
|
||||||
|
2b and Bitwise AND
|
||||||
|
2c or Bitwise OR
|
||||||
|
2d xor Bitwise XOR
|
||||||
|
2e pow Power
|
||||||
|
2f shl Shift left
|
||||||
|
30 shr Shift right
|
||||||
|
31 mod Modulo
|
||||||
|
|
||||||
|
Other value operations:
|
||||||
|
40 len Get table, array or string size
|
||||||
|
41 type Get type from value at the top of the stack
|
||||||
|
b0 cast [type] Cast type to another type
|
||||||
|
42 ver Return VM version
|
||||||
|
|
||||||
|
External code:
|
||||||
|
48 cmpl Compile code to assembly
|
||||||
|
49 asmbl Assemble code to bytecode format
|
||||||
|
4a load Load bytecode as function (will place function on stack)
|
||||||
|
|
||||||
|
Control flow:
|
||||||
|
a8 c8 e8 bz [pc] Branch if zero
|
||||||
|
a9 c9 e9 bnz [pc] Branch if not zero
|
||||||
|
aa ca ea jmp [pc] Unconditional jump
|
||||||
|
* Jumps can only happen within the same function.
|
||||||
|
|
||||||
|
|
||||||
|
Error handling: (0xa0~0xaf)
|
||||||
|
???
|
||||||
15
lua-temp/doc/VM
Normal file
15
lua-temp/doc/VM
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
Internal handling of values
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
## Supported types
|
||||||
|
Nil 0
|
||||||
|
Integer 1
|
||||||
|
Float 2
|
||||||
|
String 3
|
||||||
|
Array 4
|
||||||
|
Table 5
|
||||||
|
Function 6
|
||||||
|
NativePointer 7
|
||||||
|
|
||||||
|
## Internal format
|
||||||
|
???
|
||||||
74
lua-temp/tests.lua
Normal file
74
lua-temp/tests.lua
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
local assemble = require('tyche-as')
|
||||||
|
|
||||||
|
function tprint(o, indent)
|
||||||
|
indent = indent or 0
|
||||||
|
local spacing = string.rep(" ", indent)
|
||||||
|
|
||||||
|
if type(o) == 'table' then
|
||||||
|
local s = '{\n'
|
||||||
|
for k, v in pairs(o) do
|
||||||
|
-- Format keys: quote strings, leave numbers as is
|
||||||
|
local key = type(k) == 'string' and '["'..k..'"]' or '['..k..']'
|
||||||
|
s = s .. spacing .. " " .. key .. " = " .. tprint(v, indent + 1) .. ",\n"
|
||||||
|
end
|
||||||
|
return s .. spacing .. '}'
|
||||||
|
elseif type(o) == 'string' then
|
||||||
|
return '"' .. o .. '"'
|
||||||
|
else
|
||||||
|
return tostring(o)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function assert_eq(found, expected, key)
|
||||||
|
assert(type(found) == type(expected), "Types not matching " .. ((key ~= nil) and ('(key: ' .. key .. ')') or ''))
|
||||||
|
if type(found) == 'table' then
|
||||||
|
assert(#found == #expected, "Tables are of different sizes " .. ((key ~= nil) and ('(key: ' .. key .. ')') or ''))
|
||||||
|
for k,v in pairs(found) do
|
||||||
|
assert_eq(v, expected[k], k)
|
||||||
|
end
|
||||||
|
for k,v in pairs(expected) do
|
||||||
|
assert_eq(v, found[k], k)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
assert(found == expected, 'Assertion failed, expected "' .. tprint(expected) .. '", found "' .. tprint(found) .. '".')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local source = [[
|
||||||
|
.const
|
||||||
|
0: 3.14
|
||||||
|
1: "Hello world"
|
||||||
|
|
||||||
|
.func 0
|
||||||
|
pushi 2 ; this is a comment
|
||||||
|
pushi 3
|
||||||
|
sum
|
||||||
|
ret
|
||||||
|
.func 1
|
||||||
|
pushi 5000
|
||||||
|
ret ]]
|
||||||
|
|
||||||
|
local expected = {
|
||||||
|
constants = { [0] = 3.14, [1] = "Hello world" },
|
||||||
|
functions = {
|
||||||
|
[0] = {
|
||||||
|
{ "pushi", 2 },
|
||||||
|
{ "pushi", 3 },
|
||||||
|
{ "sum" },
|
||||||
|
{ "ret" },
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
{ "pushi", 5000 },
|
||||||
|
{ "ret" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local found = assemble(source)
|
||||||
|
-- tprint(expected)
|
||||||
|
tprint(found)
|
||||||
|
assert_eq(found, expected)
|
||||||
|
end
|
||||||
|
|
||||||
|
print('End.')
|
||||||
62
lua-temp/tyche-as.lua
Normal file
62
lua-temp/tyche-as.lua
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
----------------------
|
||||||
|
-- --
|
||||||
|
-- PARSER --
|
||||||
|
-- --
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
local function assemble(source)
|
||||||
|
local proto = {
|
||||||
|
constants = {},
|
||||||
|
functions = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
local section = ''
|
||||||
|
local current_f_id = 0
|
||||||
|
|
||||||
|
for line in source:gmatch("([^\n]+)") do
|
||||||
|
local line = line:gsub("%s*;.*$", "") -- remove comments
|
||||||
|
line = line:match("^%s*(.-)%s*$") -- trim
|
||||||
|
|
||||||
|
if #line == 1 then goto continue end
|
||||||
|
|
||||||
|
if line == ".const" then
|
||||||
|
section = 'const'
|
||||||
|
elseif line:match("%.func%s+%d+") then
|
||||||
|
section = 'function'
|
||||||
|
local f_id = tonumber(line:match("%.func%s+(%d+)"))
|
||||||
|
proto.functions[f_id] = {}
|
||||||
|
current_f_id = f_id
|
||||||
|
elseif section == 'const' then
|
||||||
|
local k, v = line:match("^%s*(%d+)%s*:%s*(.+)$")
|
||||||
|
if v:sub(1, 1) == '"' then
|
||||||
|
proto.constants[tonumber(k)] = line:match('"(.*)"')
|
||||||
|
else
|
||||||
|
proto.constants[tonumber(k)] = tonumber(v)
|
||||||
|
end
|
||||||
|
elseif section == 'function' then
|
||||||
|
local inst, par = line:match("^%s*(%a+)%s+(%d+)%s*$")
|
||||||
|
if inst then
|
||||||
|
table.insert(proto.functions[current_f_id], { inst, tonumber(par) })
|
||||||
|
else
|
||||||
|
local inst = line:match("^%s*(%a+)%s*$")
|
||||||
|
table.insert(proto.functions[current_f_id], { inst })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
::continue::
|
||||||
|
end
|
||||||
|
|
||||||
|
return proto
|
||||||
|
end
|
||||||
|
|
||||||
|
----------------------
|
||||||
|
-- --
|
||||||
|
-- MAIN --
|
||||||
|
-- --
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
if ... then
|
||||||
|
return assemble
|
||||||
|
else
|
||||||
|
error("Running assembler directly not supported yet")
|
||||||
|
end
|
||||||
0
lua-temp/tyche-vm.lua
Normal file
0
lua-temp/tyche-vm.lua
Normal file
Reference in New Issue
Block a user