From 5c4a545369f25e1c971c7112254c8856d2af33cd Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Wed, 27 Sep 2023 13:58:37 -0500 Subject: [PATCH] :pencil: doc: roadmap --- README.md | 14 +++ notes.md | 176 --------------------------- pictures/lunar wave crab nebula.jpeg | Bin 0 -> 28122 bytes test_vectors/fizz_buzz.lua | 6 +- 4 files changed, 17 insertions(+), 179 deletions(-) create mode 100644 README.md delete mode 100644 notes.md create mode 100644 pictures/lunar wave crab nebula.jpeg diff --git a/README.md b/README.md new file mode 100644 index 0000000..b392da9 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +LunarWaveVM is a Lua 5.4 virtual machine written in Rust. + +![A star field with an orange crab-shaped nebula facing a dark purple moon with a bright magenta crescent.](pictures/lunar wave crab nebula.jpeg) + +# Roadmap + +- [x] Loading simple pre-compiled bytecode programs +- [x] Hash tables +- [x] Fizzbuzz +- [ ] Closures +- [ ] Garbage collection +- [ ] Long strings +- [ ] Using arrays internally for tables +- [ ] Compiling Lua source code to bytecode diff --git a/notes.md b/notes.md deleted file mode 100644 index 1d23d4d..0000000 --- a/notes.md +++ /dev/null @@ -1,176 +0,0 @@ -Lua source code - -`hello.lua` - -```lua -print "Hello." -``` - -`math.lua` - -```lua -local function add (a, b) - return a + b -end - -print (("1 + 2 = %i"):format (add (1, 2))) -``` - -luac5.4 listing - -``` -main (5 instructions at 0x564f4fd74cc0) -0+ params, 2 slots, 1 upvalue, 0 locals, 2 constants, 0 functions - 1 [1] VARARGPREP 0 - 2 [1] GETTABUP 0 0 0 ; _ENV "print" - 3 [1] LOADK 1 1 ; "Hello." - 4 [1] CALL 0 2 1 ; 1 in 0 out - 5 [1] RETURN 0 1 1 ; 0 out -``` - -``` -main (12 instructions at 0x55ee2417acc0) -0+ params, 7 slots, 1 upvalue, 1 local, 3 constants, 1 function - 1 [1] VARARGPREP 0 - 2 [3] CLOSURE 0 0 ; 0x55ee2417b000 - 3 [5] GETTABUP 1 0 0 ; _ENV "print" - 4 [5] LOADK 2 1 ; "1 + 2 = %i" - 5 [5] SELF 2 2 2k ; "format" - 6 [5] MOVE 4 0 - 7 [5] LOADI 5 1 - 8 [5] LOADI 6 2 - 9 [5] CALL 4 3 0 ; 2 in all out - 10 [5] CALL 2 0 0 ; all in all out - 11 [5] CALL 1 0 1 ; all in 0 out - 12 [5] RETURN 1 1 1 ; 0 out - -function (4 instructions at 0x55ee2417b000) -2 params, 3 slots, 0 upvalues, 2 locals, 0 constants, 0 functions - 1 [2] ADD 2 0 1 - 2 [2] MMBIN 0 1 6 ; __add - 3 [2] RETURN1 2 - 4 [3] RETURN0 -``` - -``` -main (14 instructions at 0x559f55e1ecd0) -0+ params, 2 slots, 1 upvalue, 1 local, 5 constants, 1 function - 1 [1] VARARGPREP 0 - 2 [1] GETTABUP 0 0 0 ; _ENV "arg" - 3 [1] GETI 0 0 1 - 4 [1] EQK 0 1 0 ; "93" - 5 [1] JMP 4 ; to 10 - 6 [2] GETTABUP 0 0 2 ; _ENV "print" - 7 [2] LOADK 1 3 ; "it's 93" - 8 [2] CALL 0 2 1 ; 1 in 0 out - 9 [2] JMP 3 ; to 13 - 10 [4] GETTABUP 0 0 2 ; _ENV "print" - 11 [4] LOADK 1 4 ; "it's not 93" - 12 [4] CALL 0 2 1 ; 1 in 0 out - 13 [9] CLOSURE 0 0 ; 0x559f55e1f3d0 - 14 [9] RETURN 1 1 1 ; 0 out -constants (5) for 0x559f55e1ecd0: - 0 S "arg" - 1 S "93" - 2 S "print" - 3 S "it's 93" - 4 S "it's not 93" -locals (1) for 0x559f55e1ecd0: - 0 unused_fn 14 15 -upvalues (1) for 0x559f55e1ecd0: - 0 _ENV 1 0 - -function (4 instructions at 0x559f55e1f3d0) -0 params, 2 slots, 1 upvalue, 0 locals, 2 constants, 0 functions - 1 [8] GETTABUP 0 0 0 ; _ENV "print" - 2 [8] LOADK 1 1 ; "unused" - 3 [8] CALL 0 2 1 ; 1 in 0 out - 4 [9] RETURN0 -constants (2) for 0x559f55e1f3d0: - 0 S "print" - 1 S "unused" -locals (0) for 0x559f55e1f3d0: -upvalues (1) for 0x559f55e1f3d0: - 0 _ENV 0 0 -``` - -Octal dump of luac5.4 byte code - -``` -0000000 1b 4c 75 61 54 00 19 93 0d 0a 1a 0a 04 08 08 78 >.LuaT..........x< -0000020 56 00 00 00 00 00 00 00 00 00 00 00 28 77 40 01 >V...........(w@.< -0000040 8b 40 68 65 6c 6c 6f 2e 6c 75 61 80 80 00 01 02 >.@hello.lua.....< -0000060 85 51 00 00 00 0b 00 00 00 83 80 00 00 44 00 02 >.Q...........D..< -0000100 01 46 00 01 01 82 04 86 70 72 69 6e 74 04 87 48 >.F......print..H< -0000120 65 6c 6c 6f 2e 81 01 00 00 80 85 01 00 00 00 00 >ello............< -0000140 80 80 81 85 5f 45 4e 56 >...._ENV< -0000150 -``` - -``` -0000000 1b 4c 75 61 54 00 19 93 0d 0a 1a 0a 04 08 08 78 >.LuaT..........x< -0000020 56 00 00 00 00 00 00 00 00 00 00 00 28 77 40 01 >V...........(w@.< -0000040 8a 40 6d 61 74 68 2e 6c 75 61 80 80 00 01 07 8c >.@math.lua......< -0000060 51 00 00 00 4f 00 00 00 8b 00 00 00 03 81 00 00 >Q...O...........< -0000100 14 81 02 02 00 02 00 00 81 02 00 80 01 83 00 80 >................< -0000120 44 02 03 00 44 01 00 00 c4 00 00 01 c6 00 01 01 >D...D...........< -0000140 83 04 86 70 72 69 6e 74 04 8b 31 20 2b 20 32 20 >...print..1 + 2 < -0000160 3d 20 25 69 04 87 66 6f 72 6d 61 74 81 01 00 00 >= %i..format....< -0000200 81 80 81 83 02 00 03 84 22 01 00 01 2e 00 01 06 >........".......< -0000220 48 01 02 00 47 01 01 00 80 80 80 84 01 00 00 01 >H...G...........< -0000240 80 82 82 61 80 84 82 62 80 84 80 8c 01 02 02 00 >...a...b........< -0000260 00 00 00 00 00 00 00 00 80 81 84 61 64 64 82 8c >...........add..< -0000300 81 85 5f 45 4e 56 >.._ENV< -0000306 - -``` - -# Interpretation of byte code - -Overall structure - -- Roughly 32 byte header with magic number, version number, etc. -- File name -- `80 80 00 01 02 85` header for main function -- Packed 4-byte instructions for main function -- `82` or `83` length prefix for string table -- String table for main function -- `81 01 00 00 81 80 81 83 02 00 03 84` header for "add" function -- Packed 4-byte instructions for "add" function -- `80 80 80 84 01 00 00 01 80` Header for file-scope debug symbols? -- File-scope debug symbols? -- String table for entire file? - -## Bytecodes - -Per lopcodes.h, instructions are 32 bits long, always. -The opcode is encoded in the first (highest?) 7 bits. - -``` -83 80 00 00 ; 0x03 = 3 = LOADK -0b 00 00 00 ; 0x0b = 11 = GETTABUP -22 01 00 01 ; 0x22 = 34 = ADD -2e 00 01 06 ; 0x2e = 46 = MMBIN -c4 00 00 01 ; 0xc4 = 68 = CALL -44 00 02 01 ; 0x44 = 68 = CALL -46 00 01 01 ; 0x46 = 70 = RETURN -47 01 01 00 ; 0x47 = 71 = RETURN0 -48 01 02 00 ; 0x48 = 72 = RETURN1 -51 00 00 00 ; 0x51 = 81 = VARARGPREP -``` - -## Strings - -Filenames are encoded at the top, and there's a string table at the bottom. - -Strings appear to be prefixed with a variable-length length prefix. -There is an extra byte before each string which I can't account for, -and the lengths seem to be off by one, e.g. 0x84 is a length of 3, not 4. - -| --- | -| "add" | 81 84 61 64 64 -| "_ENV" | 81 85 5f 45 4e 56 -| "print" | 04 86 70 72 69 6e 74 -| "format" | 04 87 66 6f 72 6d 61 74 -| "@math.lua" | 01 8a 40 6d 61 74 68 2e 6c 75 61 -| "1 + 2 = %i" | 04 8b 31 20 2b 20 32 20 3d 20 25 69 \ No newline at end of file diff --git a/pictures/lunar wave crab nebula.jpeg b/pictures/lunar wave crab nebula.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..c220b7aeffc9876ac3b1189a0d94e22d7f6f10de GIT binary patch literal 28122 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%0AAIFHtEH40M}hxWU+S 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 DzcfP_ literal 0 HcmV?d00001 diff --git a/test_vectors/fizz_buzz.lua b/test_vectors/fizz_buzz.lua index 55d81de..00d858a 100644 --- a/test_vectors/fizz_buzz.lua +++ b/test_vectors/fizz_buzz.lua @@ -1,10 +1,10 @@ for i = 1, 50 do if i % 3 == 0 and i % 5 == 0 then - print ("FizzBuzz") + print (i, "FizzBuzz") elseif i % 3 == 0 then - print ("Fizz") + print (i, "Fizz") elseif i % 5 == 0 then - print ("Buzz") + print (i, "Buzz") else print (i) end