diff --git a/backend/experiments/CanvasHack/Main.fs b/backend/experiments/CanvasHack/Main.fs index 2c5524f404..c122712319 100644 --- a/backend/experiments/CanvasHack/Main.fs +++ b/backend/experiments/CanvasHack/Main.fs @@ -95,7 +95,9 @@ let seedCanvasV2 (canvasName : string) = do! C.saveTLIDs canvasID oplists print - $"Success saved canvas - endpoints available at {host} (bwdserver) and {experimentalHost} (bwd-danger-server)" + $"Success saved canvas - endpoints available + at {host} (bwdserver) + and {experimentalHost} (bwd-danger-server)" } [] @@ -112,6 +114,8 @@ let main (args : string []) = `canvas-hack {CommandNames.export}' to save dark-editor to disk" | [| CommandNames.import; canvasName |] -> + print $"Loading canvas {canvasName} from disk" + let config = parseYamlExn $"{baseDir}/{canvasName}/config.yml" diff --git a/backend/experiments/StdLibExperimental/Libs/DarkTypes.fs b/backend/experiments/StdLibExperimental/Libs/DarkTypes.fs new file mode 100644 index 0000000000..569326697c --- /dev/null +++ b/backend/experiments/StdLibExperimental/Libs/DarkTypes.fs @@ -0,0 +1,121 @@ +module StdLibExperimental.Libs.DarkTypes + +open System.Threading.Tasks +open FSharp.Control.Tasks + +open Prelude +open Tablecloth + +module Errors = LibExecution.Errors + +open LibExecution.RuntimeTypes +module PT = LibExecution.ProgramTypes + +open LibExecution.StdLib.Shortcuts + +let fn = FQFnName.stdlibFnName + +let incorrectArgs = Errors.incorrectArgs + + +// maybe these types/fns are only available to DarkEditor - giving access to users at this point +// is probably more confusing than it's worth + +// TODO: separately, write a fuzzer that will randomly generate these types + +// TODO: a bunch of stuff is missing +let types : List = + [ { name = typ "ProgramTypes" "TypeReference" 0 + typeParams = [] + definition = + CustomType.Enum( + { name = "TInt"; fields = [] }, + [ { name = "TString"; fields = [] } + { name = "TCustomType"; fields = [] } ] + ) + description = "Represents a PT.TypeReference" + deprecated = NotDeprecated } + + + { name = typ "ProgramTypes" "Expr" 0 + typeParams = [] + definition = + CustomType.Enum( + { name = "EUnit"; fields = [] }, + [ { name = "EBool"; fields = [ { typ = TBool; label = None } ] } + + { name = "EString" + // TODO: support interpolation + fields = [ { typ = TString; label = None } ] } + + { name = "EInt"; fields = [ { typ = TInt; label = None } ] } + + { name = "ELet" + fields = + [ { typ = TString; label = Some "binding" } + { typ = TVariable "TODO: ANY"; label = Some "value" } + { typ = TVariable "TODO: ANY"; label = Some "body" } ] } + + { name = "EVariable"; fields = [ { typ = TString; label = None } ] } ] + ) + description = "Represents a PT.Expr" + deprecated = NotDeprecated } + + + (* + module UserFunction = + type Parameter = + { id : id + name : string + typ : TypeReference + description : string } + + type T = + { tlid : tlid + name : string + typeParams : List + parameters : List + returnType : TypeReference + description : string + infix : bool + body : Expr } + *) + + + // { name = tp "ProgramTypes" "UserFunctionParameter" 0 + // typeParams = [ ] + // definition = + // PT.CustomType.Record( + // { id = gid(); name = "name"; typ : TypeReference } + // // name: string + // { id = 1UL; name = "name"; typ = PT.TString; label = None }, + // // typ : TypeReference + // ) + // description = "Represents a PT.UserFunction.Parameter" } + + // { name = tp "ProgramTypes" "UserFunction" 0 + // typeParams = [ ] + // definition = + // PT.CustomType.Enum() } + ] + + + + +// // Dark fn that goes from SynTree -> PT.Expr +// // later: Dark fn that goes from SynTree -> PT.TypeReference +// // later: Dark fn that goes from SynTree -> PT.Function + +// ... I'm not sure how we could + +// //type StdlibTypeName = { module_ : string; typ : string; version : int } + +// module Parser = + +// // lol what if this were a Dark fn? +// let toExpr (node : SynTree.Node) : PT.Expr = +// let (typ, text, children) = Node node + +// match typ, text, children with +// | ("Int", i, []) -> ProgramTypes.Expr(typeName, "EConstructor", [int i]) +// | ("String", s, []) -> ProgramTypes.Expr.EString(s) diff --git a/backend/experiments/StdLibExperimental/Libs/TreeSitter.fs b/backend/experiments/StdLibExperimental/Libs/TreeSitter.fs new file mode 100644 index 0000000000..df87404276 --- /dev/null +++ b/backend/experiments/StdLibExperimental/Libs/TreeSitter.fs @@ -0,0 +1,49 @@ +module StdLibExperimental.Libs.TreeSitter + +open System.Threading.Tasks +open FSharp.Control.Tasks + +open Prelude +open Tablecloth +open LibExecution.RuntimeTypes + +module Errors = LibExecution.Errors + +let fn = FQFnName.stdlibFnName + +let incorrectArgs = Errors.incorrectArgs +module PT = LibExecution.ProgramTypes + + + +// Ideally, all of this would be in Dark code +module SyntaxTree = + // This is what's sent to us from the frontend + type TreeSitterNode = + { typ : string + text : string + fieldName : Option + children : List } + + type TreeSitterTreeTpl = Node of (string * string * List) + + let rec toTuple (node : TreeSitterNode) : TreeSitterTreeTpl = + Node(node.typ, node.text, (node.children |> List.map toTuple)) + + // Ideally this would return the _Dark_ PT.Expr, not the F# one + let toExpr (node : TreeSitterNode) : PT.Expr = + let t = toTuple node + + match t with + | Node ("string", s, []) -> PT.Expr.EString(gid (), [ PT.StringText s ]) + | Node ("int", s, []) -> PT.Expr.EInt(gid (), int s) + //| Node ("float", s, []) -> PT.Expr.EFloat (gid(), float s) + //| Node ("bool", s, []) -> PT.Expr.EBool (gid(), bool s) + | _ -> Exception.raiseInternal $"Couldn't parse expression" [ "node", node ] + + +//type toFunction (node: TreeSitterNode) : PT.UserFunction.T + + + +let fns : List = [] diff --git a/backend/experiments/StdLibExperimental/StdLibExperimental.fsproj b/backend/experiments/StdLibExperimental/StdLibExperimental.fsproj index b5742fcbaf..a2c41b09d4 100644 --- a/backend/experiments/StdLibExperimental/StdLibExperimental.fsproj +++ b/backend/experiments/StdLibExperimental/StdLibExperimental.fsproj @@ -10,7 +10,9 @@ + + diff --git a/backend/src/StdLibExecution/Libs/Json.fs b/backend/src/StdLibExecution/Libs/Json.fs index 3b567b057c..e7b3a77952 100644 --- a/backend/src/StdLibExecution/Libs/Json.fs +++ b/backend/src/StdLibExecution/Libs/Json.fs @@ -366,6 +366,7 @@ let parse match Map.tryFind "Just" objFields with | Some v -> DOption(Some(convert oType v)) | None -> DOption None + | TOption oType, v -> convert oType j |> Some |> DOption | TResult (okType, errType), JsonValueKind.Object -> let objFields = @@ -410,16 +411,20 @@ let parse | CustomType.Record (firstField, additionalFields) -> let fieldDefs = firstField :: additionalFields + let enumerated = j.EnumerateObject() |> Seq.toList + let dvalMap = - j.EnumerateObject() - |> Seq.map (fun jp -> - let correspondingType = - fieldDefs - // TODO: handle case where field isn't found - |> List.find (fun def -> def.name = jp.Name) - |> fun def -> def.typ - let converted = convert correspondingType jp.Value - (jp.Name, converted)) + fieldDefs + |> List.map (fun def -> + let correspondingValue = + enumerated + // TODO: handle case where value isn't found for + // and maybe, if it's an Option<>al thing, don't complain + |> List.find (fun v -> v.Name = def.name) + |> fun field -> field.Value + + let converted = convert def.typ correspondingValue + (def.name, converted)) |> Map.ofSeq // TYPESCLEANUP add typename diff --git a/backend/src/Wasm/LibWASM.fs b/backend/src/Wasm/LibWASM.fs new file mode 100644 index 0000000000..d2e144e6a2 --- /dev/null +++ b/backend/src/Wasm/LibWASM.fs @@ -0,0 +1,43 @@ +/// Standard libraries for Files, Directories, and other OS/file system stuff +module Wasm.LibWASM + +open System +open System.Threading.Tasks +open FSharp.Control.Tasks + +open Prelude +open Tablecloth + +open LibExecution.RuntimeTypes + +open LibExecution.StdLib.Shortcuts + +module PT = LibExecution.ProgramTypes +module Exe = LibExecution.Execution + +let types : List = [] + +let fns : List = + [ { name = fn "WASM" "callJSFunction" 0 + typeParams = [] + parameters = + [ Param.make "functionName" TString "" + Param.make "serializedArgs" TString "" ] + returnType = TResult(TUnit, TString) + description = "TODO" + fn = + (function + | _, _, [ DString functionName; DString args ] -> + // TODO: I'm not really sure what to do about `args`. Maybe it should be an object to serialize? + // or have an additiol function like callJSFunctionTyped(functionName: string, args: T) + uply { + try + WasmHelpers.postMessage functionName args + return DResult(Ok DUnit) + with + | e -> return DResult(Error(DString($"Error: {e.Message}"))) + } + | _ -> incorrectArgs ()) + sqlSpec = NotQueryable + previewable = Impure + deprecated = NotDeprecated } ] diff --git a/backend/src/Wasm/Wasm.fsproj b/backend/src/Wasm/Wasm.fsproj index 2f16ec7fea..fdcfc8c8b6 100644 --- a/backend/src/Wasm/Wasm.fsproj +++ b/backend/src/Wasm/Wasm.fsproj @@ -29,6 +29,7 @@ + diff --git a/backend/static/README.md b/backend/static/README.md new file mode 100644 index 0000000000..7c89f61a94 --- /dev/null +++ b/backend/static/README.md @@ -0,0 +1,2 @@ +This directory contains static files that are served by a Dark backend for a webpage. +The `dark_wasm` and `tree-sitter` directories should ideally be hosted in a CDN, long-term. diff --git a/backend/static/tree-sitter/README.md b/backend/static/tree-sitter/README.md new file mode 100644 index 0000000000..7bdf6bba20 --- /dev/null +++ b/backend/static/tree-sitter/README.md @@ -0,0 +1,7 @@ +# Tree-Sitter WebAssembly/JS Bindings + +These files support parsing Darklang code in the browser. + +The `tree-sitter.js` and `tree-sitter.wasm` files were pulled from the releases of `tree-sitter`. The .js file is a wrapper around the .wasm file, and the .wasm file is the actual parser which calls upon language-specific parsers (like `tree-sitter-darklang.wasm`) after loading them. + +The actual parsing of Darklang code is done by the `tree-sitter-darklang.wasm` file, which is a compiled version of the `grammar.js` file in the `parser/tree-sitter-darklang` directory. See the README.md in that directory for more information. \ No newline at end of file diff --git a/backend/static/tree-sitter/tree-sitter-darklang.wasm b/backend/static/tree-sitter/tree-sitter-darklang.wasm new file mode 100755 index 0000000000..cf09c63609 Binary files /dev/null and b/backend/static/tree-sitter/tree-sitter-darklang.wasm differ diff --git a/backend/static/tree-sitter/tree-sitter.js b/backend/static/tree-sitter/tree-sitter.js new file mode 100644 index 0000000000..e115e104f0 --- /dev/null +++ b/backend/static/tree-sitter/tree-sitter.js @@ -0,0 +1 @@ +var Module=void 0!==Module?Module:{},TreeSitter=function(){var initPromise,document="object"==typeof window?{currentScript:window.document.currentScript}:null;class Parser{constructor(){this.initialize()}initialize(){throw new Error("cannot construct a Parser before calling `init()`")}static init(moduleOptions){return initPromise||(Module=Object.assign({},Module,moduleOptions),initPromise=new Promise((resolveInitPromise=>{var moduleOverrides=Object.assign({},Module),arguments_=[],thisProgram="./this.program",quit_=(e,t)=>{throw t},ENVIRONMENT_IS_WEB="object"==typeof window,ENVIRONMENT_IS_WORKER="function"==typeof importScripts,ENVIRONMENT_IS_NODE="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,scriptDirectory="",read_,readAsync,readBinary,setWindowTitle;function locateFile(e){return Module.locateFile?Module.locateFile(e,scriptDirectory):scriptDirectory+e}function logExceptionOnExit(e){if(e instanceof ExitStatus)return;err("exiting due to exception: "+e)}if(ENVIRONMENT_IS_NODE){var fs=require("fs"),nodePath=require("path");scriptDirectory=ENVIRONMENT_IS_WORKER?nodePath.dirname(scriptDirectory)+"/":__dirname+"/",read_=(e,t)=>(e=isFileURI(e)?new URL(e):nodePath.normalize(e),fs.readFileSync(e,t?void 0:"utf8")),readBinary=e=>{var t=read_(e,!0);return t.buffer||(t=new Uint8Array(t)),t},readAsync=(e,t,r)=>{e=isFileURI(e)?new URL(e):nodePath.normalize(e),fs.readFile(e,(function(e,_){e?r(e):t(_.buffer)}))},process.argv.length>1&&(thisProgram=process.argv[1].replace(/\\/g,"/")),arguments_=process.argv.slice(2),"undefined"!=typeof module&&(module.exports=Module),quit_=(e,t)=>{if(keepRuntimeAlive())throw process.exitCode=e,t;logExceptionOnExit(t),process.exit(e)},Module.inspect=function(){return"[Emscripten Module object]"}}else(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&(ENVIRONMENT_IS_WORKER?scriptDirectory=self.location.href:void 0!==document&&document.currentScript&&(scriptDirectory=document.currentScript.src),scriptDirectory=0!==scriptDirectory.indexOf("blob:")?scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1):"",read_=e=>{var t=new XMLHttpRequest;return t.open("GET",e,!1),t.send(null),t.responseText},ENVIRONMENT_IS_WORKER&&(readBinary=e=>{var t=new XMLHttpRequest;return t.open("GET",e,!1),t.responseType="arraybuffer",t.send(null),new Uint8Array(t.response)}),readAsync=(e,t,r)=>{var _=new XMLHttpRequest;_.open("GET",e,!0),_.responseType="arraybuffer",_.onload=()=>{200==_.status||0==_.status&&_.response?t(_.response):r()},_.onerror=r,_.send(null)},setWindowTitle=e=>document.title=e);var out=Module.print||console.log.bind(console),err=Module.printErr||console.warn.bind(console);Object.assign(Module,moduleOverrides),moduleOverrides=null,Module.arguments&&(arguments_=Module.arguments),Module.thisProgram&&(thisProgram=Module.thisProgram),Module.quit&&(quit_=Module.quit);var STACK_ALIGN=16,dynamicLibraries=Module.dynamicLibraries||[],wasmBinary;Module.wasmBinary&&(wasmBinary=Module.wasmBinary);var noExitRuntime=Module.noExitRuntime||!0,wasmMemory;"object"!=typeof WebAssembly&&abort("no native wasm support detected");var ABORT=!1,EXITSTATUS,UTF8Decoder="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0,buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function UTF8ArrayToString(e,t,r){for(var _=t+r,n=t;e[n]&&!(n>=_);)++n;if(n-t>16&&e.buffer&&UTF8Decoder)return UTF8Decoder.decode(e.subarray(t,n));for(var s="";t>10,56320|1023&l)}}else s+=String.fromCharCode((31&a)<<6|o)}else s+=String.fromCharCode(a)}return s}function UTF8ToString(e,t){return e?UTF8ArrayToString(HEAPU8,e,t):""}function stringToUTF8Array(e,t,r,_){if(!(_>0))return 0;for(var n=r,s=r+_-1,a=0;a=55296&&o<=57343)o=65536+((1023&o)<<10)|1023&e.charCodeAt(++a);if(o<=127){if(r>=s)break;t[r++]=o}else if(o<=2047){if(r+1>=s)break;t[r++]=192|o>>6,t[r++]=128|63&o}else if(o<=65535){if(r+2>=s)break;t[r++]=224|o>>12,t[r++]=128|o>>6&63,t[r++]=128|63&o}else{if(r+3>=s)break;t[r++]=240|o>>18,t[r++]=128|o>>12&63,t[r++]=128|o>>6&63,t[r++]=128|63&o}}return t[r]=0,r-n}function stringToUTF8(e,t,r){return stringToUTF8Array(e,HEAPU8,t,r)}function lengthBytesUTF8(e){for(var t=0,r=0;r=55296&&_<=57343?(t+=4,++r):t+=3}return t}function updateGlobalBufferAndViews(e){buffer=e,Module.HEAP8=HEAP8=new Int8Array(e),Module.HEAP16=HEAP16=new Int16Array(e),Module.HEAP32=HEAP32=new Int32Array(e),Module.HEAPU8=HEAPU8=new Uint8Array(e),Module.HEAPU16=HEAPU16=new Uint16Array(e),Module.HEAPU32=HEAPU32=new Uint32Array(e),Module.HEAPF32=HEAPF32=new Float32Array(e),Module.HEAPF64=HEAPF64=new Float64Array(e)}var INITIAL_MEMORY=Module.INITIAL_MEMORY||33554432;wasmMemory=Module.wasmMemory?Module.wasmMemory:new WebAssembly.Memory({initial:INITIAL_MEMORY/65536,maximum:32768}),wasmMemory&&(buffer=wasmMemory.buffer),INITIAL_MEMORY=buffer.byteLength,updateGlobalBufferAndViews(buffer);var wasmTable=new WebAssembly.Table({initial:20,element:"anyfunc"}),__ATPRERUN__=[],__ATINIT__=[],__ATMAIN__=[],__ATPOSTRUN__=[],__RELOC_FUNCS__=[],runtimeInitialized=!1;function keepRuntimeAlive(){return noExitRuntime}function preRun(){if(Module.preRun)for("function"==typeof Module.preRun&&(Module.preRun=[Module.preRun]);Module.preRun.length;)addOnPreRun(Module.preRun.shift());callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=!0,callRuntimeCallbacks(__RELOC_FUNCS__),callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function postRun(){if(Module.postRun)for("function"==typeof Module.postRun&&(Module.postRun=[Module.postRun]);Module.postRun.length;)addOnPostRun(Module.postRun.shift());callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(e){__ATPRERUN__.unshift(e)}function addOnInit(e){__ATINIT__.unshift(e)}function addOnPostRun(e){__ATPOSTRUN__.unshift(e)}var runDependencies=0,runDependencyWatcher=null,dependenciesFulfilled=null;function addRunDependency(e){runDependencies++,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies)}function removeRunDependency(e){if(runDependencies--,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies),0==runDependencies&&(null!==runDependencyWatcher&&(clearInterval(runDependencyWatcher),runDependencyWatcher=null),dependenciesFulfilled)){var t=dependenciesFulfilled;dependenciesFulfilled=null,t()}}function abort(e){throw Module.onAbort&&Module.onAbort(e),err(e="Aborted("+e+")"),ABORT=!0,EXITSTATUS=1,e+=". Build with -sASSERTIONS for more info.",new WebAssembly.RuntimeError(e)}var dataURIPrefix="data:application/octet-stream;base64,",wasmBinaryFile,tempDouble,tempI64;function isDataURI(e){return e.startsWith(dataURIPrefix)}function isFileURI(e){return e.startsWith("file://")}function getBinary(e){try{if(e==wasmBinaryFile&&wasmBinary)return new Uint8Array(wasmBinary);if(readBinary)return readBinary(e);throw"both async and sync fetching of the wasm failed"}catch(e){abort(e)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if("function"==typeof fetch&&!isFileURI(wasmBinaryFile))return fetch(wasmBinaryFile,{credentials:"same-origin"}).then((function(e){if(!e.ok)throw"failed to load wasm binary file at '"+wasmBinaryFile+"'";return e.arrayBuffer()})).catch((function(){return getBinary(wasmBinaryFile)}));if(readAsync)return new Promise((function(e,t){readAsync(wasmBinaryFile,(function(t){e(new Uint8Array(t))}),t)}))}return Promise.resolve().then((function(){return getBinary(wasmBinaryFile)}))}function createWasm(){var e={env:asmLibraryArg,wasi_snapshot_preview1:asmLibraryArg,"GOT.mem":new Proxy(asmLibraryArg,GOTHandler),"GOT.func":new Proxy(asmLibraryArg,GOTHandler)};function t(e,t){var r=e.exports;r=relocateExports(r,1024);var _=getDylinkMetadata(t);_.neededDynlibs&&(dynamicLibraries=_.neededDynlibs.concat(dynamicLibraries)),mergeLibSymbols(r,"main"),Module.asm=r,addOnInit(Module.asm.__wasm_call_ctors),__RELOC_FUNCS__.push(Module.asm.__wasm_apply_data_relocs),removeRunDependency("wasm-instantiate")}function r(e){t(e.instance,e.module)}function _(t){return getBinaryPromise().then((function(t){return WebAssembly.instantiate(t,e)})).then((function(e){return e})).then(t,(function(e){err("failed to asynchronously prepare wasm: "+e),abort(e)}))}if(addRunDependency("wasm-instantiate"),Module.instantiateWasm)try{return Module.instantiateWasm(e,t)}catch(e){return err("Module.instantiateWasm callback failed with error: "+e),!1}return wasmBinary||"function"!=typeof WebAssembly.instantiateStreaming||isDataURI(wasmBinaryFile)||isFileURI(wasmBinaryFile)||ENVIRONMENT_IS_NODE||"function"!=typeof fetch?_(r):fetch(wasmBinaryFile,{credentials:"same-origin"}).then((function(t){return WebAssembly.instantiateStreaming(t,e).then(r,(function(e){return err("wasm streaming compile failed: "+e),err("falling back to ArrayBuffer instantiation"),_(r)}))})),{}}wasmBinaryFile="tree-sitter.wasm",isDataURI(wasmBinaryFile)||(wasmBinaryFile=locateFile(wasmBinaryFile));var ASM_CONSTS={};function ExitStatus(e){this.name="ExitStatus",this.message="Program terminated with exit("+e+")",this.status=e}var GOT={},CurrentModuleWeakSymbols=new Set([]),GOTHandler={get:function(e,t){var r=GOT[t];return r||(r=GOT[t]=new WebAssembly.Global({value:"i32",mutable:!0})),CurrentModuleWeakSymbols.has(t)||(r.required=!0),r}};function callRuntimeCallbacks(e){for(;e.length>0;)e.shift()(Module)}function getDylinkMetadata(e){var t=0,r=0;function _(){for(var r=0,_=1;;){var n=e[t++];if(r+=(127&n)*_,_*=128,!(128&n))break}return r}function n(){var r=_();return UTF8ArrayToString(e,(t+=r)-r,r)}function s(e,t){if(e)throw new Error(t)}var a="dylink.0";if(e instanceof WebAssembly.Module){var o=WebAssembly.Module.customSections(e,a);0===o.length&&(a="dylink",o=WebAssembly.Module.customSections(e,a)),s(0===o.length,"need dylink section"),r=(e=new Uint8Array(o[0])).length}else{s(!(1836278016==new Uint32Array(new Uint8Array(e.subarray(0,24)).buffer)[0]),"need to see wasm magic number"),s(0!==e[8],"need the dylink section to be first"),t=9;var i=_();r=t+i,a=n()}var l={neededDynlibs:[],tlsExports:new Set,weakImports:new Set};if("dylink"==a){l.memorySize=_(),l.memoryAlign=_(),l.tableSize=_(),l.tableAlign=_();for(var u=_(),d=0;d>0];case"i16":return HEAP16[e>>1];case"i32":case"i64":return HEAP32[e>>2];case"float":return HEAPF32[e>>2];case"double":return HEAPF64[e>>3];case"*":return HEAPU32[e>>2];default:abort("invalid type for getValue: "+t)}return null}function asmjsMangle(e){return 0==e.indexOf("dynCall_")||["stackAlloc","stackSave","stackRestore","getTempRet0","setTempRet0"].includes(e)?e:"_"+e}function mergeLibSymbols(e,t){for(var r in e)if(e.hasOwnProperty(r)){asmLibraryArg.hasOwnProperty(r)||(asmLibraryArg[r]=e[r]);var _=asmjsMangle(r);Module.hasOwnProperty(_)||(Module[_]=e[r]),"__main_argc_argv"==r&&(Module._main=e[r])}}var LDSO={loadedLibsByName:{},loadedLibsByHandle:{}};function dynCallLegacy(e,t,r){var _=Module["dynCall_"+e];return r&&r.length?_.apply(null,[t].concat(r)):_.call(null,t)}var wasmTableMirror=[];function getWasmTableEntry(e){var t=wasmTableMirror[e];return t||(e>=wasmTableMirror.length&&(wasmTableMirror.length=e+1),wasmTableMirror[e]=t=wasmTable.get(e)),t}function dynCall(e,t,r){return e.includes("j")?dynCallLegacy(e,t,r):getWasmTableEntry(t).apply(null,r)}function createInvokeFunction(e){return function(){var t=stackSave();try{return dynCall(e,arguments[0],Array.prototype.slice.call(arguments,1))}catch(e){if(stackRestore(t),e!==e+0)throw e;_setThrew(1,0)}}}var ___heap_base=78144;function zeroMemory(e,t){return HEAPU8.fill(0,e,e+t),e}function getMemory(e){if(runtimeInitialized)return zeroMemory(_malloc(e),e);var t=___heap_base,r=t+e+15&-16;return ___heap_base=r,GOT.__heap_base.value=r,t}function isInternalSym(e){return["__cpp_exception","__c_longjmp","__wasm_apply_data_relocs","__dso_handle","__tls_size","__tls_align","__set_stack_limits","_emscripten_tls_init","__wasm_init_tls","__wasm_call_ctors","__start_em_asm","__stop_em_asm"].includes(e)}function uleb128Encode(e,t){e<128?t.push(e):t.push(e%128|128,e>>7)}function sigToWasmTypes(e){for(var t={i:"i32",j:"i32",f:"f32",d:"f64",p:"i32"},r={parameters:[],results:"v"==e[0]?[]:[t[e[0]]]},_=1;_>0];if(firstLoad){var memAlign=Math.pow(2,metadata.memoryAlign);memAlign=Math.max(memAlign,STACK_ALIGN);var memoryBase=metadata.memorySize?alignMemory(getMemory(metadata.memorySize+memAlign),memAlign):0,tableBase=metadata.tableSize?wasmTable.length:0;handle&&(HEAP8[handle+12>>0]=1,HEAPU32[handle+16>>2]=memoryBase,HEAP32[handle+20>>2]=metadata.memorySize,HEAPU32[handle+24>>2]=tableBase,HEAP32[handle+28>>2]=metadata.tableSize)}else memoryBase=HEAPU32[handle+16>>2],tableBase=HEAPU32[handle+24>>2];var tableGrowthNeeded=tableBase+metadata.tableSize-wasmTable.length,moduleExports;function resolveSymbol(e){var t=resolveGlobalSymbol(e,!1);return t||(t=moduleExports[e]),t}tableGrowthNeeded>0&&wasmTable.grow(tableGrowthNeeded);var proxyHandler={get:function(e,t){switch(t){case"__memory_base":return memoryBase;case"__table_base":return tableBase}if(t in asmLibraryArg)return asmLibraryArg[t];var r;t in e||(e[t]=function(){return r||(r=resolveSymbol(t)),r.apply(null,arguments)});return e[t]}},proxy=new Proxy({},proxyHandler),info={"GOT.mem":new Proxy({},GOTHandler),"GOT.func":new Proxy({},GOTHandler),env:proxy,wasi_snapshot_preview1:proxy};function postInstantiation(instance){function addEmAsm(addr,body){for(var args=[],arity=0;arity<16&&-1!=body.indexOf("$"+arity);arity++)args.push("$"+arity);args=args.join(",");var func="("+args+" ) => { "+body+"};";ASM_CONSTS[start]=eval(func)}if(updateTableMap(tableBase,metadata.tableSize),moduleExports=relocateExports(instance.exports,memoryBase),flags.allowUndefined||reportUndefinedSymbols(),"__start_em_asm"in moduleExports)for(var start=moduleExports.__start_em_asm,stop=moduleExports.__stop_em_asm;startt(new Uint8Array(e))),r)}));if(!readBinary)throw new Error(e+": file not found, and synchronous loading of external files is not available");return readBinary(e)}function s(){if("undefined"!=typeof preloadedWasm&&preloadedWasm[e]){var _=preloadedWasm[e];return t.loadAsync?Promise.resolve(_):_}return t.loadAsync?n(e).then((function(e){return loadWebAssemblyModule(e,t,r)})):loadWebAssemblyModule(n(e),t,r)}function a(t){_.global&&mergeLibSymbols(t,e),_.module=t}return _={refcount:t.nodelete?1/0:1,name:e,module:"loading",global:t.global},LDSO.loadedLibsByName[e]=_,r&&(LDSO.loadedLibsByHandle[r]=_),t.loadAsync?s().then((function(e){return a(e),!0})):(a(s()),!0)}function reportUndefinedSymbols(){for(var e in GOT)if(0==GOT[e].value){var t=resolveGlobalSymbol(e,!0);if(!t&&!GOT[e].required)continue;if("function"==typeof t)GOT[e].value=addFunction(t,t.sig);else{if("number"!=typeof t)throw new Error("bad export type for `"+e+"`: "+typeof t);GOT[e].value=t}}}function preloadDylibs(){dynamicLibraries.length?(addRunDependency("preloadDylibs"),dynamicLibraries.reduce((function(e,t){return e.then((function(){return loadDynamicLibrary(t,{loadAsync:!0,global:!0,nodelete:!0,allowUndefined:!0})}))}),Promise.resolve()).then((function(){reportUndefinedSymbols(),removeRunDependency("preloadDylibs")}))):reportUndefinedSymbols()}function setValue(e,t,r="i8"){switch(r.endsWith("*")&&(r="*"),r){case"i1":case"i8":HEAP8[e>>0]=t;break;case"i16":HEAP16[e>>1]=t;break;case"i32":HEAP32[e>>2]=t;break;case"i64":tempI64=[t>>>0,(tempDouble=t,+Math.abs(tempDouble)>=1?tempDouble>0?(0|Math.min(+Math.floor(tempDouble/4294967296),4294967295))>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[e>>2]=tempI64[0],HEAP32[e+4>>2]=tempI64[1];break;case"float":HEAPF32[e>>2]=t;break;case"double":HEAPF64[e>>3]=t;break;case"*":HEAPU32[e>>2]=t;break;default:abort("invalid type for setValue: "+r)}}var ___memory_base=new WebAssembly.Global({value:"i32",mutable:!1},1024),___stack_pointer=new WebAssembly.Global({value:"i32",mutable:!0},78144),___table_base=new WebAssembly.Global({value:"i32",mutable:!1},1),nowIsMonotonic=!0,_emscripten_get_now;function __emscripten_get_now_is_monotonic(){return nowIsMonotonic}function _abort(){abort("")}function _emscripten_date_now(){return Date.now()}function _emscripten_memcpy_big(e,t,r){HEAPU8.copyWithin(e,t,t+r)}function getHeapMax(){return 2147483648}function emscripten_realloc_buffer(e){try{return wasmMemory.grow(e-buffer.byteLength+65535>>>16),updateGlobalBufferAndViews(wasmMemory.buffer),1}catch(e){}}function _emscripten_resize_heap(e){var t=HEAPU8.length;e>>>=0;var r=getHeapMax();if(e>r)return!1;for(var _=1;_<=4;_*=2){var n=t*(1+.2/_);if(n=Math.min(n,e+100663296),emscripten_realloc_buffer(Math.min(r,(s=Math.max(e,n))+((a=65536)-s%a)%a)))return!0}var s,a;return!1}__emscripten_get_now_is_monotonic.sig="i",Module._abort=_abort,_abort.sig="v",_emscripten_date_now.sig="d",_emscripten_get_now=ENVIRONMENT_IS_NODE?()=>{var e=process.hrtime();return 1e3*e[0]+e[1]/1e6}:()=>performance.now(),_emscripten_get_now.sig="d",_emscripten_memcpy_big.sig="vppp",_emscripten_resize_heap.sig="ip";var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt:function(e,t,r){if(PATH.isAbs(t))return t;var _;-100===e?_=FS.cwd():_=SYSCALLS.getStreamFromFD(e).path;if(0==t.length){if(!r)throw new FS.ErrnoError(44);return _}return PATH.join2(_,t)},doStat:function(e,t,r){try{var _=e(t)}catch(e){if(e&&e.node&&PATH.normalize(t)!==PATH.normalize(FS.getPath(e.node)))return-54;throw e}HEAP32[r>>2]=_.dev,HEAP32[r+8>>2]=_.ino,HEAP32[r+12>>2]=_.mode,HEAPU32[r+16>>2]=_.nlink,HEAP32[r+20>>2]=_.uid,HEAP32[r+24>>2]=_.gid,HEAP32[r+28>>2]=_.rdev,tempI64=[_.size>>>0,(tempDouble=_.size,+Math.abs(tempDouble)>=1?tempDouble>0?(0|Math.min(+Math.floor(tempDouble/4294967296),4294967295))>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[r+40>>2]=tempI64[0],HEAP32[r+44>>2]=tempI64[1],HEAP32[r+48>>2]=4096,HEAP32[r+52>>2]=_.blocks;var n=_.atime.getTime(),s=_.mtime.getTime(),a=_.ctime.getTime();return tempI64=[Math.floor(n/1e3)>>>0,(tempDouble=Math.floor(n/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?(0|Math.min(+Math.floor(tempDouble/4294967296),4294967295))>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[r+56>>2]=tempI64[0],HEAP32[r+60>>2]=tempI64[1],HEAPU32[r+64>>2]=n%1e3*1e3,tempI64=[Math.floor(s/1e3)>>>0,(tempDouble=Math.floor(s/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?(0|Math.min(+Math.floor(tempDouble/4294967296),4294967295))>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[r+72>>2]=tempI64[0],HEAP32[r+76>>2]=tempI64[1],HEAPU32[r+80>>2]=s%1e3*1e3,tempI64=[Math.floor(a/1e3)>>>0,(tempDouble=Math.floor(a/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?(0|Math.min(+Math.floor(tempDouble/4294967296),4294967295))>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[r+88>>2]=tempI64[0],HEAP32[r+92>>2]=tempI64[1],HEAPU32[r+96>>2]=a%1e3*1e3,tempI64=[_.ino>>>0,(tempDouble=_.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(0|Math.min(+Math.floor(tempDouble/4294967296),4294967295))>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[r+104>>2]=tempI64[0],HEAP32[r+108>>2]=tempI64[1],0},doMsync:function(e,t,r,_,n){if(!FS.isFile(t.node.mode))throw new FS.ErrnoError(43);if(2&_)return 0;var s=HEAPU8.slice(e,e+r);FS.msync(t,s,n,r,_)},varargs:void 0,get:function(){return SYSCALLS.varargs+=4,HEAP32[SYSCALLS.varargs-4>>2]},getStr:function(e){return UTF8ToString(e)},getStreamFromFD:function(e){var t=FS.getStream(e);if(!t)throw new FS.ErrnoError(8);return t}};function _proc_exit(e){EXITSTATUS=e,keepRuntimeAlive()||(Module.onExit&&Module.onExit(e),ABORT=!0),quit_(e,new ExitStatus(e))}function exitJS(e,t){EXITSTATUS=e,_proc_exit(e)}_proc_exit.sig="vi";var _exit=exitJS;function _fd_close(e){try{var t=SYSCALLS.getStreamFromFD(e);return FS.close(t),0}catch(e){if("undefined"==typeof FS||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function convertI32PairToI53Checked(e,t){return t+2097152>>>0<4194305-!!e?(e>>>0)+4294967296*t:NaN}function _fd_seek(e,t,r,_,n){try{var s=convertI32PairToI53Checked(t,r);if(isNaN(s))return 61;var a=SYSCALLS.getStreamFromFD(e);return FS.llseek(a,s,_),tempI64=[a.position>>>0,(tempDouble=a.position,+Math.abs(tempDouble)>=1?tempDouble>0?(0|Math.min(+Math.floor(tempDouble/4294967296),4294967295))>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[n>>2]=tempI64[0],HEAP32[n+4>>2]=tempI64[1],a.getdents&&0===s&&0===_&&(a.getdents=null),0}catch(e){if("undefined"==typeof FS||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function doWritev(e,t,r,_){for(var n=0,s=0;s>2],o=HEAPU32[t+4>>2];t+=8;var i=FS.write(e,HEAP8,a,o,_);if(i<0)return-1;n+=i,void 0!==_&&(_+=i)}return n}function _fd_write(e,t,r,_){try{var n=doWritev(SYSCALLS.getStreamFromFD(e),t,r);return HEAPU32[_>>2]=n,0}catch(e){if("undefined"==typeof FS||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function _tree_sitter_log_callback(e,t){if(currentLogCallback){const r=UTF8ToString(t);currentLogCallback(r,0!==e)}}function _tree_sitter_parse_callback(e,t,r,_,n){var s=currentParseCallback(t,{row:r,column:_});"string"==typeof s?(setValue(n,s.length,"i32"),stringToUTF16(s,e,10240)):setValue(n,0,"i32")}function handleException(e){if(e instanceof ExitStatus||"unwind"==e)return EXITSTATUS;quit_(1,e)}function allocateUTF8OnStack(e){var t=lengthBytesUTF8(e)+1,r=stackAlloc(t);return stringToUTF8Array(e,HEAP8,r,t),r}function stringToUTF16(e,t,r){if(void 0===r&&(r=2147483647),r<2)return 0;for(var _=t,n=(r-=2)<2*e.length?r/2:e.length,s=0;s>1]=a,t+=2}return HEAP16[t>>1]=0,t-_}function AsciiToString(e){for(var t="";;){var r=HEAPU8[e++>>0];if(!r)return t;t+=String.fromCharCode(r)}}_exit.sig="vi",_fd_close.sig="ii",_fd_seek.sig="iijip",_fd_write.sig="iippp";var asmLibraryArg={__heap_base:___heap_base,__indirect_function_table:wasmTable,__memory_base:___memory_base,__stack_pointer:___stack_pointer,__table_base:___table_base,_emscripten_get_now_is_monotonic:__emscripten_get_now_is_monotonic,abort:_abort,emscripten_get_now:_emscripten_get_now,emscripten_memcpy_big:_emscripten_memcpy_big,emscripten_resize_heap:_emscripten_resize_heap,exit:_exit,fd_close:_fd_close,fd_seek:_fd_seek,fd_write:_fd_write,memory:wasmMemory,tree_sitter_log_callback:_tree_sitter_log_callback,tree_sitter_parse_callback:_tree_sitter_parse_callback},asm=createWasm(),___wasm_call_ctors=Module.___wasm_call_ctors=function(){return(___wasm_call_ctors=Module.___wasm_call_ctors=Module.asm.__wasm_call_ctors).apply(null,arguments)},___wasm_apply_data_relocs=Module.___wasm_apply_data_relocs=function(){return(___wasm_apply_data_relocs=Module.___wasm_apply_data_relocs=Module.asm.__wasm_apply_data_relocs).apply(null,arguments)},_malloc=Module._malloc=function(){return(_malloc=Module._malloc=Module.asm.malloc).apply(null,arguments)},_calloc=Module._calloc=function(){return(_calloc=Module._calloc=Module.asm.calloc).apply(null,arguments)},_realloc=Module._realloc=function(){return(_realloc=Module._realloc=Module.asm.realloc).apply(null,arguments)},_free=Module._free=function(){return(_free=Module._free=Module.asm.free).apply(null,arguments)},_ts_language_symbol_count=Module._ts_language_symbol_count=function(){return(_ts_language_symbol_count=Module._ts_language_symbol_count=Module.asm.ts_language_symbol_count).apply(null,arguments)},_ts_language_version=Module._ts_language_version=function(){return(_ts_language_version=Module._ts_language_version=Module.asm.ts_language_version).apply(null,arguments)},_ts_language_field_count=Module._ts_language_field_count=function(){return(_ts_language_field_count=Module._ts_language_field_count=Module.asm.ts_language_field_count).apply(null,arguments)},_ts_language_symbol_name=Module._ts_language_symbol_name=function(){return(_ts_language_symbol_name=Module._ts_language_symbol_name=Module.asm.ts_language_symbol_name).apply(null,arguments)},_ts_language_symbol_for_name=Module._ts_language_symbol_for_name=function(){return(_ts_language_symbol_for_name=Module._ts_language_symbol_for_name=Module.asm.ts_language_symbol_for_name).apply(null,arguments)},_ts_language_symbol_type=Module._ts_language_symbol_type=function(){return(_ts_language_symbol_type=Module._ts_language_symbol_type=Module.asm.ts_language_symbol_type).apply(null,arguments)},_ts_language_field_name_for_id=Module._ts_language_field_name_for_id=function(){return(_ts_language_field_name_for_id=Module._ts_language_field_name_for_id=Module.asm.ts_language_field_name_for_id).apply(null,arguments)},_memset=Module._memset=function(){return(_memset=Module._memset=Module.asm.memset).apply(null,arguments)},_memcpy=Module._memcpy=function(){return(_memcpy=Module._memcpy=Module.asm.memcpy).apply(null,arguments)},_ts_parser_delete=Module._ts_parser_delete=function(){return(_ts_parser_delete=Module._ts_parser_delete=Module.asm.ts_parser_delete).apply(null,arguments)},_ts_parser_reset=Module._ts_parser_reset=function(){return(_ts_parser_reset=Module._ts_parser_reset=Module.asm.ts_parser_reset).apply(null,arguments)},_ts_parser_set_language=Module._ts_parser_set_language=function(){return(_ts_parser_set_language=Module._ts_parser_set_language=Module.asm.ts_parser_set_language).apply(null,arguments)},_ts_parser_timeout_micros=Module._ts_parser_timeout_micros=function(){return(_ts_parser_timeout_micros=Module._ts_parser_timeout_micros=Module.asm.ts_parser_timeout_micros).apply(null,arguments)},_ts_parser_set_timeout_micros=Module._ts_parser_set_timeout_micros=function(){return(_ts_parser_set_timeout_micros=Module._ts_parser_set_timeout_micros=Module.asm.ts_parser_set_timeout_micros).apply(null,arguments)},_memmove=Module._memmove=function(){return(_memmove=Module._memmove=Module.asm.memmove).apply(null,arguments)},_memcmp=Module._memcmp=function(){return(_memcmp=Module._memcmp=Module.asm.memcmp).apply(null,arguments)},_ts_query_new=Module._ts_query_new=function(){return(_ts_query_new=Module._ts_query_new=Module.asm.ts_query_new).apply(null,arguments)},_ts_query_delete=Module._ts_query_delete=function(){return(_ts_query_delete=Module._ts_query_delete=Module.asm.ts_query_delete).apply(null,arguments)},_iswspace=Module._iswspace=function(){return(_iswspace=Module._iswspace=Module.asm.iswspace).apply(null,arguments)},_iswalnum=Module._iswalnum=function(){return(_iswalnum=Module._iswalnum=Module.asm.iswalnum).apply(null,arguments)},_ts_query_pattern_count=Module._ts_query_pattern_count=function(){return(_ts_query_pattern_count=Module._ts_query_pattern_count=Module.asm.ts_query_pattern_count).apply(null,arguments)},_ts_query_capture_count=Module._ts_query_capture_count=function(){return(_ts_query_capture_count=Module._ts_query_capture_count=Module.asm.ts_query_capture_count).apply(null,arguments)},_ts_query_string_count=Module._ts_query_string_count=function(){return(_ts_query_string_count=Module._ts_query_string_count=Module.asm.ts_query_string_count).apply(null,arguments)},_ts_query_capture_name_for_id=Module._ts_query_capture_name_for_id=function(){return(_ts_query_capture_name_for_id=Module._ts_query_capture_name_for_id=Module.asm.ts_query_capture_name_for_id).apply(null,arguments)},_ts_query_string_value_for_id=Module._ts_query_string_value_for_id=function(){return(_ts_query_string_value_for_id=Module._ts_query_string_value_for_id=Module.asm.ts_query_string_value_for_id).apply(null,arguments)},_ts_query_predicates_for_pattern=Module._ts_query_predicates_for_pattern=function(){return(_ts_query_predicates_for_pattern=Module._ts_query_predicates_for_pattern=Module.asm.ts_query_predicates_for_pattern).apply(null,arguments)},_ts_tree_copy=Module._ts_tree_copy=function(){return(_ts_tree_copy=Module._ts_tree_copy=Module.asm.ts_tree_copy).apply(null,arguments)},_ts_tree_delete=Module._ts_tree_delete=function(){return(_ts_tree_delete=Module._ts_tree_delete=Module.asm.ts_tree_delete).apply(null,arguments)},_ts_init=Module._ts_init=function(){return(_ts_init=Module._ts_init=Module.asm.ts_init).apply(null,arguments)},_ts_parser_new_wasm=Module._ts_parser_new_wasm=function(){return(_ts_parser_new_wasm=Module._ts_parser_new_wasm=Module.asm.ts_parser_new_wasm).apply(null,arguments)},_ts_parser_enable_logger_wasm=Module._ts_parser_enable_logger_wasm=function(){return(_ts_parser_enable_logger_wasm=Module._ts_parser_enable_logger_wasm=Module.asm.ts_parser_enable_logger_wasm).apply(null,arguments)},_ts_parser_parse_wasm=Module._ts_parser_parse_wasm=function(){return(_ts_parser_parse_wasm=Module._ts_parser_parse_wasm=Module.asm.ts_parser_parse_wasm).apply(null,arguments)},_ts_language_type_is_named_wasm=Module._ts_language_type_is_named_wasm=function(){return(_ts_language_type_is_named_wasm=Module._ts_language_type_is_named_wasm=Module.asm.ts_language_type_is_named_wasm).apply(null,arguments)},_ts_language_type_is_visible_wasm=Module._ts_language_type_is_visible_wasm=function(){return(_ts_language_type_is_visible_wasm=Module._ts_language_type_is_visible_wasm=Module.asm.ts_language_type_is_visible_wasm).apply(null,arguments)},_ts_tree_root_node_wasm=Module._ts_tree_root_node_wasm=function(){return(_ts_tree_root_node_wasm=Module._ts_tree_root_node_wasm=Module.asm.ts_tree_root_node_wasm).apply(null,arguments)},_ts_tree_edit_wasm=Module._ts_tree_edit_wasm=function(){return(_ts_tree_edit_wasm=Module._ts_tree_edit_wasm=Module.asm.ts_tree_edit_wasm).apply(null,arguments)},_ts_tree_get_changed_ranges_wasm=Module._ts_tree_get_changed_ranges_wasm=function(){return(_ts_tree_get_changed_ranges_wasm=Module._ts_tree_get_changed_ranges_wasm=Module.asm.ts_tree_get_changed_ranges_wasm).apply(null,arguments)},_ts_tree_cursor_new_wasm=Module._ts_tree_cursor_new_wasm=function(){return(_ts_tree_cursor_new_wasm=Module._ts_tree_cursor_new_wasm=Module.asm.ts_tree_cursor_new_wasm).apply(null,arguments)},_ts_tree_cursor_delete_wasm=Module._ts_tree_cursor_delete_wasm=function(){return(_ts_tree_cursor_delete_wasm=Module._ts_tree_cursor_delete_wasm=Module.asm.ts_tree_cursor_delete_wasm).apply(null,arguments)},_ts_tree_cursor_reset_wasm=Module._ts_tree_cursor_reset_wasm=function(){return(_ts_tree_cursor_reset_wasm=Module._ts_tree_cursor_reset_wasm=Module.asm.ts_tree_cursor_reset_wasm).apply(null,arguments)},_ts_tree_cursor_goto_first_child_wasm=Module._ts_tree_cursor_goto_first_child_wasm=function(){return(_ts_tree_cursor_goto_first_child_wasm=Module._ts_tree_cursor_goto_first_child_wasm=Module.asm.ts_tree_cursor_goto_first_child_wasm).apply(null,arguments)},_ts_tree_cursor_goto_next_sibling_wasm=Module._ts_tree_cursor_goto_next_sibling_wasm=function(){return(_ts_tree_cursor_goto_next_sibling_wasm=Module._ts_tree_cursor_goto_next_sibling_wasm=Module.asm.ts_tree_cursor_goto_next_sibling_wasm).apply(null,arguments)},_ts_tree_cursor_goto_parent_wasm=Module._ts_tree_cursor_goto_parent_wasm=function(){return(_ts_tree_cursor_goto_parent_wasm=Module._ts_tree_cursor_goto_parent_wasm=Module.asm.ts_tree_cursor_goto_parent_wasm).apply(null,arguments)},_ts_tree_cursor_current_node_type_id_wasm=Module._ts_tree_cursor_current_node_type_id_wasm=function(){return(_ts_tree_cursor_current_node_type_id_wasm=Module._ts_tree_cursor_current_node_type_id_wasm=Module.asm.ts_tree_cursor_current_node_type_id_wasm).apply(null,arguments)},_ts_tree_cursor_current_node_is_named_wasm=Module._ts_tree_cursor_current_node_is_named_wasm=function(){return(_ts_tree_cursor_current_node_is_named_wasm=Module._ts_tree_cursor_current_node_is_named_wasm=Module.asm.ts_tree_cursor_current_node_is_named_wasm).apply(null,arguments)},_ts_tree_cursor_current_node_is_missing_wasm=Module._ts_tree_cursor_current_node_is_missing_wasm=function(){return(_ts_tree_cursor_current_node_is_missing_wasm=Module._ts_tree_cursor_current_node_is_missing_wasm=Module.asm.ts_tree_cursor_current_node_is_missing_wasm).apply(null,arguments)},_ts_tree_cursor_current_node_id_wasm=Module._ts_tree_cursor_current_node_id_wasm=function(){return(_ts_tree_cursor_current_node_id_wasm=Module._ts_tree_cursor_current_node_id_wasm=Module.asm.ts_tree_cursor_current_node_id_wasm).apply(null,arguments)},_ts_tree_cursor_start_position_wasm=Module._ts_tree_cursor_start_position_wasm=function(){return(_ts_tree_cursor_start_position_wasm=Module._ts_tree_cursor_start_position_wasm=Module.asm.ts_tree_cursor_start_position_wasm).apply(null,arguments)},_ts_tree_cursor_end_position_wasm=Module._ts_tree_cursor_end_position_wasm=function(){return(_ts_tree_cursor_end_position_wasm=Module._ts_tree_cursor_end_position_wasm=Module.asm.ts_tree_cursor_end_position_wasm).apply(null,arguments)},_ts_tree_cursor_start_index_wasm=Module._ts_tree_cursor_start_index_wasm=function(){return(_ts_tree_cursor_start_index_wasm=Module._ts_tree_cursor_start_index_wasm=Module.asm.ts_tree_cursor_start_index_wasm).apply(null,arguments)},_ts_tree_cursor_end_index_wasm=Module._ts_tree_cursor_end_index_wasm=function(){return(_ts_tree_cursor_end_index_wasm=Module._ts_tree_cursor_end_index_wasm=Module.asm.ts_tree_cursor_end_index_wasm).apply(null,arguments)},_ts_tree_cursor_current_field_id_wasm=Module._ts_tree_cursor_current_field_id_wasm=function(){return(_ts_tree_cursor_current_field_id_wasm=Module._ts_tree_cursor_current_field_id_wasm=Module.asm.ts_tree_cursor_current_field_id_wasm).apply(null,arguments)},_ts_tree_cursor_current_node_wasm=Module._ts_tree_cursor_current_node_wasm=function(){return(_ts_tree_cursor_current_node_wasm=Module._ts_tree_cursor_current_node_wasm=Module.asm.ts_tree_cursor_current_node_wasm).apply(null,arguments)},_ts_node_symbol_wasm=Module._ts_node_symbol_wasm=function(){return(_ts_node_symbol_wasm=Module._ts_node_symbol_wasm=Module.asm.ts_node_symbol_wasm).apply(null,arguments)},_ts_node_child_count_wasm=Module._ts_node_child_count_wasm=function(){return(_ts_node_child_count_wasm=Module._ts_node_child_count_wasm=Module.asm.ts_node_child_count_wasm).apply(null,arguments)},_ts_node_named_child_count_wasm=Module._ts_node_named_child_count_wasm=function(){return(_ts_node_named_child_count_wasm=Module._ts_node_named_child_count_wasm=Module.asm.ts_node_named_child_count_wasm).apply(null,arguments)},_ts_node_child_wasm=Module._ts_node_child_wasm=function(){return(_ts_node_child_wasm=Module._ts_node_child_wasm=Module.asm.ts_node_child_wasm).apply(null,arguments)},_ts_node_named_child_wasm=Module._ts_node_named_child_wasm=function(){return(_ts_node_named_child_wasm=Module._ts_node_named_child_wasm=Module.asm.ts_node_named_child_wasm).apply(null,arguments)},_ts_node_child_by_field_id_wasm=Module._ts_node_child_by_field_id_wasm=function(){return(_ts_node_child_by_field_id_wasm=Module._ts_node_child_by_field_id_wasm=Module.asm.ts_node_child_by_field_id_wasm).apply(null,arguments)},_ts_node_next_sibling_wasm=Module._ts_node_next_sibling_wasm=function(){return(_ts_node_next_sibling_wasm=Module._ts_node_next_sibling_wasm=Module.asm.ts_node_next_sibling_wasm).apply(null,arguments)},_ts_node_prev_sibling_wasm=Module._ts_node_prev_sibling_wasm=function(){return(_ts_node_prev_sibling_wasm=Module._ts_node_prev_sibling_wasm=Module.asm.ts_node_prev_sibling_wasm).apply(null,arguments)},_ts_node_next_named_sibling_wasm=Module._ts_node_next_named_sibling_wasm=function(){return(_ts_node_next_named_sibling_wasm=Module._ts_node_next_named_sibling_wasm=Module.asm.ts_node_next_named_sibling_wasm).apply(null,arguments)},_ts_node_prev_named_sibling_wasm=Module._ts_node_prev_named_sibling_wasm=function(){return(_ts_node_prev_named_sibling_wasm=Module._ts_node_prev_named_sibling_wasm=Module.asm.ts_node_prev_named_sibling_wasm).apply(null,arguments)},_ts_node_parent_wasm=Module._ts_node_parent_wasm=function(){return(_ts_node_parent_wasm=Module._ts_node_parent_wasm=Module.asm.ts_node_parent_wasm).apply(null,arguments)},_ts_node_descendant_for_index_wasm=Module._ts_node_descendant_for_index_wasm=function(){return(_ts_node_descendant_for_index_wasm=Module._ts_node_descendant_for_index_wasm=Module.asm.ts_node_descendant_for_index_wasm).apply(null,arguments)},_ts_node_named_descendant_for_index_wasm=Module._ts_node_named_descendant_for_index_wasm=function(){return(_ts_node_named_descendant_for_index_wasm=Module._ts_node_named_descendant_for_index_wasm=Module.asm.ts_node_named_descendant_for_index_wasm).apply(null,arguments)},_ts_node_descendant_for_position_wasm=Module._ts_node_descendant_for_position_wasm=function(){return(_ts_node_descendant_for_position_wasm=Module._ts_node_descendant_for_position_wasm=Module.asm.ts_node_descendant_for_position_wasm).apply(null,arguments)},_ts_node_named_descendant_for_position_wasm=Module._ts_node_named_descendant_for_position_wasm=function(){return(_ts_node_named_descendant_for_position_wasm=Module._ts_node_named_descendant_for_position_wasm=Module.asm.ts_node_named_descendant_for_position_wasm).apply(null,arguments)},_ts_node_start_point_wasm=Module._ts_node_start_point_wasm=function(){return(_ts_node_start_point_wasm=Module._ts_node_start_point_wasm=Module.asm.ts_node_start_point_wasm).apply(null,arguments)},_ts_node_end_point_wasm=Module._ts_node_end_point_wasm=function(){return(_ts_node_end_point_wasm=Module._ts_node_end_point_wasm=Module.asm.ts_node_end_point_wasm).apply(null,arguments)},_ts_node_start_index_wasm=Module._ts_node_start_index_wasm=function(){return(_ts_node_start_index_wasm=Module._ts_node_start_index_wasm=Module.asm.ts_node_start_index_wasm).apply(null,arguments)},_ts_node_end_index_wasm=Module._ts_node_end_index_wasm=function(){return(_ts_node_end_index_wasm=Module._ts_node_end_index_wasm=Module.asm.ts_node_end_index_wasm).apply(null,arguments)},_ts_node_to_string_wasm=Module._ts_node_to_string_wasm=function(){return(_ts_node_to_string_wasm=Module._ts_node_to_string_wasm=Module.asm.ts_node_to_string_wasm).apply(null,arguments)},_ts_node_children_wasm=Module._ts_node_children_wasm=function(){return(_ts_node_children_wasm=Module._ts_node_children_wasm=Module.asm.ts_node_children_wasm).apply(null,arguments)},_ts_node_named_children_wasm=Module._ts_node_named_children_wasm=function(){return(_ts_node_named_children_wasm=Module._ts_node_named_children_wasm=Module.asm.ts_node_named_children_wasm).apply(null,arguments)},_ts_node_descendants_of_type_wasm=Module._ts_node_descendants_of_type_wasm=function(){return(_ts_node_descendants_of_type_wasm=Module._ts_node_descendants_of_type_wasm=Module.asm.ts_node_descendants_of_type_wasm).apply(null,arguments)},_ts_node_is_named_wasm=Module._ts_node_is_named_wasm=function(){return(_ts_node_is_named_wasm=Module._ts_node_is_named_wasm=Module.asm.ts_node_is_named_wasm).apply(null,arguments)},_ts_node_has_changes_wasm=Module._ts_node_has_changes_wasm=function(){return(_ts_node_has_changes_wasm=Module._ts_node_has_changes_wasm=Module.asm.ts_node_has_changes_wasm).apply(null,arguments)},_ts_node_has_error_wasm=Module._ts_node_has_error_wasm=function(){return(_ts_node_has_error_wasm=Module._ts_node_has_error_wasm=Module.asm.ts_node_has_error_wasm).apply(null,arguments)},_ts_node_is_missing_wasm=Module._ts_node_is_missing_wasm=function(){return(_ts_node_is_missing_wasm=Module._ts_node_is_missing_wasm=Module.asm.ts_node_is_missing_wasm).apply(null,arguments)},_ts_query_matches_wasm=Module._ts_query_matches_wasm=function(){return(_ts_query_matches_wasm=Module._ts_query_matches_wasm=Module.asm.ts_query_matches_wasm).apply(null,arguments)},_ts_query_captures_wasm=Module._ts_query_captures_wasm=function(){return(_ts_query_captures_wasm=Module._ts_query_captures_wasm=Module.asm.ts_query_captures_wasm).apply(null,arguments)},___cxa_atexit=Module.___cxa_atexit=function(){return(___cxa_atexit=Module.___cxa_atexit=Module.asm.__cxa_atexit).apply(null,arguments)},_iswdigit=Module._iswdigit=function(){return(_iswdigit=Module._iswdigit=Module.asm.iswdigit).apply(null,arguments)},_iswalpha=Module._iswalpha=function(){return(_iswalpha=Module._iswalpha=Module.asm.iswalpha).apply(null,arguments)},_iswlower=Module._iswlower=function(){return(_iswlower=Module._iswlower=Module.asm.iswlower).apply(null,arguments)},_memchr=Module._memchr=function(){return(_memchr=Module._memchr=Module.asm.memchr).apply(null,arguments)},_strlen=Module._strlen=function(){return(_strlen=Module._strlen=Module.asm.strlen).apply(null,arguments)},_towupper=Module._towupper=function(){return(_towupper=Module._towupper=Module.asm.towupper).apply(null,arguments)},_setThrew=Module._setThrew=function(){return(_setThrew=Module._setThrew=Module.asm.setThrew).apply(null,arguments)},stackSave=Module.stackSave=function(){return(stackSave=Module.stackSave=Module.asm.stackSave).apply(null,arguments)},stackRestore=Module.stackRestore=function(){return(stackRestore=Module.stackRestore=Module.asm.stackRestore).apply(null,arguments)},stackAlloc=Module.stackAlloc=function(){return(stackAlloc=Module.stackAlloc=Module.asm.stackAlloc).apply(null,arguments)},__Znwm=Module.__Znwm=function(){return(__Znwm=Module.__Znwm=Module.asm._Znwm).apply(null,arguments)},__ZdlPv=Module.__ZdlPv=function(){return(__ZdlPv=Module.__ZdlPv=Module.asm._ZdlPv).apply(null,arguments)},__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev=Module.__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev=function(){return(__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev=Module.__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev=Module.asm._ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev).apply(null,arguments)},__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__grow_byEmmmmmm=Module.__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__grow_byEmmmmmm=function(){return(__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__grow_byEmmmmmm=Module.__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__grow_byEmmmmmm=Module.asm._ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__grow_byEmmmmmm).apply(null,arguments)},__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcm=Module.__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcm=function(){return(__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcm=Module.__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcm=Module.asm._ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcm).apply(null,arguments)},__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEm=Module.__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEm=function(){return(__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEm=Module.__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEm=Module.asm._ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEm).apply(null,arguments)},__ZNKSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4copyEPcmm=Module.__ZNKSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4copyEPcmm=function(){return(__ZNKSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4copyEPcmm=Module.__ZNKSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4copyEPcmm=Module.asm._ZNKSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4copyEPcmm).apply(null,arguments)},__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9push_backEc=Module.__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9push_backEc=function(){return(__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9push_backEc=Module.__ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9push_backEc=Module.asm._ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9push_backEc).apply(null,arguments)},__ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEED2Ev=Module.__ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEED2Ev=function(){return(__ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEED2Ev=Module.__ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEED2Ev=Module.asm._ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEED2Ev).apply(null,arguments)},__ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9push_backEw=Module.__ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9push_backEw=function(){return(__ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9push_backEw=Module.__ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9push_backEw=Module.asm._ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9push_backEw).apply(null,arguments)},__ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6resizeEmw=Module.__ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6resizeEmw=function(){return(__ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6resizeEmw=Module.__ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6resizeEmw=Module.asm._ZNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6resizeEmw).apply(null,arguments)},dynCall_jiji=Module.dynCall_jiji=function(){return(dynCall_jiji=Module.dynCall_jiji=Module.asm.dynCall_jiji).apply(null,arguments)},_orig$ts_parser_timeout_micros=Module._orig$ts_parser_timeout_micros=function(){return(_orig$ts_parser_timeout_micros=Module._orig$ts_parser_timeout_micros=Module.asm.orig$ts_parser_timeout_micros).apply(null,arguments)},_orig$ts_parser_set_timeout_micros=Module._orig$ts_parser_set_timeout_micros=function(){return(_orig$ts_parser_set_timeout_micros=Module._orig$ts_parser_set_timeout_micros=Module.asm.orig$ts_parser_set_timeout_micros).apply(null,arguments)},calledRun;function callMain(e){var t=Module._main;if(t){(e=e||[]).unshift(thisProgram);var r=e.length,_=stackAlloc(4*(r+1)),n=_>>2;e.forEach((e=>{HEAP32[n++]=allocateUTF8OnStack(e)})),HEAP32[n]=0;try{var s=t(r,_);return exitJS(s,!0),s}catch(e){return handleException(e)}}}Module.AsciiToString=AsciiToString,Module.stringToUTF16=stringToUTF16,dependenciesFulfilled=function e(){calledRun||run(),calledRun||(dependenciesFulfilled=e)};var dylibsLoaded=!1;function run(e){function t(){calledRun||(calledRun=!0,Module.calledRun=!0,ABORT||(initRuntime(),preMain(),Module.onRuntimeInitialized&&Module.onRuntimeInitialized(),shouldRunNow&&callMain(e),postRun()))}e=e||arguments_,runDependencies>0||!dylibsLoaded&&(preloadDylibs(),dylibsLoaded=!0,runDependencies>0)||(preRun(),runDependencies>0||(Module.setStatus?(Module.setStatus("Running..."),setTimeout((function(){setTimeout((function(){Module.setStatus("")}),1),t()}),1)):t()))}if(Module.preInit)for("function"==typeof Module.preInit&&(Module.preInit=[Module.preInit]);Module.preInit.length>0;)Module.preInit.pop()();var shouldRunNow=!0;Module.noInitialRun&&(shouldRunNow=!1),run();const C=Module,INTERNAL={},SIZE_OF_INT=4,SIZE_OF_NODE=5*SIZE_OF_INT,SIZE_OF_POINT=2*SIZE_OF_INT,SIZE_OF_RANGE=2*SIZE_OF_INT+2*SIZE_OF_POINT,ZERO_POINT={row:0,column:0},QUERY_WORD_REGEX=/[\w-.]*/g,PREDICATE_STEP_TYPE_CAPTURE=1,PREDICATE_STEP_TYPE_STRING=2,LANGUAGE_FUNCTION_REGEX=/^_?tree_sitter_\w+/;var VERSION,MIN_COMPATIBLE_VERSION,TRANSFER_BUFFER,currentParseCallback,currentLogCallback;class ParserImpl{static init(){TRANSFER_BUFFER=C._ts_init(),VERSION=getValue(TRANSFER_BUFFER,"i32"),MIN_COMPATIBLE_VERSION=getValue(TRANSFER_BUFFER+SIZE_OF_INT,"i32")}initialize(){C._ts_parser_new_wasm(),this[0]=getValue(TRANSFER_BUFFER,"i32"),this[1]=getValue(TRANSFER_BUFFER+SIZE_OF_INT,"i32")}delete(){C._ts_parser_delete(this[0]),C._free(this[1]),this[0]=0,this[1]=0}setLanguage(e){let t;if(e){if(e.constructor!==Language)throw new Error("Argument must be a Language");{t=e[0];const r=C._ts_language_version(t);if(re.slice(t,_);else{if("function"!=typeof e)throw new Error("Argument must be a string or a function");currentParseCallback=e}this.logCallback?(currentLogCallback=this.logCallback,C._ts_parser_enable_logger_wasm(this[0],1)):(currentLogCallback=null,C._ts_parser_enable_logger_wasm(this[0],0));let _=0,n=0;if(r&&r.includedRanges){_=r.includedRanges.length,n=C._calloc(_,SIZE_OF_RANGE);let e=n;for(let t=0;t<_;t++)marshalRange(e,r.includedRanges[t]),e+=SIZE_OF_RANGE}const s=C._ts_parser_parse_wasm(this[0],this[1],t?t[0]:0,n,_);if(!s)throw currentParseCallback=null,currentLogCallback=null,new Error("Parsing failed");const a=new Tree(INTERNAL,s,this.language,currentParseCallback);return currentParseCallback=null,currentLogCallback=null,a}reset(){C._ts_parser_reset(this[0])}setTimeoutMicros(e){C._ts_parser_set_timeout_micros(this[0],e)}getTimeoutMicros(){return C._ts_parser_timeout_micros(this[0])}setLogger(e){if(e){if("function"!=typeof e)throw new Error("Logger callback must be a function")}else e=null;return this.logCallback=e,this}getLogger(){return this.logCallback}}class Tree{constructor(e,t,r,_){assertInternal(e),this[0]=t,this.language=r,this.textCallback=_}copy(){const e=C._ts_tree_copy(this[0]);return new Tree(INTERNAL,e,this.language,this.textCallback)}delete(){C._ts_tree_delete(this[0]),this[0]=0}edit(e){marshalEdit(e),C._ts_tree_edit_wasm(this[0])}get rootNode(){return C._ts_tree_root_node_wasm(this[0]),unmarshalNode(this)}getLanguage(){return this.language}walk(){return this.rootNode.walk()}getChangedRanges(e){if(e.constructor!==Tree)throw new TypeError("Argument must be a Tree");C._ts_tree_get_changed_ranges_wasm(this[0],e[0]);const t=getValue(TRANSFER_BUFFER,"i32"),r=getValue(TRANSFER_BUFFER+SIZE_OF_INT,"i32"),_=new Array(t);if(t>0){let e=r;for(let r=0;r0){let r=t;for(let t=0;t0){let r=t;for(let t=0;t0){let e=o;for(let t=0;t0){if("string"!==n[0].type)throw new Error("Predicates must begin with a literal value");const t=n[0].value;let r=!0;switch(t){case"not-eq?":r=!1;case"eq?":if(3!==n.length)throw new Error("Wrong number of arguments to `#eq?` predicate. Expected 2, got "+(n.length-1));if("capture"!==n[1].type)throw new Error(`First argument of \`#eq?\` predicate must be a capture. Got "${n[1].value}"`);if("capture"===n[2].type){const t=n[1].name,_=n[2].name;m[e].push((function(e){let n,s;for(const r of e)r.name===t&&(n=r.node),r.name===_&&(s=r.node);return void 0===n||void 0===s||n.text===s.text===r}))}else{const t=n[1].name,_=n[2].value;m[e].push((function(e){for(const n of e)if(n.name===t)return n.node.text===_===r;return!0}))}break;case"not-match?":r=!1;case"match?":if(3!==n.length)throw new Error(`Wrong number of arguments to \`#match?\` predicate. Expected 2, got ${n.length-1}.`);if("capture"!==n[1].type)throw new Error(`First argument of \`#match?\` predicate must be a capture. Got "${n[1].value}".`);if("string"!==n[2].type)throw new Error(`Second argument of \`#match?\` predicate must be a string. Got @${n[2].value}.`);const _=n[1].name,s=new RegExp(n[2].value);m[e].push((function(e){for(const t of e)if(t.name===_)return s.test(t.node.text)===r;return!0}));break;case"set!":if(n.length<2||n.length>3)throw new Error(`Wrong number of arguments to \`#set!\` predicate. Expected 1 or 2. Got ${n.length-1}.`);if(n.some((e=>"string"!==e.type)))throw new Error('Arguments to `#set!` predicate must be a strings.".');l[e]||(l[e]={}),l[e][n[1].value]=n[2]?n[2].value:null;break;case"is?":case"is-not?":if(n.length<2||n.length>3)throw new Error(`Wrong number of arguments to \`#${t}\` predicate. Expected 1 or 2. Got ${n.length-1}.`);if(n.some((e=>"string"!==e.type)))throw new Error(`Arguments to \`#${t}\` predicate must be a strings.".`);const a="is?"===t?u:d;a[e]||(a[e]={}),a[e][n[1].value]=n[2]?n[2].value:null;break;default:c[e].push({operator:t,operands:n.slice(1)})}n.length=0}}Object.freeze(l[e]),Object.freeze(u[e]),Object.freeze(d[e])}return C._free(r),new Query(INTERNAL,_,o,m,c,Object.freeze(l),Object.freeze(u),Object.freeze(d))}static load(e){let t;if(e instanceof Uint8Array)t=Promise.resolve(e);else{const r=e;if("undefined"!=typeof process&&process.versions&&process.versions.node){const e=require("fs");t=Promise.resolve(e.readFileSync(r))}else t=fetch(r).then((e=>e.arrayBuffer().then((t=>{if(e.ok)return new Uint8Array(t);{const r=new TextDecoder("utf-8").decode(t);throw new Error(`Language.load failed with status ${e.status}.\n\n${r}`)}}))))}const r="function"==typeof loadSideModule?loadSideModule:loadWebAssemblyModule;return t.then((e=>r(e,{loadAsync:!0}))).then((e=>{const t=Object.keys(e),r=t.find((e=>LANGUAGE_FUNCTION_REGEX.test(e)&&!e.includes("external_scanner_")));r||console.log(`Couldn't find language function in WASM file. Symbols:\n${JSON.stringify(t,null,2)}`);const _=e[r]();return new Language(INTERNAL,_)}))}}class Query{constructor(e,t,r,_,n,s,a,o){assertInternal(e),this[0]=t,this.captureNames=r,this.textPredicates=_,this.predicates=n,this.setProperties=s,this.assertedProperties=a,this.refutedProperties=o,this.exceededMatchLimit=!1}delete(){C._ts_query_delete(this[0]),this[0]=0}matches(e,t,r,_){t||(t=ZERO_POINT),r||(r=ZERO_POINT),_||(_={});let n=_.matchLimit;if(void 0===n)n=0;else if("number"!=typeof n)throw new Error("Arguments must be numbers");marshalNode(e),C._ts_query_matches_wasm(this[0],e.tree[0],t.row,t.column,r.row,r.column,n);const s=getValue(TRANSFER_BUFFER,"i32"),a=getValue(TRANSFER_BUFFER+SIZE_OF_INT,"i32"),o=getValue(TRANSFER_BUFFER+2*SIZE_OF_INT,"i32"),i=new Array(s);this.exceededMatchLimit=!!o;let l=0,u=a;for(let t=0;te(n)))){i[l++]={pattern:r,captures:n};const e=this.setProperties[r];e&&(i[t].setProperties=e);const _=this.assertedProperties[r];_&&(i[t].assertedProperties=_);const s=this.refutedProperties[r];s&&(i[t].refutedProperties=s)}}return i.length=l,C._free(a),i}captures(e,t,r,_){t||(t=ZERO_POINT),r||(r=ZERO_POINT),_||(_={});let n=_.matchLimit;if(void 0===n)n=0;else if("number"!=typeof n)throw new Error("Arguments must be numbers");marshalNode(e),C._ts_query_captures_wasm(this[0],e.tree[0],t.row,t.column,r.row,r.column,n);const s=getValue(TRANSFER_BUFFER,"i32"),a=getValue(TRANSFER_BUFFER+SIZE_OF_INT,"i32"),o=getValue(TRANSFER_BUFFER+2*SIZE_OF_INT,"i32"),i=[];this.exceededMatchLimit=!!o;const l=[];let u=a;for(let t=0;te(l)))){const e=l[_],r=this.setProperties[t];r&&(e.setProperties=r);const n=this.assertedProperties[t];n&&(e.assertedProperties=n);const s=this.refutedProperties[t];s&&(e.refutedProperties=s),i.push(e)}}return C._free(a),i}predicatesForPattern(e){return this.predicates[e]}didExceedMatchLimit(){return this.exceededMatchLimit}}function getText(e,t,r){const _=r-t;let n=e.textCallback(t,null,r);for(t+=n.length;t0))break;t+=_.length,n+=_}return t>r&&(n=n.slice(0,_)),n}function unmarshalCaptures(e,t,r,_){for(let n=0,s=_.length;n{ParserImpl.init(),resolveInitPromise()}})))}}return Parser}();"object"==typeof exports&&(module.exports=TreeSitter); diff --git a/backend/static/tree-sitter/tree-sitter.wasm b/backend/static/tree-sitter/tree-sitter.wasm new file mode 100644 index 0000000000..d9ca0da7b1 Binary files /dev/null and b/backend/static/tree-sitter/tree-sitter.wasm differ diff --git a/backend/testfiles/execution/json.tests b/backend/testfiles/execution/json.tests index 99e0a66b06..449a444145 100644 --- a/backend/testfiles/execution/json.tests +++ b/backend/testfiles/execution/json.tests @@ -252,6 +252,8 @@ Json.serialize> Nothing = Ok "{\"Nothing\":null}" Json.parse> "{\"Nothing\":null}" = Ok Nothing Json.serialize> (Just 1) = Ok "{\"Just\":1}" Json.parse> "{\"Just\":1}" = Ok (Just 1) +Json.parse> "null" = Ok Nothing +Json.parse> "1" = Ok (Just 1) // TODO: more... @@ -304,6 +306,9 @@ Json.parse """{ "Name": "Bob", "Age": 42 }""" = Ok (Person { Name = "Bob Json.serialize (People { GroupName = "Two Georges"; People = [Person { Name = "George A"; Age = 27 }; Person { Name = "George B"; Age = 42 }] }) = Ok """{"GroupName":"Two Georges","People":[{"Age":27,"Name":"George A"},{"Age":42,"Name":"George B"}]}""" Json.parse """{"GroupName":"Two Georges","People":[{"Age":27,"Name":"George A"},{"Age":42,"Name":"George B"}]}""" = Ok (People { GroupName = "Two Georges"; People = [Person { Name = "George A"; Age = 27 }; Person { Name = "George B"; Age = 42 }] }) +// can parse even if the JSON has _extra_ fields +Json.parse """{ "Name": "Bob", "Age": 42, "Height": "6 ft" }""" = Ok (Person { Name = "Bob"; Age = 42 }) + (let personMaybe = Json.parse """{ "Name": "Bob", "Age": 42 }""" match personMaybe with | Ok person -> person.Age diff --git a/canvases/dark-tree-sitter-demo/config.yml b/canvases/dark-tree-sitter-demo/config.yml new file mode 100644 index 0000000000..392deb04da --- /dev/null +++ b/canvases/dark-tree-sitter-demo/config.yml @@ -0,0 +1,2 @@ +version: 2 +main: main diff --git a/canvases/dark-tree-sitter-demo/main.dark b/canvases/dark-tree-sitter-demo/main.dark new file mode 100644 index 0000000000..7079d5ac98 --- /dev/null +++ b/canvases/dark-tree-sitter-demo/main.dark @@ -0,0 +1,363 @@ +[] +let _handler _req = + let body = + (Experiments.readFromStaticDir path) + |> Result.withDefault Bytes.empty + + let contentType = + match (String.split_v1 path ".") |> List.last_v2 |> Option.withDefault "" with + | "wasm" -> "application/wasm" + | "js" -> "text/javascript" + | "dll" -> "application/octet-stream" + | "dat" -> "application/octet-stream" + | "blat" -> "application/octet-stream" + | "json" -> "application/json" + | _ -> "text/plain" + + let incomingHost = + request.headers + |> List.findFirst_v2 (fun t -> Tuple2.first t == "origin") + |> Option.map_v1 (fun t -> Tuple2.second t) + |> Option.withDefault "Couldn't find 'origin' request header to determine Access-Control-Allow-Origin" + + let headers = + Dict.fromListOverwritingDuplicates + [ + ("Access-Control-Allow-Origin", incomingHost) + ("Access-Control-Allow-Credentials", "true") + ("Content-type", contentType) + ("Accept-Ranges", "bytes") + ] + + Http.responseWithHeaders body headers 200 + +[] +let _indexHandler _req = + // TODO: HTML of a basic webpage, that references WASM stuff + let body = + """ + + + + + + Dark Tree-Sitter WASM demo + + + + +
+
+ + +
+ +
+ + +
+ +
+ + +
+
+ + + + + """ + + Http.responseWithHeaders (String.toBytes body) (Dict.fromListOverwritingDuplicates [("Content-Type", "text/html")]) 200 + + +let gid (): Int = + Int.random_v1 0 9223372036854775807 + + +let err (msg: String): Unit = + // TODO: maybe something with the msg? + let _ = 1.0/0.0 + () + + +type PTTypeReference = + | TInt + +// TODO: the types of the 'id' fields should be something more like `type id = Int` +type PTExpr = + | EInt of id: Int * Int + | ELet of id: Int * identifier: String * expr: PTExpr * body: PTExpr + | EVariable of id: Int * String + | EFnCall of id: Int * fnName: String * args : List + + + + + +type PTUserFunctionParameter = + { id: Int + name: String + typ: PTTypeReference + description: String } + +type PTUserFunction = + { tlid: Int + name: String + typeParams: List // TODO + parameters: List + returnType: PTTypeReference + body: PTExpr + infix: Bool + description: String } + + +/// This is the 'universal' type that represents the output +/// of the tree-sitter parser. +type SyntaxTreeNode = + { typ: String + text: String + fieldName: Option + children: List } + +/// From a node, looks through its children for a single node +/// whose fieldName matches the one specified +/// +/// TODO: should return Option +let getField (node: SyntaxTreeNode) (fieldName: String): SyntaxTreeNode = + let children = node.children + + // TOOD: ensure only 1 child of this type exists + // (right now this won't error if 2 of the same fieldName exist) + let found = + children + |> List.findFirst_v2 (fun c -> + match c.fieldName with + | Just fName -> fName == fieldName + | Nothing -> false + ) + + match found with + | Just c -> c + | Nothing -> err ("Could not 1 field of name" ++ fieldName ++ " in node " ++ node.typ) + +let getText (node: SyntaxTreeNode): String = + node.text + +// TODO: should return Result +let parseExprCase (node: SyntaxTreeNode): PTExpr = + match node.typ with + | "identifier" -> PTExpr.EVariable (gid(), getText node) + + | "integer" -> + let i = Int.parse (getText node) + PTExpr.EInt (gid(), i) + + | "let_expression" -> + let identifier = (getField node "identifier") |> getText + let expr = (getField node "expr") |> parseExpr + let body = (getField node "body") |> parseExpr + PTExpr.ELet (gid(), identifier, expr, body) + + | "function_call" -> + let fnName = (getField node "fn") |> getText + + let args = getField node "args" + let args = + args.children + |> List.map (fun c -> parseExpr c) + + PTExpr.EFnCall (gid(), fnName, args) + + | "infix_operation" -> + let op = (getField node "operator") |> getText + + let id = gid() + + let left = parseExpr (getField node "left") + let right = parseExpr (getField node "right") + + match op with + | "+" -> PTExpr.EFnCall (id, "Int.add", [left; right]) + | "-" -> PTExpr.EFnCall (id, "Int.subtract", [left; right]) + + +// TODO: should return Result +let parseExpr (node: SyntaxTreeNode): PTExpr = + if node.typ != "expression" then + err "bad expr" + + match node.children with + | [single] -> single |> parseExprCase + | _ -> err "expression has 0 or 2+ children" + + +// TODO: should return Result +let parseTypeReference (node: SyntaxTreeNode): PTTypeReference = + // TODO: support additional types + PTTypeReference.TInt + + +// TODO: handle unit params +// e.g. `let doSomething () = ...` +// +// TODO: should return Result +let parseUserFunctionParam (node: SyntaxTreeNode): PTUserFunctionParameter = + if node.typ != "fn_param_def" then + err "fn param def wrong" + + PTUserFunctionParameter + { id = gid() + name = (getField node "identifier") |> getText + typ = (getField node "typ") |> parseTypeReference + description = "TODO" } + + +let parseUserFunctionParams (node: SyntaxTreeNode): List = + if node.typ != "fn_params_def" then + err "fn params def wrong" + + // TODO: the grammar is currently kinda bad - fix it and then follow up here + let first = getField node "first" + let additional = getField node "additional" + + [ first; additional ] + |> List.map(fun p -> parseUserFunctionParam p) + + +// TODO: should return Result +let parseUserFunction (node: SyntaxTreeNode): PTUserFunction = + if node.typ != "fn_def" then + err "fn def wrong" + + let params = (getField node "params") |> parseUserFunctionParams + + PTUserFunction + { tlid = gid() + name = (getField node "name") |> getText + parameters = params + typeParams = [] + returnType = (getField node "return_type") |> parseTypeReference + body = (getField node "body") |> parseExpr + infix = false + description = "TODO" } + + +/// This returns a Json-serialized PT.UserFunction that should be +/// able to be deserialized in WASM by Json.deserialize. +[] +let _handler _req = + // TODO: theoretically, we could even pass in the source code + // instead of the serialized syntax tree, and then parse it + // somehow in Dark? + let reqBody = String.fromBytes_v0 request.body + let synTree = Json.parse reqBody + + match synTree with + | Ok root -> + if root.typ != "source_file" then + err "fn def wrong" + + let userFn = + match root.children with + | [userFunction] -> parseUserFunction userFunction + + match Json.serialize userFn with + | Ok serialized -> + let respHeaders = + Dict.fromListOverwritingDuplicates + [ ("content-type", "application/json") ] + + Http.responseWithHeaders (String.toBytes serialized) respHeaders 200 + + | Error e -> + Http.responseWithHeaders (String.toBytes_v0 e) Dict.empty_v0 500 + + | Error e -> + Http.responseWithHeaders (String.toBytes_v0 e) Dict.empty_v0 400 \ No newline at end of file diff --git a/parser/tree-sitter-darklang/.gitignore b/parser/tree-sitter-darklang/.gitignore new file mode 100644 index 0000000000..6d6f6b23b1 --- /dev/null +++ b/parser/tree-sitter-darklang/.gitignore @@ -0,0 +1,4 @@ +src +bindings +build +node_modules \ No newline at end of file diff --git a/parser/tree-sitter-darklang/Cargo.toml b/parser/tree-sitter-darklang/Cargo.toml new file mode 100644 index 0000000000..e0a82a5c56 --- /dev/null +++ b/parser/tree-sitter-darklang/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "tree-sitter-darklang" +description = "darklang grammar for the tree-sitter parsing library" +version = "0.0.1" +keywords = ["incremental", "parsing", "darklang"] +categories = ["parsing", "text-editors"] +repository = "https://github.com/darklang/dark" +edition = "2018" +license = "MIT" + +build = "bindings/rust/build.rs" +include = [ + "bindings/rust/*", + "grammar.js", + "queries/*", + "src/*", +] + +[lib] +path = "bindings/rust/lib.rs" + +[dependencies] +tree-sitter = "~0.20.10" + +[build-dependencies] +cc = "1.0" diff --git a/parser/tree-sitter-darklang/README.md b/parser/tree-sitter-darklang/README.md new file mode 100644 index 0000000000..e065436c00 --- /dev/null +++ b/parser/tree-sitter-darklang/README.md @@ -0,0 +1,54 @@ +# Darklang tree-sitter parser + +In-progress / experimental `tree-sitter` parser for Darklang. + +- https://tree-sitter.github.io + +## Grammar and Parser + +The grammar of Darklang is defined in `grammar.js`. +This is a `tree-sitter`-specific file, which is used to generate a parser in C code. +The resultant parser is used to tokenize and parse Darklang code into a syntax tree. + +To get set up and familiar with the grammar and parser: + +- `npm i` install npm dependencies specific to this project +- `npm i -g tree-sitter-cli` + install tree-sitter globally via npm +- `tree-sitter init-config` + this creates a config file at `~/.config/tree-sitter/config.json` +- `code ~/.config/tree-sitter/config.json` + edit the config; add the path of `dark/parser` to the `parser-directories` array + for example, I keep my `dark` repo in `~/code/dark`, + so I added "/home/stachu/code/dark/parser" there. +- `tree-sitter dump-languages` to make sure you see `darklang` there somewhere +- `tree-sitter generate` to generate parser from grammar +- `tree-sitter parse ./demo.dark` to parse a hardcoded file +- `tree-sitter test` to test the parser against a 'corpus' of test cases found in `test/corpus` + +Note: `export PATH=$PATH:./node_modules/.bin` may be needed at some point? I forget. + +## Bindings + +"Bindings" are used to interface with the parser. While the parser takes taext and returns a structured syntax tree, +bindings must be created to interface with the parser in a particular language. + +Bindings may be used to provide syntax highlighting, code folding, or to turn the syntax tree into an AST (semantic analysis). + +At this point, we have bindings for JS/WASM - later, we may need bindings for F# or something else. + +### JS/WASM bindings + +To build the JS/WASM bindings: + +- compile to WASM with `tree-sitter build-wasm . && mv ./tree-sitter-darklang.wasm ./bindings` +- copy the bindings to `backend/static/tree-sitter` +- see `canvases/dark-tree-sitter-demo/README.md` for a JS/WASM usage demo + +Relevant documentation + +- https://github.com/tree-sitter/tree-sitter/tree/master/lib/binding_web + in particular, review the README.md and the .d.ts file +- the `tree-sitter.js` and `tree-sitter.wasm` files were pulled from the releases of `tree-sitter`. + The .js file is a wrapper around the .wasm file, and the .wasm file is the actual parser which calls upon language-specific parsers (like `tree-sitter-darklang.wasm`) after loading them. + https://github.com/tree-sitter/tree-sitter/releases/tag/v0.20.8 is the release these files were pulled from. diff --git a/parser/tree-sitter-darklang/binding.gyp b/parser/tree-sitter-darklang/binding.gyp new file mode 100644 index 0000000000..9d71740c50 --- /dev/null +++ b/parser/tree-sitter-darklang/binding.gyp @@ -0,0 +1,19 @@ +{ + "targets": [ + { + "target_name": "tree_sitter_darklang_binding", + "include_dirs": [ + " repeat($.fn_def), + + // Function definitions + fn_def: $ => seq( + 'let', + field('name', $.identifier), + field('params', $.fn_params_def), + ':', + field('return_type', $.type), + '=', + field('body', $.expression) + ), + + // fns need at least one param + // TODO: should this rule be enforced like this _in the parser_? + // TODO: we could just repeat1 here + fn_params_def: $ => seq( + field("first", $.fn_param_def), + field("additional", repeat($.fn_param_def)) + ), + + fn_param_def: $ => choice( + $.unit, + seq('(', + field('identifier', $.identifier), + ':', + field('typ', $.type), + ')' + ) + ), + + + // Expressions + expression: $ => choice( + $.let_expression, + //$.function_call, TODO: fix this (generator doesn't work when included) + $.infix_operation, + $.identifier, + $.string_literal, + $.unit + ), + let_expression: $ => seq( + 'let', + field('identifier', $.identifier), + '=', + field('expr', $.expression), + choice('in', '\n'), + field('body', $.expression), + ), + function_call: $ => seq( + field('fn', $.identifier), + field('args', repeat1($.expression)) + ), + string_literal: $ => seq( + '"', + field('value', /.*/), + '"' + ), + infix_operation: $ => prec.left(1, seq( + field('left', $.expression), + field('operator', choice('+', '-')), + field('right', $.expression), + )), + + // Basics + unit: $ => '()', + type: $ => choice(/Int/, /Bool/, /Float/, /String/, /Char/), + identifier: $ => /[a-zA-Z_][a-zA-Z0-9_]*/, + } +}); diff --git a/parser/tree-sitter-darklang/package-lock.json b/parser/tree-sitter-darklang/package-lock.json new file mode 100644 index 0000000000..3b77e93247 --- /dev/null +++ b/parser/tree-sitter-darklang/package-lock.json @@ -0,0 +1,67 @@ +{ + "name": "tree-sitter-darklang", + "version": "0.0.1", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "tree-sitter-darklang", + "version": "0.0.1", + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "nan": "^2.17.0" + }, + "devDependencies": { + "tree-sitter-cli": "^0.20.8", + "tree-sitter-javascript": "^0.19.0" + } + }, + "node_modules/nan": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==" + }, + "node_modules/tree-sitter-cli": { + "version": "0.20.8", + "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", + "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "tree-sitter": "cli.js" + } + }, + "node_modules/tree-sitter-javascript": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/tree-sitter-javascript/-/tree-sitter-javascript-0.19.0.tgz", + "integrity": "sha512-SNykDdNgmlJZhX02ZIu0TQF9P7t847jV7769SxA9XrZ2QXjofQsVTMEi9+LpXZKsI0UoFYI25FnZm3fFm0z2yw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "nan": "^2.12.1" + } + } + }, + "dependencies": { + "nan": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==" + }, + "tree-sitter-cli": { + "version": "0.20.8", + "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", + "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", + "dev": true + }, + "tree-sitter-javascript": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/tree-sitter-javascript/-/tree-sitter-javascript-0.19.0.tgz", + "integrity": "sha512-SNykDdNgmlJZhX02ZIu0TQF9P7t847jV7769SxA9XrZ2QXjofQsVTMEi9+LpXZKsI0UoFYI25FnZm3fFm0z2yw==", + "dev": true, + "requires": { + "nan": "^2.12.1" + } + } + } +} diff --git a/parser/tree-sitter-darklang/package.json b/parser/tree-sitter-darklang/package.json new file mode 100644 index 0000000000..ec47be26e7 --- /dev/null +++ b/parser/tree-sitter-darklang/package.json @@ -0,0 +1,32 @@ +{ + "name": "tree-sitter-darklang", + "version": "0.0.1", + "description": "A tree-sitter parser to parse Darklang source code", + "main": "bindings/node", + "scripts": { + "build": "tree-sitter generate && node-gyp configure && node-gyp build && tree-sitter build-wasm . && mv ./tree-sitter-darklang.wasm ./bindings", + "test": "tree-sitter test" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/darklang/dark.git" + }, + "author": "", + "license": "SEE LICENSE IN LICENSE.md", + "bugs": { + "url": "https://github.com/darklang/dark/issues" + }, + "homepage": "https://github.com/darklang/dark#readme", + "dependencies": { + "nan": "^2.17.0" + }, + "devDependencies": { + "tree-sitter-cli": "^0.20.8", + "tree-sitter-javascript": "^0.19.0" + }, + "tree-sitter": { + "file-types": [ + ".dark" + ] + } +} diff --git a/parser/tree-sitter-darklang/test/corpus/README.md b/parser/tree-sitter-darklang/test/corpus/README.md new file mode 100644 index 0000000000..8bcad86bed --- /dev/null +++ b/parser/tree-sitter-darklang/test/corpus/README.md @@ -0,0 +1,2 @@ +It's a `tree-sitter`-ism to keep these test files either in `./corpus` or `./test/corpus`. +I settled on following this, and choosing the latter. \ No newline at end of file diff --git a/parser/tree-sitter-darklang/test/corpus/functions.txt b/parser/tree-sitter-darklang/test/corpus/functions.txt new file mode 100644 index 0000000000..0978efc546 --- /dev/null +++ b/parser/tree-sitter-darklang/test/corpus/functions.txt @@ -0,0 +1,32 @@ +================== +Simple add function +================== + +let add (a: Int) (b: Int): Int = + let sum = a + b + sum + +--- + +(source_file + (fn_def + name: (identifier) + params: (fn_params_def + first: (fn_param_def + identifier: (identifier) + typ: (type)) + additional: (fn_param_def + identifier: (identifier) + typ: (type))) + return_type: (type) + body: (expression + (let_expression + identifier: (identifier) + expr: (expression + (infix_operation + left: (expression + (identifier)) + right: (expression + (identifier)))) + body: (expression + (identifier)))))) \ No newline at end of file