11import { LuaEngine , LuaFactory } from "wasmoon"
2- import { loadLuaModule } from "./util"
2+ import { getLuaInterop } from "./lua-utils/luaInterop"
3+
4+ const loadLuaModule = async ( doString : ( luaCode : string ) => void , p : Promise < { default : string } > , moduleName : string , chunkName ?: string ) => {
5+ let { default : code } = await p
6+
7+ if ( code . startsWith ( "#" ) ) {
8+ // remove shebang
9+ const index = code . indexOf ( "\n" )
10+ if ( index !== - 1 ) {
11+ code = code . substring ( index )
12+ }
13+ }
14+
15+ // I think something broke with moonwasm. There seems to be a limit on how large the string can be.
16+ // This may be taking it too far but I've spent too much time on this already..
17+
18+ const bytes = ( new TextEncoder ( ) ) . encode ( code )
19+ let bytesString : string [ ] = [ ]
20+ let bytesStringIndex = 0
21+ for ( let i = 0 ; i < bytes . length ; i ++ ) {
22+ let code = bytes [ i ]
23+ bytesString [ bytesStringIndex ] = `\\${ code } `
24+ bytesStringIndex ++
25+ if ( bytesStringIndex > 8000 ) {
26+ let str = `CHUNKS = CHUNKS or {};CHUNKS[#CHUNKS + 1] = "${ bytesString . join ( "" ) } "`
27+ doString ( str )
28+ bytesString = [ ]
29+ bytesStringIndex = 0
30+ }
31+ }
32+ {
33+ let str = `CHUNKS = CHUNKS or {};CHUNKS[#CHUNKS + 1] = "${ bytesString . join ( "" ) } "`
34+ doString ( str )
35+ }
36+
37+ let str = `
38+ local code = "package.preload['${ moduleName } '] = function(...) " .. table.concat(CHUNKS) .. " end"
39+ assert(load(code, "${ chunkName } "))(...); CHUNKS = nil
40+ `
41+ doString ( str )
42+ }
43+
44+ export const loadLuaWasmoon = async ( ) => {
45+
346
4- export const loadLua = async ( ) => {
547 const factory = new LuaFactory ( )
648 const lua = await factory . createEngine ( {
749 openStandardLibs : true ,
@@ -40,31 +82,143 @@ export const loadLua = async () => {
4082
4183 _G.lsp = lsp` )
4284
43- console . log ( "OK" )
4485
45- return lua
46- }
86+ await lua . doString ( `
87+ _G.syntax_typesystem = require("nattlua.syntax.typesystem")
88+ _G.syntax_runtime = require("nattlua.syntax.runtime")
89+ ` )
90+
91+ const syntax_typesystem = lua . global . get ( "syntax_typesystem" )
92+ const syntax_runtime = lua . global . get ( "syntax_runtime" )
93+ const lsp = lua . global . get ( "lsp" )
94+ console . log ( "Lua engine initialized successfully" )
95+ return {
96+ syntax_typesystem,
97+ syntax_runtime,
98+ lsp,
99+ prettyPrint : ( lua : LuaEngine , code : string ) => {
100+ lua . doStringSync ( `
101+ function _G.prettyPrint(code)
102+ local nl = require("nattlua")
103+ local compiler = nl.Compiler(code, "temp", {
104+ emitter = {
105+ preserve_whitespace = false,
106+ string_quote = "\\"",
107+ no_semicolon = true,
108+ type_annotations = "explicit",
109+ force_parenthesis = true,
110+ comment_type_annotations = false,
111+ },
112+ parser = {
113+ skip_import = true,
114+ }
115+ })
116+ return assert(compiler:Emit())
117+ end
118+ ` )
47119
48- export const prettyPrint = ( lua : LuaEngine , code : string ) => {
49- lua . doStringSync ( `
50- function _G.prettyPrint(code)
51- local nl = require("nattlua")
52- local compiler = nl.Compiler(code, "temp", {
53- emitter = {
54- preserve_whitespace = false,
55- string_quote = "\\"",
56- no_semicolon = true,
57- type_annotations = "explicit",
58- force_parenthesis = true,
59- comment_type_annotations = false,
60- },
61- parser = {
62- skip_import = true,
63- }
64- })
65- return assert(compiler:Emit())
66- end
67- ` )
68-
69- return lua . global . get ( "prettyPrint" ) ( code ) as string
120+ return lua . global . get ( "prettyPrint" ) ( code ) as string
121+ }
122+
123+ }
70124}
125+
126+ export const loadLuaInterop = async ( ) => {
127+ const { newLua } = await getLuaInterop ( ) ;
128+ let lua = await newLua ( {
129+ print : s => {
130+ console . log ( '>' , s ) ;
131+ } ,
132+ printErr : s => {
133+ console . log ( '1>' , s ) ;
134+ console . log ( new Error ( ) . stack ) ;
135+ } ,
136+ } ) ;
137+ lua . newState ( ) ;
138+
139+ globalThis . lua = lua
140+
141+ let lsp : any
142+ globalThis . loadLSP = ( obj ) => lsp = obj
143+
144+ let syntax_runtime : any
145+ globalThis . loadSyntaxRuntime = ( obj ) => syntax_runtime = obj
146+
147+ let syntax_typesystem : any
148+ globalThis . loadSyntaxTypesystem = ( obj ) => syntax_typesystem = obj
149+
150+ await loadLuaModule ( ( str ) => lua . doString ( str ) , import ( "./../../build_output.lua" ) , "nattlua" )
151+ await lua . doString ( "for k, v in pairs(package.preload) do print(k,v) end require('nattlua') for k,v in pairs(IMPORTS) do package.preload[k] = v end" )
152+ await loadLuaModule ( ( str ) => lua . doString ( str ) , import ( "./../../language_server/lsp.lua" ) , "lsp" , "@language_server/lsp.lua" )
153+
154+ await lua . doString ( `
155+ local lsp = require("lsp")
156+
157+ local listeners = {}
158+
159+ function lsp.Call(data)
160+ assert(data.method, "missing method")
161+ listeners[data.method](data.params)
162+ end
163+
164+ function lsp.On(method, callback)
165+ listeners[method] = callback
166+ end
167+
168+ for k,v in pairs(lsp.methods) do
169+ lsp.methods[k] = function(params)
170+ print("calling on server", k)
171+ local ok, res = xpcall(function()
172+ return v(params)
173+ end, debug.traceback)
174+ if not ok then
175+ error(res, 2)
176+ end
177+ return res
178+ end
179+ end
180+
181+ jsToLua[0].loadLSP(lsp)` )
182+
183+
184+ await lua . doString ( `
185+ jsToLua[0].loadSyntaxRuntime(require("nattlua.syntax.typesystem"))
186+ jsToLua[0].loadSyntaxTypesystem(require("nattlua.syntax.runtime"))
187+ ` )
188+
189+ globalThis . syntax_typesystem = syntax_typesystem
190+ globalThis . syntax_runtime = syntax_runtime
191+ globalThis . lsp = lsp
192+
193+ console . log ( "Lua interop initialized successfully" )
194+ return {
195+ syntax_typesystem,
196+ syntax_runtime,
197+ lsp,
198+ prettyPrint : ( lua : LuaEngine , code : string ) => {
199+ lua . doStringSync ( `
200+ function _G.prettyPrint(code)
201+ local nl = require("nattlua")
202+ local compiler = nl.Compiler(code, "temp", {
203+ emitter = {
204+ preserve_whitespace = false,
205+ string_quote = "\\"",
206+ no_semicolon = true,
207+ type_annotations = "explicit",
208+ force_parenthesis = true,
209+ comment_type_annotations = false,
210+ },
211+ parser = {
212+ skip_import = true,
213+ }
214+ })
215+ return assert(compiler:Emit())
216+ end
217+ ` )
218+
219+ return lua . global . get ( "prettyPrint" ) ( code ) as string
220+ }
221+
222+ }
223+
224+ }
0 commit comments