diff --git a/.gitmodules b/.gitmodules index ef053a507c..2b34239a20 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1352,6 +1352,9 @@ [submodule "vendor/grammars/verilog.tmbundle"] path = vendor/grammars/verilog.tmbundle url = https://github.com/textmate/verilog.tmbundle +[submodule "vendor/grammars/verse-grammar"] + path = vendor/grammars/verse-grammar + url = https://github.com/simnJS/verse-grammar.git [submodule "vendor/grammars/vsc-ember-syntax"] path = vendor/grammars/vsc-ember-syntax url = https://github.com/lifeart/vsc-ember-syntax.git diff --git a/grammars.yml b/grammars.yml index 4037508b1f..cab51ee5ce 100644 --- a/grammars.yml +++ b/grammars.yml @@ -1203,6 +1203,8 @@ vendor/grammars/typst-grammar: - source.typst vendor/grammars/verilog.tmbundle: - source.verilog +vendor/grammars/verse-grammar: +- source.verse vendor/grammars/vsc-ember-syntax: - inline.hbs - inline.template diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index dbde1fd01d..0b69c3cf9c 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -8288,6 +8288,14 @@ Verilog: codemirror_mode: verilog codemirror_mime_type: text/x-verilog language_id: 387 +Verse: + type: programming + color: "#518ef8" + extensions: + - ".verse" + tm_scope: source.verse + ace_mode: text + language_id: 180832205 Vim Help File: type: prose color: "#199f4b" diff --git a/samples/Verse/ConcurrencyFeatures.verse b/samples/Verse/ConcurrencyFeatures.verse new file mode 100644 index 0000000000..c9743ab59b --- /dev/null +++ b/samples/Verse/ConcurrencyFeatures.verse @@ -0,0 +1,64 @@ +using. /Verse.org/Concurrency +using. /Verse.org/Simulation + +ConcurrencyFeatures := module { + + ArrayRace(Array:[]t, HandlerFunction(Element:t):u where t:type, u:type):u = { + if ( + Array.Length > 1 + MidPoint := Floor(Array.Length / 2) + LeftArray := Array.Slice[0, MidPoint] + RightArray := Array.Slice[MidPoint] + ) { + race { + ArrayRace(LeftArray, HandlerFunction) + ArrayRace(RightArray, HandlerFunction) + } + } else if (FirstElement := Array[0]) { + HandlerFunction(FirstElement) + } else { + Sleep(Inf) + Err("Unreachable") + } + } + + ArrayRush(Array:[]t, HandlerFunction(Element:t):u where t:type, u:type):u = { + if ( + Array.Length > 1 + MidPoint := Floor(Array.Length / 2) + LeftArray := Array.Slice[0, MidPoint] + RightArray := Array.Slice[MidPoint] + ) { + rush { + ArrayRush(LeftArray, HandlerFunction) + ArrayRush(RightArray, HandlerFunction) + } + } else if (FirstElement := Array[0]) { + HandlerFunction(FirstElement) + } else { + Sleep(Inf) + Err("Unreachable") + } + } + + ArraySync(Array:[]t, HandlerFunction(Element:t):u where t:type, u:type):[]u = { + if ( + Array.Length > 1 + MidPoint := Floor(Array.Length / 2) + LeftArray := Array.Slice[0, MidPoint] + RightArray := Array.Slice[MidPoint] + ) { + SyncResult := sync { + ArraySync(LeftArray, HandlerFunction) + ArraySync(RightArray, HandlerFunction) + } + + SyncResult(0) + SyncResult(1) + + } else if (FirstElement := Array[0]) { + array{HandlerFunction(FirstElement)} + } else { + array{} + } + } +} \ No newline at end of file diff --git a/samples/Verse/Hexadecimal.verse b/samples/Verse/Hexadecimal.verse new file mode 100644 index 0000000000..a6b6363bd8 --- /dev/null +++ b/samples/Verse/Hexadecimal.verse @@ -0,0 +1,126 @@ +Hexadecimal := module{ + using. BitMath + using. MathFeatures + using. StringProcessing + + UpperCaseHexAlphabet : string = "0123456789ABCDEF" + LowerCaseHexAlphabet : string = "0123456789abcdef" + + ReverseHexTable : [char]int = map{ + '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, + 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, + 'a' => 10, 'b' => 11, 'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15 + } + + # Converts a single byte (0-255) to its two-character hexadecimal representation + # By default uses uppercase letters, but can use lowercase if wanted (for ex in MD5 Hashes) + # Fails if the input is outside the byte range + EncodeByteToHex(Byte:int, ?LowerCase:logic=false):string = { + HexAlphabet := LowerCase? and LowerCaseHexAlphabet or UpperCaseHexAlphabet + + HighNibble := HexAlphabet[Quotient[Byte, 16]] + LowNibble := HexAlphabet[Mod[Byte, 16]] + + "{HighNibble}{LowNibble}" + } + + # Converts a byte array to its hexadecimal string representation + EncodeByteArrayToHex(ByteArray:[]int, ?LowerCase:logic=false):string = { + HexParts := for (Byte : ByteArray) { + EncodeByteToHex[Byte, ?LowerCase := LowerCase] + } + Concatenate(HexParts) + } + + # WIP: Deprecate later (redundant) + # Converts a single char to its two-character hexadecimal representation + EncodeCharToHex(Character:char, ?LowerCase:logic=false):string = { + ByteValue := CharToByte(Character) + + EncodeByteToHex[ByteValue, ?LowerCase := LowerCase] or Err("Unreachable") + } + + # WIP: Deprecate later (redundant) + # Converts a string to its hexadecimal string representation + EncodeStringToHex(String:string, ?LowerCase:logic=false):string = { + HexParts := for (Character : String) { + EncodeCharToHex(Character, ?LowerCase := LowerCase) + } + Concatenate(HexParts) + } + + # WIP: Deprecate later (redundant) + # Converts an arbitrary-sized integer to its hexadecimal string representation + # Fails if the input integer is negative + EncodeIntToHex(Value:int, ?LowerCase:logic=false):string = { + Value >= 0 + + # Calculate how many bytes are needed to represent the unsigned value + ByteCount := Value = 0 and 1 or Quotient[GetBitWidth(Value) + 8, 8] or Err("Unreachable") + + # 2. Iterate through the bytes from high to low + Concatenate(for (Index := 1..ByteCount) { + # We want to print Big-Endian (Most Significant Byte first) + # So we invert the index + BytePosition := ByteCount - Index + + # Calculate divisor: 2^(BytePosition * 8) + Divisor := PowerOfTwo[BytePosition * 8] or Err("Unreachable") + + # Shift the value down to this byte position + # This gives us the value of this byte AND all bytes above it + ShiftedValue := Quotient[Value, Divisor] + + # If ShiftedValue is 0, it means this byte (and all above it) are 0. + # We skip it (return empty string) UNLESS it's the very last byte (Divisor=1). + # This ensures '0' prints as "00" but '0xFF' prints as "FF" (not "00FF"). + (ShiftedValue > 0 or Divisor = 1) and ( + ByteValue := Mod[ShiftedValue, 256] or Err("Unreachable") + EncodeByteToHex[ByteValue, ?LowerCase := LowerCase] or Err("Unreachable") + ) or "" + }) + } + + # Converts a hexadecimal string into its respective byte array + # Fails if the input string has an odd length or contains invalid hexadecimal characters + DecodeHexToByteArray(HexString:string):[]int = { + HexLength := HexString.Length + + Mod[HexLength, 2] = 0 + + for (Index := 0..(Truncate(HexLength / 2)) - 1) { + HighChar := HexString[Index * 2] or Err("Unreachable") + LowChar := HexString[(Index * 2) + 1] or Err("Unreachable") + + HighValue := ReverseHexTable[HighChar] + LowValue := ReverseHexTable[LowChar] + + (HighValue * 16) + LowValue + } + } + + # WIP: Deprecate later (redundant) + # Decodes a hexadecimal string into its normal byte string representation + # Fails if the input string has an odd length or contains invalid hexadecimal characters + DecodeHexToString(HexString:string):string = { + ByteArray := DecodeHexToByteArray[HexString] + ByteArrayToString[ByteArray] or Err("Unreachable") + } + + # WIP: Deprecate later (redundant) + # Decodes a hexadecimal string into its integer representation + # Fails if the input string is empty, has an odd length, or contains invalid hexadecimal characters + DecodeHexToInt(HexString:string):int = { + var Result : int = 0 + + ByteArray := DecodeHexToByteArray[HexString] + + ByteArray.Length > 0 + + for (Byte : ByteArray) { + set Result = (Result * 256) + Byte + } + + Result + } +} \ No newline at end of file diff --git a/vendor/README.md b/vendor/README.md index a2decadded..464cd7b88b 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -667,6 +667,7 @@ This is a list of grammars that Linguist selects to provide syntax highlighting - **Velocity Template Language:** [animecyc/AtomLanguageVelocity](https://github.com/animecyc/AtomLanguageVelocity) - **Vento:** [ventojs/vscode-vento](https://github.com/ventojs/vscode-vento) - **Verilog:** [textmate/verilog.tmbundle](https://github.com/textmate/verilog.tmbundle) +- **Verse:** [simnJS/verse-grammar](https://github.com/simnJS/verse-grammar) - **Vim Help File:** [Alhadis/language-viml](https://github.com/Alhadis/language-viml) - **Vim Script:** [Alhadis/language-viml](https://github.com/Alhadis/language-viml) - **Vim Snippet:** [Alhadis/language-viml](https://github.com/Alhadis/language-viml) diff --git a/vendor/grammars/verse-grammar b/vendor/grammars/verse-grammar new file mode 160000 index 0000000000..3abf18ec6e --- /dev/null +++ b/vendor/grammars/verse-grammar @@ -0,0 +1 @@ +Subproject commit 3abf18ec6e8d9fcbbb15be8183cb5b2cb6a621b8 diff --git a/vendor/licenses/git_submodule/verse-grammar.dep.yml b/vendor/licenses/git_submodule/verse-grammar.dep.yml new file mode 100644 index 0000000000..51327e3fe8 --- /dev/null +++ b/vendor/licenses/git_submodule/verse-grammar.dep.yml @@ -0,0 +1,33 @@ +--- +name: verse-grammar +version: 3abf18ec6e8d9fcbbb15be8183cb5b2cb6a621b8 +type: git_submodule +homepage: https://github.com/simnjs/verse-grammar.git +license: mit +licenses: +- sources: LICENSE + text: | + MIT License + + Copyright (c) 2025 GAY Simon + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- sources: README.md + text: MIT License - see LICENSE file for details. +notices: []