├── .gitignore ├── doc ├── readme.md ├── stark-language-reference.md ├── stark-region-lifetime.drawio.svg └── stark_grammar.g4 ├── img └── logo.png ├── license.txt ├── readme.md └── src ├── compiler ├── .editorconfig ├── Stark.Compiler.BenchApp │ ├── BenchHash.cs │ ├── BenchLexer.cs │ ├── Program.cs │ └── Stark.Compiler.BenchApp.csproj ├── Stark.Compiler.SourceGen │ ├── DiagnosticMessagesGenerator.cs │ └── Stark.Compiler.SourceGen.csproj ├── Stark.Compiler.Tests │ ├── Stark.Compiler.Tests.csproj │ └── TestLexer.cs ├── Stark.Compiler.sln ├── Stark.Compiler.sln.DotSettings ├── Stark.Compiler │ ├── Collections │ │ └── InlineList.cs │ ├── Diagnostics │ │ ├── Diagnostic.cs │ │ ├── DiagnosticBag.cs │ │ ├── DiagnosticId.cs │ │ ├── DiagnosticKind.cs │ │ ├── DiagnosticLocation.cs │ │ ├── DiagnosticMessage.cs │ │ └── DiagnosticSourceFileLocation.cs │ ├── Helpers │ │ ├── HashHelper.cs │ │ ├── ThrowHelper.cs │ │ ├── Utf8Class.cs │ │ ├── Utf8ClassMask.cs │ │ ├── Utf8Helper.cs │ │ └── Utf8String.cs │ ├── Parsing │ │ ├── KeywordHelper.cs │ │ ├── Lexer.cs │ │ ├── LexerFileEntry.cs │ │ └── LexerInputOutput.cs │ ├── Stark.Compiler.csproj │ ├── Syntax │ │ ├── TokenKind.cs │ │ └── TokenSpan.cs │ └── TextSpan.cs ├── global.json └── readme.md ├── ide ├── readme.md └── vscode │ └── stark │ ├── .vscode │ ├── launch.json │ └── tasks.json │ ├── language-configuration.json │ ├── package.json │ ├── readme.md │ ├── src │ └── extension.ts │ ├── syntaxes │ ├── stark.YAML-tmLanguage │ └── stark.tmLanguage │ ├── theme │ └── file_type_stark.svg │ └── tsconfig.json └── runtime └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Rider 14 | .idea/ 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | build/ 24 | bld/ 25 | [Bb]in/ 26 | [Oo]bj/ 27 | tmp/ 28 | [tT]emp/ 29 | 30 | # Visual Studio 2015 cache/options directory 31 | .vs/ 32 | # Uncomment if you have tasks that create the project's static files in wwwroot 33 | #wwwroot/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # DNX 49 | project.lock.json 50 | artifacts/ 51 | 52 | *_i.c 53 | *_p.c 54 | *_i.h 55 | *.ilk 56 | *.meta 57 | *.obj 58 | *.pch 59 | *.pdb 60 | *.pgc 61 | *.pgd 62 | *.rsp 63 | *.sbr 64 | *.tlb 65 | *.tli 66 | *.tlh 67 | *.tmp 68 | *.tmp_proj 69 | *.log 70 | *.vspscc 71 | *.vssscc 72 | .builds 73 | *.pidb 74 | *.svclog 75 | *.scc 76 | 77 | # Chutzpah Test files 78 | _Chutzpah* 79 | 80 | # Visual C++ cache files 81 | ipch/ 82 | *.aps 83 | *.ncb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | 88 | # Visual Studio profiler 89 | *.psess 90 | *.vsp 91 | *.vspx 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | *.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | 158 | # Windows Azure Build Output 159 | csx/ 160 | *.build.csdef 161 | 162 | # Windows Store app package directory 163 | AppPackages/ 164 | 165 | # Visual Studio cache files 166 | # files ending in .cache can be ignored 167 | *.[Cc]ache 168 | # but keep track of directories ending in .cache 169 | !*.[Cc]ache/ 170 | 171 | # Others 172 | ClientBin/ 173 | [Ss]tyle[Cc]op.* 174 | ~$* 175 | *~ 176 | *.dbmdl 177 | *.dbproj.schemaview 178 | *.pfx 179 | *.publishsettings 180 | node_modules/ 181 | orleans.codegen.cs 182 | 183 | # RIA/Silverlight projects 184 | Generated_Code/ 185 | 186 | # Backup & report files from converting an old project file 187 | # to a newer Visual Studio version. Backup files are not needed, 188 | # because we have git ;-) 189 | _UpgradeReport_Files/ 190 | Backup*/ 191 | UpgradeLog*.XML 192 | UpgradeLog*.htm 193 | 194 | # SQL Server files 195 | *.mdf 196 | *.ldf 197 | 198 | # Business Intelligence projects 199 | *.rdl.data 200 | *.bim.layout 201 | *.bim_*.settings 202 | 203 | # Microsoft Fakes 204 | FakesAssemblies/ 205 | 206 | # Node.js Tools for Visual Studio 207 | .ntvs_analysis.dat 208 | 209 | # Visual Studio 6 build log 210 | *.plg 211 | 212 | # Visual Studio 6 workspace options file 213 | *.opt 214 | 215 | # Visual Studio LightSwitch build output 216 | **/*.HTMLClient/GeneratedArtifacts 217 | **/*.DesktopClient/GeneratedArtifacts 218 | **/*.DesktopClient/ModelManifest.xml 219 | **/*.Server/GeneratedArtifacts 220 | **/*.Server/ModelManifest.xml 221 | _Pvt_Extensions 222 | 223 | # ANTLR 224 | .antlr/ 225 | -------------------------------------------------------------------------------- /doc/readme.md: -------------------------------------------------------------------------------- 1 | # Stark documentation 2 | 3 | ## Language Reference 4 | 5 | The language reference is described [here](stark-language-reference.md). 6 | 7 | ## Runtime Reference 8 | 9 | TBD. 10 | -------------------------------------------------------------------------------- /doc/stark-region-lifetime.drawio.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 | Region1 19 |
20 |
21 |
22 |
23 | 24 | Region1 25 | 26 |
27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 |
39 | Region2 40 |
41 |
42 |
43 |
44 | 45 | Region2 46 | 47 |
48 |
49 | 50 | 51 | 52 | 53 |
54 |
55 |
56 | Region3 57 |
58 |
59 |
60 |
61 | 62 | Region3 63 | 64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 |
73 |
74 |
75 | Region4 76 |
77 |
78 |
79 |
80 | 81 | Region4 82 | 83 |
84 |
85 | 86 | 87 | 88 | 89 |
90 |
91 |
92 | Region5 93 |
94 |
95 |
96 |
97 | 98 | Region5 99 | 100 |
101 |
102 | 103 | 104 | 105 | 106 | 107 | 108 |
109 |
110 |
111 | Region6 112 |
113 |
114 |
115 |
116 | 117 | Region6 118 | 119 |
120 |
121 | 122 | 123 | 124 | 125 | 126 | 127 |
128 |
129 |
130 | Region7 131 |
132 |
133 |
134 |
135 | 136 | Region7 137 | 138 |
139 |
140 | 141 | 142 | 143 | 144 |
145 |
146 |
147 | 148 | Region6 149 | 150 | - with lifetime #L 151 |
152 |
153 |
154 |
155 | 156 | Region6 - with lifetime #L 157 | 158 |
159 |
160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 |
186 |
187 |
188 | 189 | Region7 190 | 191 | - with Lifetime #R 192 |
193 |
194 |
195 |
196 | 197 | Region7 - with Lifetime #R 198 | 199 |
200 |
201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 |
224 |
225 |
226 | 227 | ropen #L 228 | 229 |
230 |
231 |
232 |
233 | 234 | ropen #L 235 | 236 |
237 |
238 | 239 | 240 | 241 | 242 |
243 |
244 |
245 | 246 | ropen #R 247 | 248 |
249 |
250 |
251 |
252 | 253 | ropen #R 254 | 255 |
256 |
257 |
258 | 259 | 260 | 261 | 262 | Viewer does not support full SVG 1.1 263 | 264 | 265 | 266 |
-------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stark-lang/stark/018d9ecad4266392700ded912c95cb6085a6e473/img/logo.png -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022, Alexandre Mutel 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification 5 | , are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # stark-lang 2 | 3 | 4 | 5 | This is the main repository of the stark programming language. 6 | 7 | > The repository is in a **prototyping stage** and is going through multiple phase of prototypes. 8 | > 9 | > A first functional prototype was using a fork of Roslyn and the code is now only available in the branch: [roslyn-fork-prototype](https://github.com/stark-lang/stark/tree/roslyn-fork-prototype) 10 | > 11 | > The next iteration of the prototype will be more disruptive and so can't reuse Roslyn. 12 | 13 | ## About 14 | 15 | You can find more details about this project in the following blog post series: 16 | 17 | - [The Odyssey of Stark and Melody](https://xoofx.github.io/blog/2020/03/05/stark-melody-dotnet-sel4/) 18 | - [Stark - Language And Frontend Compiler - Prototype 2019](https://xoofx.github.io/blog/2020/03/06/stark-language-frontend-compiler/) 19 | 20 | ## IDE Syntax Highlighting 21 | 22 | You need to have Visual Studio Code installed. 23 | 24 | - Open the folder `src/ide/vscode/stark` with Visual Studio Code 25 | - Run the build task via the menu `Terminal/Run Build Task...` (or `CTRL+SHIFT+B` on Windows). 26 | - If the build is failing, it could be a misconfiguration of npm/tsc. Open a terminal from VSCode and run the command `npm install -g typescript`. Check that `tsc --version` is running fine (you should have a version above `3.x` or more) 27 | - Press F5 and it should open a new Visual Studio Code instance with the syntax highlighting for Stark and a pseudo integration with a compiler server (nothing is actually plugged there). 28 | - With this new Visual Studio Code instance, open the folder `src/runtime` and you should be able to play with the syntax/language by changing the `core` library. 29 | 30 | ## License 31 | 32 | This software is released under the [BSD-Clause 2 license](http://opensource.org/licenses/BSD-2-Clause). 33 | 34 | -------------------------------------------------------------------------------- /src/compiler/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | 3 | # NUnit2005: Consider using Assert.That(actual, Is.EqualTo(expected)) instead of Assert.AreEqual(expected, actual) 4 | dotnet_diagnostic.NUnit2005.severity = none 5 | csharp_indent_labels = one_less_than_current 6 | csharp_using_directive_placement = outside_namespace:silent 7 | csharp_prefer_simple_using_statement = true:suggestion 8 | csharp_prefer_braces = true:silent 9 | csharp_style_namespace_declarations = block_scoped:silent 10 | csharp_style_prefer_method_group_conversion = true:silent 11 | csharp_style_prefer_top_level_statements = true:silent 12 | csharp_style_expression_bodied_methods = false:silent 13 | csharp_style_expression_bodied_constructors = false:silent 14 | csharp_style_expression_bodied_operators = false:silent 15 | csharp_style_expression_bodied_properties = true:silent 16 | csharp_style_expression_bodied_indexers = true:silent 17 | csharp_style_expression_bodied_accessors = true:silent 18 | csharp_style_expression_bodied_lambdas = true:silent 19 | csharp_style_expression_bodied_local_functions = false:silent 20 | csharp_style_throw_expression = true:suggestion 21 | csharp_style_prefer_null_check_over_type_check = true:suggestion 22 | csharp_prefer_simple_default_expression = true:suggestion 23 | csharp_style_prefer_local_over_anonymous_function = true:suggestion 24 | csharp_style_prefer_index_operator = true:suggestion 25 | csharp_style_prefer_range_operator = true:suggestion 26 | csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion 27 | csharp_style_prefer_tuple_swap = true:suggestion 28 | csharp_style_prefer_utf8_string_literals = true:suggestion 29 | csharp_style_inlined_variable_declaration = true:suggestion 30 | csharp_style_deconstructed_variable_declaration = true:suggestion 31 | 32 | [*.{cs,vb}] 33 | #### Naming styles #### 34 | 35 | # Naming rules 36 | 37 | dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion 38 | dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface 39 | dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i 40 | 41 | dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion 42 | dotnet_naming_rule.types_should_be_pascal_case.symbols = types 43 | dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case 44 | 45 | dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion 46 | dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members 47 | dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case 48 | 49 | # Symbol specifications 50 | 51 | dotnet_naming_symbols.interface.applicable_kinds = interface 52 | dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected 53 | dotnet_naming_symbols.interface.required_modifiers = 54 | 55 | dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum 56 | dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected 57 | dotnet_naming_symbols.types.required_modifiers = 58 | 59 | dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method 60 | dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected 61 | dotnet_naming_symbols.non_field_members.required_modifiers = 62 | 63 | # Naming styles 64 | 65 | dotnet_naming_style.begins_with_i.required_prefix = I 66 | dotnet_naming_style.begins_with_i.required_suffix = 67 | dotnet_naming_style.begins_with_i.word_separator = 68 | dotnet_naming_style.begins_with_i.capitalization = pascal_case 69 | 70 | dotnet_naming_style.pascal_case.required_prefix = 71 | dotnet_naming_style.pascal_case.required_suffix = 72 | dotnet_naming_style.pascal_case.word_separator = 73 | dotnet_naming_style.pascal_case.capitalization = pascal_case 74 | 75 | dotnet_naming_style.pascal_case.required_prefix = 76 | dotnet_naming_style.pascal_case.required_suffix = 77 | dotnet_naming_style.pascal_case.word_separator = 78 | dotnet_naming_style.pascal_case.capitalization = pascal_case 79 | dotnet_style_operator_placement_when_wrapping = beginning_of_line 80 | tab_width = 4 81 | indent_size = 4 82 | end_of_line = crlf 83 | dotnet_style_coalesce_expression = true:suggestion 84 | dotnet_style_null_propagation = true:suggestion 85 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion 86 | dotnet_style_prefer_auto_properties = true:silent 87 | dotnet_style_object_initializer = true:suggestion 88 | dotnet_style_collection_initializer = true:suggestion 89 | dotnet_style_prefer_simplified_boolean_expressions = true:suggestion 90 | dotnet_style_prefer_conditional_expression_over_assignment = true:silent 91 | dotnet_style_prefer_conditional_expression_over_return = true:silent 92 | dotnet_style_explicit_tuple_names = true:suggestion 93 | dotnet_style_prefer_inferred_tuple_names = true:suggestion 94 | dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion 95 | dotnet_style_prefer_compound_assignment = true:suggestion 96 | dotnet_style_prefer_simplified_interpolation = true:suggestion 97 | dotnet_style_namespace_match_folder = true:suggestion 98 | -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler.BenchApp/BenchHash.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | using BenchmarkDotNet.Attributes; 6 | using Stark.Compiler.Helpers; 7 | 8 | namespace Stark.Compiler.BenchApp; 9 | 10 | /// 11 | /// Small benchmark to decide until which size I can use FNV-1A vs System.HashCode. 12 | /// 13 | /// Verdict: If the size is lower than 28, FNV-1A is better 14 | /// 15 | /// BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22000.1098/21H2) 16 | /// AMD Ryzen 9 5950X, 1 CPU, 32 logical and 16 physical cores 17 | /// .NET SDK=7.0.100-rc.1.22431.12 18 | /// [Host] : .NET 7.0.0 (7.0.22.42610), X64 RyuJIT AVX2 19 | /// DefaultJob : .NET 7.0.0 (7.0.22.42610), X64 RyuJIT AVX2 20 | /// 21 | /// | Method | data | Mean | Error | StdDev | 22 | /// |----------- |----------|----------:|---------:|---------:| 23 | /// | HashCode | Byte[16] | 6.808 ns | 0.0465 ns | 0.0412 ns | 24 | /// | HashCode | Byte[17] | 7.148 ns | 0.0106 ns | 0.0094 ns | 25 | /// | HashCode | Byte[18] | 8.608 ns | 0.0282 ns | 0.0264 ns | 26 | /// | HashCode | Byte[19] | 9.855 ns | 0.0314 ns | 0.0294 ns | 27 | /// | HashCode | Byte[20] | 7.133 ns | 0.0273 ns | 0.0256 ns | 28 | /// | HashCode | Byte[21] | 8.601 ns | 0.0136 ns | 0.0127 ns | 29 | /// | HashCode | Byte[22] | 9.961 ns | 0.0292 ns | 0.0273 ns | 30 | /// | HashCode | Byte[23] | 13.877 ns | 0.1031 ns | 0.0964 ns | 31 | /// | HashCode | Byte[24] | 8.698 ns | 0.0287 ns | 0.0255 ns | 32 | /// | HashCode | Byte[25] | 10.795 ns | 0.0276 ns | 0.0259 ns | 33 | /// | HashCode | Byte[26] | 13.96 ns | 0.051 ns | 0.045 ns | 34 | /// | HashCode | Byte[27] | 14.87 ns | 0.041 ns | 0.038 ns | 35 | /// | HashCode | Byte[28] | 9.885 ns | 0.0236 ns | 0.0210 ns | 36 | /// | HashCode | Byte[29] | 13.954 ns | 0.0289 ns | 0.0270 ns | 37 | /// | HashCode | Byte[30] | 14.974 ns | 0.0755 ns | 0.0707 ns | 38 | /// | HashCode | Byte[31] | 15.703 ns | 0.0645 ns | 0.0572 ns | 39 | /// | HashCode | Byte[32] | 9.337 ns | 0.0337 ns | 0.0315 ns | 40 | /// | HashCode | Byte[33] | 12.929 ns | 0.0977 ns | 0.0914 ns | 41 | /// | HashFNV1A | Byte[16] | 6.542 ns | 0.0260 ns | 0.0243 ns | 42 | /// | HashFNV1A | Byte[17] | 6.923 ns | 0.0141 ns | 0.0131 ns | 43 | /// | HashFNV1A | Byte[18] | 7.264 ns | 0.0210 ns | 0.0197 ns | 44 | /// | HashFNV1A | Byte[19] | 7.707 ns | 0.0208 ns | 0.0194 ns | 45 | /// | HashFNV1A | Byte[20] | 9.034 ns | 0.0209 ns | 0.0196 ns | 46 | /// | HashFNV1A | Byte[21] | 8.679 ns | 0.0223 ns | 0.0209 ns | 47 | /// | HashFNV1A | Byte[22] | 9.279 ns | 0.0218 ns | 0.0193 ns | 48 | /// | HashFNV1A | Byte[23] | 9.876 ns | 0.0563 ns | 0.0499 ns | 49 | /// | HashFNV1A | Byte[24] | 10.428 ns | 0.0357 ns | 0.0334 ns | 50 | /// | HashFNV1A | Byte[25] | 11.074 ns | 0.0385 ns | 0.0360 ns | 51 | /// | HashFNV1A | Byte[26] | 11.90 ns | 0.022 ns | 0.021 ns | 52 | /// | HashFNV1A | Byte[27] | 12.79 ns | 0.020 ns | 0.016 ns | 53 | /// | HashFNV1A | Byte[28] | 13.585 ns | 0.0348 ns | 0.0325 ns | 54 | /// | HashFNV1A | Byte[29] | 14.412 ns | 0.0326 ns | 0.0305 ns | 55 | /// | HashFNV1A | Byte[30] | 16.614 ns | 0.0682 ns | 0.0638 ns | 56 | /// | HashFNV1A | Byte[31] | 15.993 ns | 0.0677 ns | 0.0600 ns | 57 | /// | HashFNV1A | Byte[32] | 16.388 ns | 0.0562 ns | 0.0498 ns | 58 | /// | HashFNV1A | Byte[33] | 16.879 ns | 0.0397 ns | 0.0371 ns | 59 | /// 60 | public class BenchHash 61 | { 62 | [Benchmark] 63 | [ArgumentsSource(nameof(Data))] 64 | public int HashCode(byte[] data) 65 | { 66 | var hash = new HashCode(); 67 | hash.AddBytes(data); 68 | return hash.ToHashCode(); 69 | } 70 | 71 | [Benchmark] 72 | [ArgumentsSource(nameof(Data))] 73 | public int HashFNV1A(byte[] data) 74 | { 75 | return HashHelper.Hash(data); 76 | } 77 | 78 | public IEnumerable Data() 79 | { 80 | //for (int i = 1; i < 36; i++) 81 | //{ 82 | // yield return Enumerable.Range(0, i).Select(x => (byte)x).ToArray(); 83 | //} 84 | yield return Enumerable.Range(0, 64).Select(x => (byte)x).ToArray(); 85 | yield return Enumerable.Range(0, 80).Select(x => (byte)x).ToArray(); 86 | yield return Enumerable.Range(0, 96).Select(x => (byte)x).ToArray(); 87 | //yield return Enumerable.Range(0, 64).Select(x => (byte)x).ToArray(); 88 | } 89 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler.BenchApp/BenchLexer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | using System.Text; 6 | using BenchmarkDotNet.Attributes; 7 | using Microsoft.CodeAnalysis.CSharp; 8 | using Stark.Compiler.Parsing; 9 | using Varena; 10 | 11 | namespace Stark.Compiler.BenchApp; 12 | 13 | /// 14 | /// Benchmark of Stark lexer vs Roslyn lexer. 15 | /// 16 | /// The comparison is not completely fair for Stark, as it is parsing C# keywords, so it will generate a lot more identifiers than C# 17 | /// But as the computation is relatively the same if it is a keyword or an identifier (expect it needs to store the identifier) 18 | /// we keep it simple. 19 | /// 20 | public class BenchLexer 21 | { 22 | private static RoslynRunner? _roslynRunner; 23 | private static StarkRunner? _starkRunner; 24 | 25 | [Benchmark] 26 | public void Roslyn() 27 | { 28 | _roslynRunner ??= new RoslynRunner(); 29 | _roslynRunner.Run(); 30 | } 31 | 32 | [Benchmark] 33 | public void Stark() 34 | { 35 | _starkRunner ??= new StarkRunner(); 36 | _starkRunner.Run(); 37 | } 38 | 39 | private class RoslynRunner 40 | { 41 | private readonly List _roslynTokens = new(); 42 | private readonly string _csharpText; 43 | 44 | public RoslynRunner() 45 | { 46 | _csharpText = new CodeBuilder().GenerateCode(); 47 | } 48 | 49 | public void Run() 50 | { 51 | _roslynTokens.Clear(); 52 | var tokenCount = 0; 53 | foreach (var token in Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseTokens(_csharpText)) 54 | { 55 | if (token.HasLeadingTrivia) 56 | { 57 | foreach (var trivia in token.LeadingTrivia) 58 | { 59 | tokenCount++; 60 | } 61 | } 62 | 63 | if (token.HasTrailingTrivia) 64 | { 65 | foreach (var trivia in token.TrailingTrivia) 66 | { 67 | tokenCount++; 68 | } 69 | } 70 | 71 | _roslynTokens.Add(token); 72 | tokenCount++; 73 | } 74 | } 75 | } 76 | 77 | private class StarkRunner 78 | { 79 | private readonly byte[] _starkText; 80 | private readonly Stark.Compiler.Parsing.LexerInputOutput _lio; 81 | private readonly Lexer _lexer; 82 | 83 | public StarkRunner() 84 | { 85 | _starkText = Encoding.UTF8.GetBytes(new CodeBuilder().GenerateCode()); 86 | var vm = new VirtualArenaManager(); 87 | _lio = new LexerInputOutput(vm); 88 | _lexer = new Lexer(_lio); 89 | } 90 | 91 | public void Run() 92 | { 93 | _lio.Reset(VirtualArenaResetKind.KeepAllCommitted); 94 | _lexer.Run(_starkText); 95 | } 96 | } 97 | 98 | private class CodeBuilder 99 | { 100 | private Random _random; 101 | private readonly StringBuilder _builder; 102 | 103 | public CodeBuilder() 104 | { 105 | _random = new Random(1); 106 | // 10MB 107 | _builder = new StringBuilder(10 << 20); 108 | } 109 | 110 | public string GenerateCode() 111 | { 112 | _random = new Random(1); 113 | _builder.Length = 0; 114 | return PrepareCode(true); 115 | } 116 | 117 | private string PrepareCode(bool isCsharp) 118 | { 119 | var totalCount = SyntaxStats.Select(x => x.Item3).Sum(); 120 | var tokenList = SyntaxStats.OrderByDescending(x => x.Item3).Select(x => (x.Item1, (double)x.Item2 / x.Item3, (double)x.Item3 / totalCount, 0.0)).ToList(); 121 | for (var i = 0; i < tokenList.Count; i++) 122 | { 123 | var tokenPair = tokenList[i]; 124 | for (var j = 0; j <= i; j++) 125 | { 126 | tokenPair.Item4 += tokenList[j].Item3; 127 | } 128 | tokenList[i] = tokenPair; 129 | //totalPercent += tokenPair.Item3; 130 | ////if (SyntaxFacts.GetText(tokenPair.Item1) != string.Empty) continue; 131 | //Console.WriteLine($"{tokenPair.Item1} {tokenPair.Item2} {tokenPair.Item4 * 100}%"); 132 | } 133 | 134 | _builder.Length = 0; 135 | 136 | var percents = tokenList.Select(x => x.Item4).ToList(); 137 | 138 | //Console.WriteLine($"{totalPercent * 100}%"); 139 | 140 | bool isPreviousKeywordOrIdentifier = false; 141 | while (true) 142 | { 143 | var percentage = _random.NextDouble(); 144 | var index = percents.BinarySearch(percentage); 145 | if (index < 0) 146 | { 147 | index = ~index; 148 | } 149 | var kind = tokenList[index].Item1; 150 | var text = GetText(kind, isCsharp); 151 | if (_builder.Length + text.Length + 1 > _builder.Capacity) 152 | { 153 | break; 154 | } 155 | 156 | var nextIsKeywordOrIdentifier = IsKeywordOrIdentifier(kind); 157 | if (nextIsKeywordOrIdentifier && isPreviousKeywordOrIdentifier) 158 | { 159 | _builder.Append(' '); 160 | } 161 | isPreviousKeywordOrIdentifier = nextIsKeywordOrIdentifier; 162 | 163 | _builder.Append(text); 164 | } 165 | 166 | return _builder.ToString(); 167 | } 168 | } 169 | 170 | 171 | 172 | 173 | /// 174 | /// true if the kind is a keyword or an identifier. 175 | /// 176 | private static bool IsKeywordOrIdentifier(SyntaxKind kind) 177 | { 178 | return SyntaxFacts.IsKeywordKind(kind) || kind == SyntaxKind.IdentifierToken; 179 | } 180 | 181 | /// 182 | /// Get the text associated to a specific SyntaxKind 183 | /// 184 | private static string GetText(SyntaxKind kind, bool isCsharp) 185 | { 186 | switch (kind) 187 | { 188 | case SyntaxKind.WhitespaceTrivia: 189 | return " "; 190 | // 5.663806850820647 24.89375682562034% 191 | case SyntaxKind.IdentifierToken: 192 | return "abcDEFgZ_1"; 193 | // 10.885354429437067 21.51937860751891 % 194 | case SyntaxKind.EndOfLineTrivia: 195 | return "\r\n"; 196 | // 2 12.115911115803648 % 197 | case SyntaxKind.StringLiteralToken: 198 | return "\"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\""; 199 | // 99.28415660665608 1.5735030439692832 % 200 | case SyntaxKind.SingleLineCommentTrivia: 201 | return "// 012345678901234567890123456789012345678901234567890123456789\r\n"; 202 | // 64.87759382725298 0.9787606129375346 % 203 | case SyntaxKind.NumericLiteralToken: 204 | return "59"; 205 | // 2.0525428325492 0.8883035786671392 % 206 | case SyntaxKind.SingleLineDocumentationCommentTrivia: 207 | return "/// 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\r\n"; 208 | // 228.0139344262295 0.09584088276680373 % 209 | case SyntaxKind.InterpolatedStringToken: 210 | return "\"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\""; 211 | // 198.84106483921983 0.01986996225230893 % 212 | case SyntaxKind.CharacterLiteralToken: 213 | return "'Z'"; 214 | // 3.2856743926277576 0.018754437223383835 % 215 | case SyntaxKind.MultiLineCommentTrivia: 216 | return "/* 0123456789\r\n0123456789\r\n0123456789\r\n0123456789 */"; 217 | // 41.819397993311036 0.003131849611723969 % 218 | default: 219 | return SyntaxFacts.GetText(kind); 220 | } 221 | } 222 | 223 | /// 224 | /// Statistics extracted from Roslyn codebase in order to be closer to reality 225 | /// (SyntaxKind, TotalLength, TotalCount) 226 | /// 227 | private static readonly (SyntaxKind, int, int)[] SyntaxStats = new[] 228 | { 229 | (SyntaxKind.IdentifierToken, 44727290, 4108942), 230 | (SyntaxKind.StringLiteralToken, 29829627, 300447), 231 | (SyntaxKind.WhitespaceTrivia, 26946405, 4757649), 232 | (SyntaxKind.SingleLineCommentTrivia, 12124714, 186886), 233 | (SyntaxKind.EndOfLineTrivia, 4626860, 2313430), 234 | (SyntaxKind.SingleLineDocumentationCommentTrivia, 4172655, 18300), 235 | (SyntaxKind.DotToken, 1125009, 1125009), 236 | (SyntaxKind.OpenParenToken, 1039686, 1039686), 237 | (SyntaxKind.CloseParenToken, 1039686, 1039686), 238 | //(SyntaxKind.DisabledTextTrivia, 923442, 986), 239 | (SyntaxKind.PublicKeyword, 768546, 128091), 240 | (SyntaxKind.InterpolatedStringToken, 754403, 3794), 241 | (SyntaxKind.CommaToken, 740607, 740607), 242 | (SyntaxKind.SemicolonToken, 693748, 693748), 243 | (SyntaxKind.ReturnKeyword, 441630, 73605), 244 | (SyntaxKind.NumericLiteralToken, 348140, 169614), 245 | (SyntaxKind.UsingKeyword, 291825, 58365), 246 | (SyntaxKind.OpenBraceToken, 286184, 286184), 247 | (SyntaxKind.CloseBraceToken, 286184, 286184), 248 | (SyntaxKind.EqualsToken, 285734, 285734), 249 | (SyntaxKind.StringKeyword, 270936, 45156), 250 | (SyntaxKind.PrivateKeyword, 238378, 34054), 251 | (SyntaxKind.VoidKeyword, 217380, 54345), 252 | (SyntaxKind.InternalKeyword, 208024, 26003), 253 | (SyntaxKind.NewKeyword, 206979, 68993), 254 | (SyntaxKind.ThisKeyword, 198024, 49506), 255 | (SyntaxKind.OverrideKeyword, 178144, 22268), 256 | (SyntaxKind.NullKeyword, 168940, 42235), 257 | (SyntaxKind.StaticKeyword, 144066, 24011), 258 | (SyntaxKind.OpenBracketToken, 136945, 136945), 259 | (SyntaxKind.CloseBracketToken, 136945, 136945), 260 | (SyntaxKind.ClassKeyword, 116505, 23301), 261 | (SyntaxKind.ColonToken, 115938, 115938), 262 | (SyntaxKind.ReadOnlyKeyword, 112248, 14031), 263 | (SyntaxKind.FalseKeyword, 110795, 22159), 264 | (SyntaxKind.BoolKeyword, 107752, 26938), 265 | (SyntaxKind.IfKeyword, 106706, 53353), 266 | (SyntaxKind.NamespaceKeyword, 84753, 9417), 267 | (SyntaxKind.CaseKeyword, 83264, 20816), 268 | (SyntaxKind.LessThanToken, 81387, 81387), 269 | (SyntaxKind.GreaterThanToken, 81330, 81330), 270 | (SyntaxKind.ProtectedKeyword, 79965, 8885), 271 | (SyntaxKind.IntKeyword, 79572, 26524), 272 | (SyntaxKind.EqualsGreaterThanToken, 78710, 39355), 273 | (SyntaxKind.TrueKeyword, 76492, 19123), 274 | (SyntaxKind.DefaultKeyword, 65268, 9324), 275 | (SyntaxKind.ObjectKeyword, 56886, 9481), 276 | (SyntaxKind.EqualsEqualsToken, 55776, 27888), 277 | (SyntaxKind.ForEachKeyword, 48727, 6961), 278 | (SyntaxKind.AbstractKeyword, 47200, 5900), 279 | //(SyntaxKind.RegionDirectiveTrivia, 44800, 1461), 280 | (SyntaxKind.ExclamationEqualsToken, 41962, 20981), 281 | (SyntaxKind.OutKeyword, 40203, 13401), 282 | (SyntaxKind.ElseKeyword, 34940, 8735), 283 | (SyntaxKind.ByteKeyword, 32008, 8002), 284 | (SyntaxKind.ThrowKeyword, 31320, 6264), 285 | //(SyntaxKind.NullableDirectiveTrivia, 29796, 1808), 286 | (SyntaxKind.TypeOfKeyword, 28188, 4698), 287 | (SyntaxKind.QuestionToken, 27079, 27079), 288 | (SyntaxKind.AmpersandAmpersandToken, 26492, 13246), 289 | (SyntaxKind.SealedKeyword, 26226, 4371), 290 | (SyntaxKind.BreakKeyword, 26165, 5233), 291 | //(SyntaxKind.PragmaWarningDirectiveTrivia, 25443, 354), 292 | (SyntaxKind.MultiLineCommentTrivia, 25008, 598), 293 | (SyntaxKind.BaseKeyword, 22664, 5666), 294 | (SyntaxKind.ConstKeyword, 22515, 4503), 295 | (SyntaxKind.SwitchKeyword, 21972, 3662), 296 | (SyntaxKind.BarBarToken, 21320, 10660), 297 | (SyntaxKind.RefKeyword, 20508, 6836), 298 | (SyntaxKind.VirtualKeyword, 20146, 2878), 299 | //(SyntaxKind.EndRegionDirectiveTrivia, 18452, 1461), 300 | (SyntaxKind.ExclamationToken, 15785, 15785), 301 | (SyntaxKind.InKeyword, 15712, 7856), 302 | (SyntaxKind.IsKeyword, 13168, 6584), 303 | (SyntaxKind.ContinueKeyword, 13000, 1625), 304 | //(SyntaxKind.IfDirectiveTrivia, 12873, 1018), 305 | (SyntaxKind.CharacterLiteralToken, 11766, 3581), 306 | (SyntaxKind.UIntKeyword, 8548, 2137), 307 | (SyntaxKind.PlusToken, 8471, 8471), 308 | (SyntaxKind.InterfaceKeyword, 7902, 878), 309 | (SyntaxKind.ParamsKeyword, 7572, 1262), 310 | (SyntaxKind.ForKeyword, 7515, 2505), 311 | (SyntaxKind.WhileKeyword, 6955, 1391), 312 | (SyntaxKind.StructKeyword, 6414, 1069), 313 | (SyntaxKind.PlusPlusToken, 6380, 3190), 314 | //(SyntaxKind.EndIfDirectiveTrivia, 6306, 1018), 315 | (SyntaxKind.AsKeyword, 5942, 2971), 316 | (SyntaxKind.CatchKeyword, 5625, 1125), 317 | (SyntaxKind.CharKeyword, 5164, 1291), 318 | (SyntaxKind.QuestionQuestionToken, 4628, 2314), 319 | (SyntaxKind.MinusToken, 4290, 4290), 320 | (SyntaxKind.TryKeyword, 4212, 1404), 321 | (SyntaxKind.BarToken, 3986, 3986), 322 | (SyntaxKind.GreaterThanEqualsToken, 3378, 1689), 323 | (SyntaxKind.UShortKeyword, 3000, 500), 324 | (SyntaxKind.FinallyKeyword, 2954, 422), 325 | (SyntaxKind.LongKeyword, 2424, 606), 326 | (SyntaxKind.DoubleKeyword, 2400, 400), 327 | (SyntaxKind.LockKeyword, 2172, 543), 328 | (SyntaxKind.EnumKeyword, 2120, 530), 329 | (SyntaxKind.UncheckedKeyword, 2061, 229), 330 | (SyntaxKind.PlusEqualsToken, 1946, 973), 331 | (SyntaxKind.ULongKeyword, 1785, 357), 332 | (SyntaxKind.OperatorKeyword, 1752, 219), 333 | (SyntaxKind.LessThanEqualsToken, 1662, 831), 334 | (SyntaxKind.ShortKeyword, 1520, 304), 335 | (SyntaxKind.AmpersandToken, 1456, 1456), 336 | (SyntaxKind.DelegateKeyword, 1432, 179), 337 | (SyntaxKind.GotoKeyword, 1372, 343), 338 | (SyntaxKind.BarEqualsToken, 1356, 678), 339 | (SyntaxKind.LessThanLessThanToken, 1272, 636), 340 | (SyntaxKind.EventKeyword, 1235, 247), 341 | (SyntaxKind.DecimalKeyword, 1071, 153), 342 | (SyntaxKind.AsteriskToken, 1009, 1009), 343 | (SyntaxKind.UnsafeKeyword, 966, 161), 344 | (SyntaxKind.SByteKeyword, 920, 184), 345 | (SyntaxKind.FloatKeyword, 800, 160), 346 | (SyntaxKind.MinusMinusToken, 698, 349), 347 | (SyntaxKind.MinusEqualsToken, 682, 341), 348 | (SyntaxKind.QuestionQuestionEqualsToken, 663, 221), 349 | (SyntaxKind.ExternKeyword, 636, 106), 350 | //(SyntaxKind.ElseDirectiveTrivia, 575, 115), 351 | (SyntaxKind.SizeOfKeyword, 498, 83), 352 | (SyntaxKind.ImplicitKeyword, 424, 53), 353 | //(SyntaxKind.ElifDirectiveTrivia, 310, 17), 354 | (SyntaxKind.AmpersandEqualsToken, 280, 140), 355 | (SyntaxKind.DoKeyword, 264, 132), 356 | (SyntaxKind.TildeToken, 250, 250), 357 | //(SyntaxKind.ErrorDirectiveTrivia, 224, 7), 358 | (SyntaxKind.FixedKeyword, 210, 42), 359 | (SyntaxKind.CheckedKeyword, 210, 30), 360 | (SyntaxKind.SlashToken, 182, 182), 361 | //(SyntaxKind.DefineDirectiveTrivia, 161, 6), 362 | (SyntaxKind.ColonColonToken, 136, 68), 363 | (SyntaxKind.ExplicitKeyword, 136, 17), 364 | (SyntaxKind.PercentToken, 100, 100), 365 | (SyntaxKind.CaretToken, 90, 90), 366 | (SyntaxKind.VolatileKeyword, 88, 11), 367 | //(SyntaxKind.LineDirectiveTrivia, 70, 4), 368 | (SyntaxKind.AsteriskEqualsToken, 40, 20), 369 | (SyntaxKind.DotDotToken, 28, 14), 370 | (SyntaxKind.MinusGreaterThanToken, 22, 11), 371 | (SyntaxKind.LessThanLessThanEqualsToken, 18, 6), 372 | (SyntaxKind.CaretEqualsToken, 12, 6), 373 | (SyntaxKind.SlashEqualsToken, 8, 4), 374 | //(SyntaxKind.BadToken, 6, 6), 375 | (SyntaxKind.PercentEqualsToken, 4, 2), 376 | //(SyntaxKind.EndOfFileToken, 0, 9407), 377 | }; 378 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler.BenchApp/Program.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Running; 2 | 3 | namespace Stark.Compiler.BenchApp; 4 | 5 | internal class Program 6 | { 7 | static void Main(string[] args) 8 | { 9 | //var benchLexer = new BenchLexer(); 10 | //for (int i = 0; i < 100; i++) 11 | //{ 12 | // //benchLexer.Roslyn(); 13 | // benchLexer.Stark(); 14 | //} 15 | BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); 16 | //BenchmarkDotNet.Running.BenchmarkRunner.Run(); 17 | } 18 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler.BenchApp/Stark.Compiler.BenchApp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | enable 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler.SourceGen/DiagnosticMessagesGenerator.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using System; 3 | using Microsoft.CodeAnalysis.CSharp.Syntax; 4 | using Microsoft.CodeAnalysis.Text; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | using Microsoft.CodeAnalysis.CSharp; 11 | 12 | namespace Stark.Compiler.SourceGen; 13 | 14 | /// 15 | /// This generator generates the DiagnosticMessages class from the DiagnosticId enum. 16 | /// 17 | [Generator] 18 | public class DiagnosticMessagesGenerator : IIncrementalGenerator 19 | { 20 | public void Initialize(IncrementalGeneratorInitializationContext context) 21 | { 22 | // We make sure to not depend on CompilationProvider to avoid having this generator being called on every key stroke for any files in a project. 23 | var enumDeclarations = context.SyntaxProvider 24 | .CreateSyntaxProvider(predicate: static (s, _) => s is EnumDeclarationSyntax enumDecl && enumDecl.Identifier.Text == "DiagnosticId", 25 | transform: static (context, _) => (EnumDeclarationSyntax)context.Node); 26 | 27 | context.RegisterSourceOutput(enumDeclarations, static (spc, source) => Execute(source, spc)); 28 | } 29 | 30 | private static void Execute(EnumDeclarationSyntax diagnosticIdEnum, SourceProductionContext context) 31 | { 32 | var enumsToGenerate = new List(); 33 | EnumMemberDeclarationSyntax? currentMember = null; 34 | 35 | foreach (var member1 in diagnosticIdEnum.Members.GetWithSeparators()) 36 | { 37 | if (member1.IsToken && currentMember != null) 38 | { 39 | Log($"Token: {member1.AsToken().ToFullString()}"); 40 | var comment = member1.AsToken().TrailingTrivia.FirstOrDefault(x => x.IsKind(SyntaxKind.SingleLineCommentTrivia)); 41 | if (comment != null) 42 | { 43 | var commentAsText = comment.ToFullString(); 44 | if (commentAsText.StartsWith("// ")) 45 | { 46 | enumsToGenerate.Add(new DiagnosticEnumToGenerate(currentMember.Identifier.Text, commentAsText)); 47 | } 48 | } 49 | } 50 | else if (member1.IsNode) 51 | { 52 | var node = member1.AsNode()!; 53 | Log($"Syntax ({node.Kind()}: {node.ToFullString()}"); 54 | currentMember = node as EnumMemberDeclarationSyntax; 55 | } 56 | } 57 | 58 | // If there were errors in the EnumDeclarationSyntax, we won't create an 59 | // EnumToGenerate for it, so make sure we have something to generate 60 | if (enumsToGenerate.Count > 0) 61 | { 62 | // generate the source code and add it to the output 63 | string result = GenerateExtensionClass(enumsToGenerate); 64 | Log($"We have some stuff to generate: {result}"); 65 | 66 | context.AddSource("DiagnosticMessages.g.cs", SourceText.From(result, Encoding.UTF8)); 67 | } 68 | } 69 | 70 | private static string GenerateExtensionClass(List enumsToGenerate) 71 | { 72 | var sb = new StringBuilder(); 73 | sb.Append(@"// This file is auto-generated from DiagnosticId 74 | namespace Stark.Compiler.Diagnostics; 75 | 76 | public static partial class DiagnosticMessages 77 | {"); 78 | foreach (var enumToGenerate in enumsToGenerate) 79 | { 80 | // public static DiagnosticMessage ERR_InvalidCharacter(string c) => 81 | // new(DiagnosticId.ERR_InvalidCharacter, $"The character `{c}` is invalid in a string"); 82 | var arguments = enumToGenerate.Description.Substring("// ".Length); 83 | string description = arguments; 84 | if (arguments.StartsWith("(")) 85 | { 86 | var index = arguments.IndexOf(")"); 87 | if (index > 0) 88 | { 89 | description = arguments.Substring(index + 1); 90 | description = description.Trim(); 91 | arguments = arguments.Substring(0, index + 1); 92 | if (description.StartsWith("=>")) 93 | { 94 | description = description.Substring("=>".Length).Trim(); 95 | } 96 | } 97 | } 98 | else 99 | { 100 | arguments = "()"; 101 | } 102 | 103 | sb.Append($@" 104 | public static DiagnosticMessage {enumToGenerate.Name}{arguments} => 105 | new(DiagnosticId.{enumToGenerate.Name}, $""{description}""); 106 | "); 107 | } 108 | 109 | sb.Append(@" 110 | } 111 | "); 112 | 113 | // Normalize new lines 114 | return sb.ToString().Replace("\r\n", "\n").Replace("\n", Environment.NewLine); 115 | } 116 | 117 | [Conditional("DEBUG")] 118 | private static void Log(string message) 119 | { 120 | // Uncomment this line to get some log 121 | //File.AppendAllText(@"C:\code\stark\stark\src\Stark.Compiler\Stark.Compiler\roslyn.log", $"{DateTime.Now} {message}{Environment.NewLine}"); 122 | } 123 | 124 | public readonly struct DiagnosticEnumToGenerate 125 | { 126 | public readonly string Name; 127 | public readonly string Description; 128 | 129 | public DiagnosticEnumToGenerate(string name, string description) 130 | { 131 | Name = name; 132 | Description = description; 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler.SourceGen/Stark.Compiler.SourceGen.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 10.0 6 | enable 7 | false 8 | false 9 | 10 | 11 | 12 | 13 | all 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler.Tests/Stark.Compiler.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32825.248 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stark.Compiler", "Stark.Compiler\Stark.Compiler.csproj", "{AAB22D03-9EA4-4946-B66A-93D110F6003A}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9514F3C8-C6EB-47E4-B9FC-3D9A1C244E4F}" 9 | ProjectSection(SolutionItems) = preProject 10 | .editorconfig = .editorconfig 11 | global.json = global.json 12 | EndProjectSection 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stark.Compiler.SourceGen", "Stark.Compiler.SourceGen\Stark.Compiler.SourceGen.csproj", "{7D9F593D-21A3-43AF-B15D-4870D47BD601}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stark.Compiler.Tests", "Stark.Compiler.Tests\Stark.Compiler.Tests.csproj", "{D12ADA97-DD5A-46C6-85DF-7EB8FB031C35}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stark.Compiler.BenchApp", "Stark.Compiler.BenchApp\Stark.Compiler.BenchApp.csproj", "{CC731DB5-8E5C-439C-80B8-3086346269FC}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Release|Any CPU = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {AAB22D03-9EA4-4946-B66A-93D110F6003A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {AAB22D03-9EA4-4946-B66A-93D110F6003A}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {AAB22D03-9EA4-4946-B66A-93D110F6003A}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {AAB22D03-9EA4-4946-B66A-93D110F6003A}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {7D9F593D-21A3-43AF-B15D-4870D47BD601}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {7D9F593D-21A3-43AF-B15D-4870D47BD601}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {7D9F593D-21A3-43AF-B15D-4870D47BD601}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {7D9F593D-21A3-43AF-B15D-4870D47BD601}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {D12ADA97-DD5A-46C6-85DF-7EB8FB031C35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {D12ADA97-DD5A-46C6-85DF-7EB8FB031C35}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {D12ADA97-DD5A-46C6-85DF-7EB8FB031C35}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {D12ADA97-DD5A-46C6-85DF-7EB8FB031C35}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {CC731DB5-8E5C-439C-80B8-3086346269FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {CC731DB5-8E5C-439C-80B8-3086346269FC}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {CC731DB5-8E5C-439C-80B8-3086346269FC}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {CC731DB5-8E5C-439C-80B8-3086346269FC}.Release|Any CPU.Build.0 = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | GlobalSection(ExtensibilityGlobals) = postSolution 47 | SolutionGuid = {ACA7F631-F49F-47B5-8171-7B8656F24435} 48 | EndGlobalSection 49 | EndGlobal 50 | -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | ERR 3 | SK 4 | True -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Collections/InlineList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Diagnostics; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | namespace Stark.Compiler.Collections; 7 | 8 | /// 9 | /// Lightweight struct list with optimized behavior over : 10 | /// - by ref on this[int index] 11 | /// - AddByRef(in T item) 12 | /// - RemoveAt returning remove item T 13 | /// - Settable Count 14 | /// - Underlying array accessible (pinnable...etc.) 15 | /// - Push/Pop methods 16 | /// 17 | /// Type of an item 18 | [DebuggerTypeProxy(typeof(InlineList<>.DebugListView)), DebuggerDisplay("Count = {Count}")] 19 | public struct InlineList : IEnumerable 20 | { 21 | private const int DefaultCapacity = 4; 22 | 23 | private static readonly InlineList Empty = new InlineList(0); 24 | 25 | public uint Count; 26 | 27 | public T[] Items; 28 | 29 | public InlineList(uint capacity) 30 | { 31 | Count = 0; 32 | Items = capacity == 0 ? Array.Empty() : new T[capacity]; 33 | } 34 | 35 | public uint Capacity 36 | { 37 | get => (uint)(Items?.Length ?? 0); 38 | set 39 | { 40 | Ensure(); 41 | if (value <= Items.Length) return; 42 | EnsureCapacity(value); 43 | } 44 | } 45 | 46 | public static InlineList Create() 47 | { 48 | return Empty; 49 | } 50 | 51 | public static InlineList Create(uint capacity) 52 | { 53 | return new InlineList(capacity); 54 | } 55 | 56 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 57 | public void Ensure() 58 | { 59 | if (Items == null) Items = Array.Empty(); 60 | } 61 | 62 | public bool IsReadOnly => false; 63 | 64 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 65 | public void Clear() 66 | { 67 | if (Count > 0) 68 | { 69 | Array.Clear(Items, 0, (int)Count); 70 | Count = 0; 71 | } 72 | } 73 | 74 | public InlineList Clone() 75 | { 76 | var items = (T[])Items?.Clone(); 77 | return new InlineList() { Count = Count, Items = items }; 78 | } 79 | 80 | public bool Contains(T item) 81 | { 82 | return Count > 0 && IndexOf(item) >= 0; 83 | } 84 | 85 | public void CopyTo(T[] array, int arrayIndex) 86 | { 87 | if (array == null) throw new ArgumentNullException(nameof(array)); 88 | if (Count > 0) 89 | { 90 | System.Array.Copy(Items, 0, array, arrayIndex, Count); 91 | } 92 | } 93 | 94 | public void Reset() 95 | { 96 | Clear(); 97 | Count = 0; 98 | } 99 | 100 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 101 | public void Add(T child) 102 | { 103 | if (Count == Items.Length) 104 | { 105 | EnsureCapacity(Count + 1); 106 | } 107 | Items[Count++] = child; 108 | } 109 | 110 | public ref T GetOrCreate(uint index) 111 | { 112 | if (index >= Count) 113 | { 114 | var newCount = index + 1; 115 | EnsureCapacity(newCount); 116 | Count = newCount; 117 | } 118 | return ref Items[index]; 119 | } 120 | 121 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 122 | public void AddByRef(in T child) 123 | { 124 | if (Count == Items.Length) 125 | { 126 | EnsureCapacity(Count + 1); 127 | } 128 | Items[Count++] = child; 129 | } 130 | 131 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 132 | public ref T AddByRefCurrent() 133 | { 134 | if (Count == Items.Length) 135 | { 136 | EnsureCapacity(Count + 1); 137 | } 138 | return ref Items[Count++]; 139 | } 140 | 141 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 142 | public void Insert(int index, T item) 143 | { 144 | if (Count == Items.Length) 145 | { 146 | EnsureCapacity(Count + 1); 147 | } 148 | if (index < Count) 149 | { 150 | Array.Copy(Items, index, Items, index + 1, Count - index); 151 | } 152 | Items[index] = item; 153 | Count++; 154 | } 155 | 156 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 157 | public ref T InsertReturnRef(int index, T item) 158 | { 159 | if (Count == Items.Length) 160 | { 161 | EnsureCapacity(Count + 1); 162 | } 163 | if (index < Count) 164 | { 165 | Array.Copy(Items, index, Items, index + 1, Count - index); 166 | } 167 | 168 | ref var refItem = ref Items[index]; 169 | refItem = item; 170 | Count++; 171 | return ref refItem; 172 | } 173 | 174 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 175 | public void InsertByRef(int index, in T item) 176 | { 177 | if (Count == Items.Length) 178 | { 179 | EnsureCapacity(Count + 1); 180 | } 181 | if (index < Count) 182 | { 183 | Array.Copy(Items, index, Items, index + 1, Count - index); 184 | } 185 | Items[index] = item; 186 | Count++; 187 | } 188 | 189 | public bool Remove(T element) 190 | { 191 | var index = IndexOf(element); 192 | if (index >= 0) 193 | { 194 | RemoveAt((uint)index); 195 | return true; 196 | } 197 | return false; 198 | } 199 | 200 | public int IndexOf(T element) 201 | { 202 | return Array.IndexOf(Items, element, 0, (int)Count); 203 | } 204 | 205 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 206 | public T RemoveAt(uint index) 207 | { 208 | #if DEBUG 209 | if (index >= Count) throw new ArgumentOutOfRangeException(nameof(index), $"Index must be < {Count}."); 210 | #endif 211 | Count--; 212 | // previous children 213 | var item = Items[index]; 214 | if (index < Count) 215 | { 216 | Array.Copy(Items, index + 1, Items, index, Count - index); 217 | } 218 | Items[Count] = default(T); 219 | return item; 220 | } 221 | 222 | public T RemoveLast() 223 | { 224 | if (Count > 0) 225 | { 226 | ref var removed = ref Items[Count - 1]; 227 | var copy = removed; 228 | removed = default; 229 | Count--; 230 | return copy; 231 | } 232 | return default; 233 | } 234 | 235 | public ref T this[uint index] 236 | { 237 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 238 | get 239 | { 240 | #if DEBUG 241 | if (index >= Count) throw new ArgumentOutOfRangeException(nameof(index), $"Index must be < {Count}."); 242 | #endif 243 | return ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Items), (IntPtr)index); 244 | } 245 | } 246 | 247 | public void Push(T element) 248 | { 249 | Add(element); 250 | } 251 | 252 | public ref T Peek() 253 | { 254 | return ref Items[Count - 1]; 255 | } 256 | 257 | public T Pop() 258 | { 259 | return RemoveAt(Count - 1); 260 | } 261 | 262 | private void EnsureCapacity(uint min) 263 | { 264 | if (Items.Length < min) 265 | { 266 | uint num = (Items.Length == 0) ? DefaultCapacity : ((uint)Items.Length) << 1; 267 | if (num < min) 268 | { 269 | num = min; 270 | } 271 | var destinationArray = new T[num]; // ArrayPool.Shared.Rent(num); 272 | if (Count > 0) 273 | { 274 | Array.Copy(Items, 0, destinationArray, 0, Count); 275 | } 276 | if (Items.Length > 0) 277 | { 278 | //ArrayPool.Shared.Return(Items, true); 279 | } 280 | Items = destinationArray; 281 | } 282 | } 283 | 284 | public Enumerator GetEnumerator() 285 | { 286 | return new Enumerator(this); 287 | } 288 | 289 | IEnumerator IEnumerable.GetEnumerator() 290 | { 291 | return GetEnumerator(); 292 | } 293 | 294 | IEnumerator IEnumerable.GetEnumerator() 295 | { 296 | return GetEnumerator(); 297 | } 298 | 299 | public struct Enumerator : IEnumerator 300 | { 301 | private readonly InlineList list; 302 | private uint index; 303 | private T current; 304 | 305 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 306 | internal Enumerator(InlineList list) 307 | { 308 | this.list = list; 309 | index = 0; 310 | current = default(T); 311 | } 312 | 313 | public T Current => current; 314 | 315 | object IEnumerator.Current => Current; 316 | 317 | 318 | public void Dispose() 319 | { 320 | } 321 | 322 | public bool MoveNext() 323 | { 324 | if (index < list.Count) 325 | { 326 | current = list[index]; 327 | index++; 328 | return true; 329 | } 330 | return MoveNextRare(); 331 | } 332 | 333 | private bool MoveNextRare() 334 | { 335 | index = list.Count + 1; 336 | current = default(T); 337 | return false; 338 | } 339 | 340 | void IEnumerator.Reset() 341 | { 342 | index = 0; 343 | current = default(T); 344 | } 345 | } 346 | 347 | private class DebugListView 348 | { 349 | private readonly InlineList _collection; 350 | 351 | public DebugListView(InlineList collection) 352 | { 353 | this._collection = collection; 354 | } 355 | 356 | [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] 357 | public T[] Items 358 | { 359 | get 360 | { 361 | var array = new T[this._collection.Count]; 362 | for (uint i = 0; i < array.Length; i++) 363 | { 364 | array[i] = _collection[i]; 365 | } 366 | return array; 367 | } 368 | } 369 | } 370 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Diagnostics/Diagnostic.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | namespace Stark.Compiler.Diagnostics; 6 | 7 | public sealed class Diagnostic 8 | { 9 | public Diagnostic(DiagnosticKind kind, DiagnosticLocation location, DiagnosticMessage message) 10 | { 11 | Kind = kind; 12 | Location = location; 13 | Message = message; 14 | } 15 | 16 | public DiagnosticLocation Location { get; } 17 | 18 | public DiagnosticKind Kind { get; } 19 | 20 | public DiagnosticMessage Message { get; } 21 | 22 | public override string ToString() 23 | { 24 | // test 25 | // C:\code\stark\stark\src\Stark.Compiler\Stark.Compiler\Diagnostics\DiagnosticBag.cs(44,22,44,22): error CS1002: ; expected 26 | return $"{Location}: {SeverityToString(Kind)} SK{(int)Message.Id:0000}: {Message.Text}"; 27 | } 28 | 29 | private static string SeverityToString(DiagnosticKind kind) => kind switch 30 | { 31 | DiagnosticKind.Internal => "internal", 32 | DiagnosticKind.Info => "info", 33 | DiagnosticKind.Warning => "warning", 34 | DiagnosticKind.Error => "error", 35 | _ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null) 36 | }; 37 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Diagnostics/DiagnosticBag.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | using System.Collections; 6 | using System.Diagnostics; 7 | 8 | namespace Stark.Compiler.Diagnostics; 9 | 10 | [DebuggerTypeProxy(typeof(DiagnosticBagDebugView))] 11 | public class DiagnosticBag : IEnumerable 12 | { 13 | private readonly List _list; 14 | 15 | public DiagnosticBag() 16 | { 17 | _list = new List(); 18 | } 19 | 20 | public bool HasErrors { get; private set; } 21 | 22 | public int Count => _list.Count; 23 | 24 | public void Add(Diagnostic diagnostic) 25 | { 26 | if (diagnostic.Kind == DiagnosticKind.Error) 27 | { 28 | HasErrors = true; 29 | } 30 | 31 | _list.Add(diagnostic); 32 | } 33 | 34 | public void AddRange(IEnumerable collection) 35 | { 36 | foreach (var diagnostic in collection) 37 | { 38 | Add(diagnostic); 39 | } 40 | } 41 | 42 | public void Clear() 43 | { 44 | _list.Clear(); 45 | HasErrors = false; 46 | } 47 | 48 | public void CopyTo(DiagnosticBag diagnosticBag) 49 | { 50 | diagnosticBag._list.AddRange(_list); 51 | diagnosticBag.HasErrors = HasErrors; 52 | } 53 | 54 | public List.Enumerator GetEnumerator() 55 | { 56 | // List.Enumerator 57 | return _list.GetEnumerator(); 58 | } 59 | 60 | IEnumerator IEnumerable.GetEnumerator() 61 | { 62 | // List.Enumerator 63 | return _list.GetEnumerator(); 64 | } 65 | 66 | IEnumerator IEnumerable.GetEnumerator() 67 | { 68 | return ((IEnumerable)_list).GetEnumerator(); 69 | } 70 | 71 | 72 | internal sealed class DiagnosticBagDebugView 73 | { 74 | private readonly DiagnosticBag _collection; 75 | 76 | public DiagnosticBagDebugView(DiagnosticBag collection) 77 | { 78 | _collection = collection; 79 | } 80 | 81 | [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] 82 | public Diagnostic[] Items 83 | { 84 | get 85 | { 86 | var array = new Diagnostic[_collection.Count]; 87 | _collection._list.CopyTo(array, 0); 88 | return array; 89 | } 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Diagnostics/DiagnosticId.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | namespace Stark.Compiler.Diagnostics; 6 | 7 | // When modifying this file, the Stark.Compiler.SourceGenerator will generate 8 | // the DiagnosticMessages class with methods having the same name as the enum item and taking 9 | // arguments specified in the comment. 10 | // The following comment is then used as the string that will be displayed for the end user 11 | 12 | public enum DiagnosticId 13 | { 14 | ERR_InvalidInputExpectedEof = 90, // Invalid input. Unexpected EOF character (\x03) found before the end of the source code. 15 | 16 | ERR_InvalidHexNumberInString1 = 101, // (string c) => Unexpected hex number `{c}` following `\\u`. Expecting `\\u0000` to `\\uffff`. 17 | ERR_InvalidHexNumberInString2 = 102, // (string c) => Unexpected hex number `{c}` following `\\x`. Expecting `\\x0` to `\\xffff`. 18 | ERR_InvalidHexNumberInString3 = 103, // (string c) => Invalid hex number `{c}` following `\\U00HHHHHH`. Expecting 8 hex numbers from `\\U00000000` to `\\U0010FFFF`. 19 | ERR_UnexpectedEscapeCharacter = 104, // (string c) => Unsupported character `{c}` used as an escape sequence. 20 | ERR_UnexpectedEndOfString = 105, // Unexpected end of string without a terminating \". 21 | ERR_InvalidUtf8InString = 106, // (int c) => Invalid Unicode found in string `\\U{c:x8}` must be between `\\U00000000` to `\\U0010FFFF`. 22 | ERR_UnexpectedEndOfFileForInterpolatedString = 107, // (string c) => Unexpected end of file while parsing interpolated string. Missing a closing `{c}`. 23 | ERR_InvalidRawStringExpectingEmptyFirstLine = 108, // Invalid raw string literal. The first line of a multiline raw string literal must be empty. 24 | ERR_InvalidRawStringExpectingEmptyLastLine = 109, // Invalid raw string literal. The last line of a multiline raw string literal must be empty. 25 | ERR_InvalidRawStringExpectingSpaceToMatchClosing = 110, // Invalid raw string literal. Line does not start with the same whitespace as the closing line of the raw string literal 26 | ERR_InvalidRawStringExpectingEnoughQuotes = 111, // Invalid raw string literal. The raw string literal does not start with enough quote characters to allow this many consecutive quote characters as content 27 | ERR_InvalidRawStringUnexpectedEndOfString = 112, // (string c) => Invalid raw string literal. Expecting the terminating quotes `{c}`. 28 | ERR_InvalidRawStringExpectingAtLeastOneLine = 113, // Multi-line raw string literals must contain at least one line of content. 29 | ERR_InvalidRawStringUnexpectedMixSpaces = 114, // (string c, string d) => Invalid raw string literal. Line contains different whitespace `{c}` than previous lines (`{d}`). 30 | ERR_InvalidUtf8InRune = 115, // (int c) => Invalid Unicode found in rune `\\U{c:x8}` must be between `\\U00000000` to `\\U0010FFFF`. 31 | ERR_InvalidRuneTooManyCharacters = 116, // Invalid rune. Too many characters. Expecting a single rune. 32 | ERR_InvalidRuneCannotBeEmpty = 117, // Invalid rune. A rune cannot be empty. 33 | ERR_UnexpectedEndOfRune = 118, // Unexpected end of rune without a terminating \'. 34 | 35 | ERR_UnexpectedUnderscoreAfterDigit = 120, // Unexpected underscore found after digit. They can only be enclosed by digits. 36 | ERR_UnexpectedCharacterAfterDot = 121, // (string c) => Unexpected character `{c}` found after a dot while parsing a float. Expecting a digit 0-9. 37 | ERR_UnexpectedCharacterForExponent = 122, // (string c) => Unexpected character `{c}` found while parsing the exponent of a float. Expecting a digit 0-9. 38 | ERR_NumberOverflow = 123, // The number is overflowing 64 bit. 39 | ERR_InvalidHexNumberExpectingDigit = 124, // Invalid hexadecimal number. Expecting at least one [0-9a-fA-F] digit. 40 | ERR_InvalidOctalNumberExpectingDigit = 125, // Invalid octal number. Expecting at least one [0-7] digit. 41 | ERR_InvalidBinaryNumberExpectingDigit = 126, // Invalid binary number. Expecting at least one [0-1] digit. 42 | 43 | ERR_UnexpectedEndOfFileForMultiLineComment = 130, // (int c) => Unexpected end of file found while parsing a multi-line comment. Expecting {c} `*/` to close the comment. 44 | } 45 | -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Diagnostics/DiagnosticKind.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | namespace Stark.Compiler.Diagnostics; 6 | 7 | /// 8 | /// Describes the kind of a diagnostic. 9 | /// 10 | public enum DiagnosticKind 11 | { 12 | /// 13 | /// Used internally. 14 | /// 15 | Internal = 0, 16 | 17 | /// 18 | /// This is a diagnostic that provides an information. 19 | /// 20 | Info = 1, 21 | 22 | /// 23 | /// This is a warning about something suspicious but allowed. 24 | /// 25 | Warning = 2, 26 | 27 | /// 28 | /// Something is not allowed by the rules of the language or other authority. 29 | /// 30 | Error = 3, 31 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Diagnostics/DiagnosticLocation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | namespace Stark.Compiler.Diagnostics; 6 | 7 | /// 8 | /// A diagnostic location. This class is abstract because a location could 9 | /// be a specific line in a source file or a type/method from a precompiled library. 10 | /// 11 | public abstract class DiagnosticLocation 12 | { 13 | public sealed override string ToString() => ToText(); 14 | 15 | public abstract string ToText(); 16 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Diagnostics/DiagnosticMessage.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | namespace Stark.Compiler.Diagnostics; 6 | 7 | public record DiagnosticMessage(DiagnosticId Id, string Text); -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Diagnostics/DiagnosticSourceFileLocation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | namespace Stark.Compiler.Diagnostics; 6 | 7 | /// 8 | /// A location to a source file. 9 | /// 10 | public sealed class DiagnosticSourceFileLocation : DiagnosticLocation 11 | { 12 | public DiagnosticSourceFileLocation(string filePath, TextSpan span) 13 | { 14 | FilePath = filePath; 15 | Span = span; 16 | } 17 | 18 | public string FilePath { get; } 19 | 20 | public TextSpan Span { get; } 21 | 22 | public override string ToText() 23 | { 24 | return $"{FilePath}{Span.ToText()}"; 25 | } 26 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Helpers/HashHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | using System.Runtime.CompilerServices; 6 | 7 | namespace Stark.Compiler.Helpers; 8 | 9 | /// 10 | /// FNV-1a hash for identifiers/strings. Might be not fast enough for large strings. 11 | /// 12 | public static class HashHelper 13 | { 14 | public static int Init() => unchecked((int)2166136261); 15 | 16 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 17 | public static void Hash(byte b, ref int hash) 18 | { 19 | hash ^= b; 20 | hash *= 16777619; 21 | } 22 | 23 | public static int Hash(ReadOnlySpan bytes) 24 | { 25 | var hash = Init(); 26 | foreach (var b in bytes) 27 | { 28 | Hash(b, ref hash); 29 | } 30 | return hash; 31 | } 32 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Helpers/ThrowHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | namespace Stark.Compiler.Helpers; 6 | 7 | internal class ThrowHelper 8 | { 9 | 10 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Helpers/Utf8Class.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | namespace Stark.Compiler.Helpers; 6 | 7 | internal enum Utf8Class : byte 8 | { 9 | Eof, // End of file 10 | Sof, // Start of file 11 | CarriageReturn, // \r 12 | LineFeed, // \n 13 | Space, // " " 14 | Tab, // \t 15 | Digit, // Digit 16 | Letter, // Letter 17 | ExclamationMark, // ! 18 | DoubleQuote, // " 19 | NumberSign, // # 20 | DollarSign, // $ 21 | PercentSign, // % 22 | Ampersand, // & 23 | SingleQuote, // ' 24 | LeftParenthesis, // ( 25 | RightParenthesis, // ) 26 | Asterisk, // * 27 | PlusSign, // + 28 | Comma, // , 29 | MinusSign, // - 30 | Period, // . 31 | Slash, // / 32 | Colon, // : 33 | SemiColon, // ; 34 | LessThanSign, // < 35 | EqualSign, // = 36 | GreaterThanSign, // > 37 | QuestionMark, // ? 38 | CommercialAtSign, // @ 39 | LeftSquareBracket, // [ 40 | Backslash, // \ 41 | RightSquareBracket, // ] 42 | CircumflexAccent, // ^ 43 | Underscore, // _ 44 | GraveAccent, // ` 45 | LeftBrace, // { 46 | VerticalBar, // | 47 | RightBrace, // } 48 | TildeAccent, // ~ 49 | Invalid, // Special characters 50 | Utf8Value, // 80-BF 51 | Utf8Head2, // C0-DF 52 | Utf8Head3, // E0-EF 53 | Utf8Head4 // F0-F7 54 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Helpers/Utf8ClassMask.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | namespace Stark.Compiler.Helpers; 6 | 7 | [Flags] 8 | internal enum Utf8ClassMask : long 9 | { 10 | Eof = 1L << Utf8Class.Eof, 11 | Sof = 1L << Utf8Class.Sof, 12 | CarriageReturn = 1L << Utf8Class.CarriageReturn, 13 | LineFeed = 1L << Utf8Class.LineFeed, 14 | Space = 1L << Utf8Class.Space, 15 | Tab = 1L << Utf8Class.Tab, 16 | Digit = 1L << Utf8Class.Digit, 17 | Letter = 1L << Utf8Class.Letter, 18 | ExclamationMark = 1L << Utf8Class.ExclamationMark, 19 | DoubleQuote = 1L << Utf8Class.DoubleQuote, 20 | NumberSign = 1L << Utf8Class.NumberSign, 21 | DollarSign = 1L << Utf8Class.DollarSign, 22 | PercentSign = 1L << Utf8Class.PercentSign, 23 | Ampersand = 1L << Utf8Class.Ampersand, 24 | SingleQuote = 1L << Utf8Class.SingleQuote, 25 | LeftParenthesis = 1L << Utf8Class.LeftParenthesis, 26 | RightParenthesis = 1L << Utf8Class.RightParenthesis, 27 | Asterisk = 1L << Utf8Class.Asterisk, 28 | PlusSign = 1L << Utf8Class.PlusSign, 29 | Comma = 1L << Utf8Class.Comma, 30 | MinusSign = 1L << Utf8Class.MinusSign, 31 | Period = 1L << Utf8Class.Period, 32 | Slash = 1L << Utf8Class.Slash, 33 | Colon = 1L << Utf8Class.Colon, 34 | SemiColon = 1L << Utf8Class.SemiColon, 35 | LessThanSign = 1L << Utf8Class.LessThanSign, 36 | EqualSign = 1L << Utf8Class.EqualSign, 37 | GreaterThanSign = 1L << Utf8Class.GreaterThanSign, 38 | QuestionMark = 1L << Utf8Class.QuestionMark, 39 | CommercialAtSign = 1L << Utf8Class.CommercialAtSign, 40 | LeftSquareBracket = 1L << Utf8Class.LeftSquareBracket, 41 | Backslash = 1L << Utf8Class.Backslash, 42 | RightSquareBracket = 1L << Utf8Class.RightSquareBracket, 43 | CircumflexAccent = 1L << Utf8Class.CircumflexAccent, 44 | Underscore = 1L << Utf8Class.Underscore, 45 | GraveAccent = 1L << Utf8Class.GraveAccent, 46 | LeftBrace = 1L << Utf8Class.LeftBrace, 47 | VerticalBar = 1L << Utf8Class.VerticalBar, 48 | RightBrace = 1L << Utf8Class.RightBrace, 49 | TildeAccent = 1L << Utf8Class.TildeAccent, 50 | Invalid = 1L << Utf8Class.Invalid, 51 | Utf8Value = 1L << Utf8Class.Utf8Value, 52 | Utf8Head2 = 1L << Utf8Class.Utf8Head2, 53 | Utf8Head3 = 1L << Utf8Class.Utf8Head3, 54 | Utf8Head4 = 1L << Utf8Class.Utf8Head4 55 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Helpers/Utf8Helper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | using System.Globalization; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | using System.Text; 9 | 10 | namespace Stark.Compiler.Helpers; 11 | 12 | internal static class Utf8Helper 13 | { 14 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 15 | public static int GetWidth(Rune rune) => Wcwidth.UnicodeCalculator.GetWidth(rune); 16 | 17 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 18 | public static bool IsDigit(byte b) => (uint)(b - '0') <= ('9' - '0'); 19 | 20 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 21 | public static bool IsLetter(byte b) => (uint)((b - 'A') & ~0x20) <= ('Z' - 'A'); 22 | 23 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 24 | public static bool IsLetterOrUnderscore(byte b) => IsLetter(b) || b == (byte)'_'; 25 | 26 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 27 | public static bool IsLetterContinuationForIdentifier(byte b) => IsLetter(b) || b == (byte)'_' || IsDigit(b); 28 | 29 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 30 | public static bool IsHex(byte b) => IsDigit(b) || (uint)((b - 'A') & ~0x20) <= ('F' - 'A'); 31 | 32 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 33 | public static int HexToValue(byte b) => IsDigit(b) ? b - (byte)'0' : b >= (byte)'a' && b <= (byte)'f' ? b - (byte)'a' + 10 : b - (byte)'A' + 10; 34 | 35 | public static string ByteToSafeString(byte b) => b < ' ' || b >= 127 ? $"\\x{b:x2}" : ((char)b).ToString(CultureInfo.InvariantCulture); 36 | 37 | // UTF8 Characters 38 | // 1 byte: 00-7F 39 | // 2 byte: C0-DF 80-BF 40 | // 3 byte: E0-EF 80-BF 80-BF 41 | // 4 byte: F0-F7 80-BF 80-BF 80-BF 42 | 43 | public static Utf8Class GetClassFromByte(byte b) 44 | { 45 | // Equivalent to ByteToClass[b] but removes the bounds check because we know that we have only 256 values 46 | // 47 | // Generates the following code: 48 | // 49 | // Stark.Compiler.Parser.Utf8ClassHelper.GetClassFromByte2(Byte) 50 | // L0000: mov eax, 0x1a0c0eb0 51 | // L0005: movzx edx, cl 52 | // L0008: movzx eax, byte ptr [eax+edx] 53 | // L000c: ret 54 | // 55 | // Instead of: 56 | // 57 | // Stark.Compiler.Parser.Utf8ClassHelper.GetClassFromByte(Byte) 58 | // L0000: movzx eax, cl 59 | // L0003: cmp eax, 0x100 60 | // L0008: jae short L0012 61 | // L000a: movzx eax, byte ptr [eax+0x1a0c0eb0] 62 | // L0011: ret 63 | // L0012: call 0x71ff6250 64 | // L0017: int3 65 | return Unsafe.AddByteOffset(ref Unsafe.AsRef(MemoryMarshal.AsRef(MemoryMarshal.AsBytes(ByteToClass))), b); 66 | } 67 | 68 | private static ReadOnlySpan ByteToClass => new(new Utf8Class[256] 69 | { 70 | Utf8Class.Invalid, // 0x00, , 0 71 | Utf8Class.Invalid, // 0x01, , 1 72 | Utf8Class.Sof, // 0x02, , 2 73 | Utf8Class.Eof, // 0x03, , 3 74 | Utf8Class.Invalid, // 0x04, , 4 75 | Utf8Class.Invalid, // 0x05, , 5 76 | Utf8Class.Invalid, // 0x06, , 6 77 | Utf8Class.Invalid, // 0x07, , 7 78 | Utf8Class.Invalid, // 0x08, , 8 79 | Utf8Class.Tab, // 0x09, , 9 80 | Utf8Class.LineFeed, // 0x0A, , 10 81 | Utf8Class.Invalid, // 0x0B, , 11 82 | Utf8Class.Invalid, // 0x0C, , 12 83 | Utf8Class.CarriageReturn, // 0x0D, , 13 84 | Utf8Class.Invalid, // 0x0E, , 14 85 | Utf8Class.Invalid, // 0x0F, , 15 86 | Utf8Class.Invalid, // 0x10, , 16 87 | Utf8Class.Invalid, // 0x11, , 17 88 | Utf8Class.Invalid, // 0x12, , 18 89 | Utf8Class.Invalid, // 0x13, , 19 90 | Utf8Class.Invalid, // 0x14, , 20 91 | Utf8Class.Invalid, // 0x15, , 21 92 | Utf8Class.Invalid, // 0x16, , 22 93 | Utf8Class.Invalid, // 0x17, , 23 94 | Utf8Class.Invalid, // 0x18, , 24 95 | Utf8Class.Invalid, // 0x19, , 25 96 | Utf8Class.Invalid, // 0x1A, , 26 97 | Utf8Class.Invalid, // 0x1B, , 27 98 | Utf8Class.Invalid, // 0x1C, , 28 99 | Utf8Class.Invalid, // 0x1D, , 29 100 | Utf8Class.Invalid, // 0x1E, , 30 101 | Utf8Class.Invalid, // 0x1F, , 31 102 | Utf8Class.Space, // 0x20, , 32 103 | Utf8Class.ExclamationMark, // 0x21, !, 33 104 | Utf8Class.DoubleQuote, // 0x22, ", 34 105 | Utf8Class.NumberSign, // 0x23, #, 35 106 | Utf8Class.DollarSign, // 0x24, $, 36 107 | Utf8Class.PercentSign, // 0x25, %, 37 108 | Utf8Class.Ampersand, // 0x26, &, 38 109 | Utf8Class.SingleQuote, // 0x27, ', 39 110 | Utf8Class.LeftParenthesis, // 0x28, (, 40 111 | Utf8Class.RightParenthesis, // 0x29, ), 41 112 | Utf8Class.Asterisk, // 0x2A, *, 42 113 | Utf8Class.PlusSign, // 0x2B, +, 43 114 | Utf8Class.Comma, // 0x2C, ,, 44 115 | Utf8Class.MinusSign, // 0x2D, -, 45 116 | Utf8Class.Period, // 0x2E, ., 46 117 | Utf8Class.Slash, // 0x2F, /, 47 118 | Utf8Class.Digit, // 0x30, 0, 48 119 | Utf8Class.Digit, // 0x31, 1, 49 120 | Utf8Class.Digit, // 0x32, 2, 50 121 | Utf8Class.Digit, // 0x33, 3, 51 122 | Utf8Class.Digit, // 0x34, 4, 52 123 | Utf8Class.Digit, // 0x35, 5, 53 124 | Utf8Class.Digit, // 0x36, 6, 54 125 | Utf8Class.Digit, // 0x37, 7, 55 126 | Utf8Class.Digit, // 0x38, 8, 56 127 | Utf8Class.Digit, // 0x39, 9, 57 128 | Utf8Class.Colon, // 0x3A, :, 58 129 | Utf8Class.SemiColon, // 0x3B, ;, 59 130 | Utf8Class.LessThanSign, // 0x3C, <, 60 131 | Utf8Class.EqualSign, // 0x3D, =, 61 132 | Utf8Class.GreaterThanSign, // 0x3E, >, 62 133 | Utf8Class.QuestionMark, // 0x3F, ?, 63 134 | Utf8Class.CommercialAtSign, // 0x40, @, 64 135 | Utf8Class.Letter, // 0x41, A, 65 136 | Utf8Class.Letter, // 0x42, B, 66 137 | Utf8Class.Letter, // 0x43, C, 67 138 | Utf8Class.Letter, // 0x44, D, 68 139 | Utf8Class.Letter, // 0x45, E, 69 140 | Utf8Class.Letter, // 0x46, F, 70 141 | Utf8Class.Letter, // 0x47, G, 71 142 | Utf8Class.Letter, // 0x48, H, 72 143 | Utf8Class.Letter, // 0x49, I, 73 144 | Utf8Class.Letter, // 0x4A, J, 74 145 | Utf8Class.Letter, // 0x4B, K, 75 146 | Utf8Class.Letter, // 0x4C, L, 76 147 | Utf8Class.Letter, // 0x4D, M, 77 148 | Utf8Class.Letter, // 0x4E, N, 78 149 | Utf8Class.Letter, // 0x4F, O, 79 150 | Utf8Class.Letter, // 0x50, P, 80 151 | Utf8Class.Letter, // 0x51, Q, 81 152 | Utf8Class.Letter, // 0x52, R, 82 153 | Utf8Class.Letter, // 0x53, S, 83 154 | Utf8Class.Letter, // 0x54, T, 84 155 | Utf8Class.Letter, // 0x55, U, 85 156 | Utf8Class.Letter, // 0x56, V, 86 157 | Utf8Class.Letter, // 0x57, W, 87 158 | Utf8Class.Letter, // 0x58, X, 88 159 | Utf8Class.Letter, // 0x59, Y, 89 160 | Utf8Class.Letter, // 0x5A, Z, 90 161 | Utf8Class.LeftSquareBracket, // 0x5B, [, 91 162 | Utf8Class.Backslash, // 0x5C, \, 92 163 | Utf8Class.RightSquareBracket, // 0x5D, ], 93 164 | Utf8Class.CircumflexAccent, // 0x5E, ^, 94 165 | Utf8Class.Underscore, // 0x5F, _, 95 166 | Utf8Class.GraveAccent, // 0x60, `, 96 167 | Utf8Class.Letter, // 0x61, a, 97 168 | Utf8Class.Letter, // 0x62, b, 98 169 | Utf8Class.Letter, // 0x63, c, 99 170 | Utf8Class.Letter, // 0x64, d, 100 171 | Utf8Class.Letter, // 0x65, e, 101 172 | Utf8Class.Letter, // 0x66, f, 102 173 | Utf8Class.Letter, // 0x67, g, 103 174 | Utf8Class.Letter, // 0x68, h, 104 175 | Utf8Class.Letter, // 0x69, i, 105 176 | Utf8Class.Letter, // 0x6A, j, 106 177 | Utf8Class.Letter, // 0x6B, k, 107 178 | Utf8Class.Letter, // 0x6C, l, 108 179 | Utf8Class.Letter, // 0x6D, m, 109 180 | Utf8Class.Letter, // 0x6E, n, 110 181 | Utf8Class.Letter, // 0x6F, o, 111 182 | Utf8Class.Letter, // 0x70, p, 112 183 | Utf8Class.Letter, // 0x71, q, 113 184 | Utf8Class.Letter, // 0x72, r, 114 185 | Utf8Class.Letter, // 0x73, s, 115 186 | Utf8Class.Letter, // 0x74, t, 116 187 | Utf8Class.Letter, // 0x75, u, 117 188 | Utf8Class.Letter, // 0x76, v, 118 189 | Utf8Class.Letter, // 0x77, w, 119 190 | Utf8Class.Letter, // 0x78, x, 120 191 | Utf8Class.Letter, // 0x79, y, 121 192 | Utf8Class.Letter, // 0x7A, z, 122 193 | Utf8Class.LeftBrace, // 0x7B, {, 123 194 | Utf8Class.VerticalBar, // 0x7C, |, 124 195 | Utf8Class.RightBrace, // 0x7D, }, 125 196 | Utf8Class.TildeAccent, // 0x7E, ~, 126 197 | Utf8Class.Invalid, // 0x7F, , 127 198 | Utf8Class.Utf8Value, // 0x80, €, 128 199 | Utf8Class.Utf8Value, // 0x81, , 129 200 | Utf8Class.Utf8Value, // 0x82, ‚, 130 201 | Utf8Class.Utf8Value, // 0x83, ƒ, 131 202 | Utf8Class.Utf8Value, // 0x84, „, 132 203 | Utf8Class.Utf8Value, // 0x85, …, 133 204 | Utf8Class.Utf8Value, // 0x86, †, 134 205 | Utf8Class.Utf8Value, // 0x87, ‡, 135 206 | Utf8Class.Utf8Value, // 0x88, ˆ, 136 207 | Utf8Class.Utf8Value, // 0x89, ‰, 137 208 | Utf8Class.Utf8Value, // 0x8A, Š, 138 209 | Utf8Class.Utf8Value, // 0x8B, ‹, 139 210 | Utf8Class.Utf8Value, // 0x8C, Œ, 140 211 | Utf8Class.Utf8Value, // 0x8D, , 141 212 | Utf8Class.Utf8Value, // 0x8E, Ž, 142 213 | Utf8Class.Utf8Value, // 0x8F, , 143 214 | Utf8Class.Utf8Value, // 0x90, , 144 215 | Utf8Class.Utf8Value, // 0x91, ‘, 145 216 | Utf8Class.Utf8Value, // 0x92, ’, 146 217 | Utf8Class.Utf8Value, // 0x93, “, 147 218 | Utf8Class.Utf8Value, // 0x94, ”, 148 219 | Utf8Class.Utf8Value, // 0x95, •, 149 220 | Utf8Class.Utf8Value, // 0x96, –, 150 221 | Utf8Class.Utf8Value, // 0x97, —, 151 222 | Utf8Class.Utf8Value, // 0x98, ˜, 152 223 | Utf8Class.Utf8Value, // 0x99, ™, 153 224 | Utf8Class.Utf8Value, // 0x9A, š, 154 225 | Utf8Class.Utf8Value, // 0x9B, ›, 155 226 | Utf8Class.Utf8Value, // 0x9C, œ, 156 227 | Utf8Class.Utf8Value, // 0x9D, , 157 228 | Utf8Class.Utf8Value, // 0x9E, ž, 158 229 | Utf8Class.Utf8Value, // 0x9F, Ÿ, 159 230 | Utf8Class.Utf8Value, // 0xA0,  , 160 231 | Utf8Class.Utf8Value, // 0xA1, ¡, 161 232 | Utf8Class.Utf8Value, // 0xA2, ¢, 162 233 | Utf8Class.Utf8Value, // 0xA3, £, 163 234 | Utf8Class.Utf8Value, // 0xA4, ¤, 164 235 | Utf8Class.Utf8Value, // 0xA5, ¥, 165 236 | Utf8Class.Utf8Value, // 0xA6, ¦, 166 237 | Utf8Class.Utf8Value, // 0xA7, §, 167 238 | Utf8Class.Utf8Value, // 0xA8, ¨, 168 239 | Utf8Class.Utf8Value, // 0xA9, ©, 169 240 | Utf8Class.Utf8Value, // 0xAA, ª, 170 241 | Utf8Class.Utf8Value, // 0xAB, «, 171 242 | Utf8Class.Utf8Value, // 0xAC, ¬, 172 243 | Utf8Class.Utf8Value, // 0xAD, ­, 173 244 | Utf8Class.Utf8Value, // 0xAE, ®, 174 245 | Utf8Class.Utf8Value, // 0xAF, ¯, 175 246 | Utf8Class.Utf8Value, // 0xB0, °, 176 247 | Utf8Class.Utf8Value, // 0xB1, ±, 177 248 | Utf8Class.Utf8Value, // 0xB2, ², 178 249 | Utf8Class.Utf8Value, // 0xB3, ³, 179 250 | Utf8Class.Utf8Value, // 0xB4, ´, 180 251 | Utf8Class.Utf8Value, // 0xB5, µ, 181 252 | Utf8Class.Utf8Value, // 0xB6, ¶, 182 253 | Utf8Class.Utf8Value, // 0xB7, ·, 183 254 | Utf8Class.Utf8Value, // 0xB8, ¸, 184 255 | Utf8Class.Utf8Value, // 0xB9, ¹, 185 256 | Utf8Class.Utf8Value, // 0xBA, º, 186 257 | Utf8Class.Utf8Value, // 0xBB, », 187 258 | Utf8Class.Utf8Value, // 0xBC, ¼, 188 259 | Utf8Class.Utf8Value, // 0xBD, ½, 189 260 | Utf8Class.Utf8Value, // 0xBE, ¾, 190 261 | Utf8Class.Utf8Value, // 0xBF, ¿, 191 262 | Utf8Class.Utf8Head2, // 0xC0, À, 192 263 | Utf8Class.Utf8Head2, // 0xC1, Á, 193 264 | Utf8Class.Utf8Head2, // 0xC2, Â, 194 265 | Utf8Class.Utf8Head2, // 0xC3, Ã, 195 266 | Utf8Class.Utf8Head2, // 0xC4, Ä, 196 267 | Utf8Class.Utf8Head2, // 0xC5, Å, 197 268 | Utf8Class.Utf8Head2, // 0xC6, Æ, 198 269 | Utf8Class.Utf8Head2, // 0xC7, Ç, 199 270 | Utf8Class.Utf8Head2, // 0xC8, È, 200 271 | Utf8Class.Utf8Head2, // 0xC9, É, 201 272 | Utf8Class.Utf8Head2, // 0xCA, Ê, 202 273 | Utf8Class.Utf8Head2, // 0xCB, Ë, 203 274 | Utf8Class.Utf8Head2, // 0xCC, Ì, 204 275 | Utf8Class.Utf8Head2, // 0xCD, Í, 205 276 | Utf8Class.Utf8Head2, // 0xCE, Î, 206 277 | Utf8Class.Utf8Head2, // 0xCF, Ï, 207 278 | Utf8Class.Utf8Head2, // 0xD0, Ð, 208 279 | Utf8Class.Utf8Head2, // 0xD1, Ñ, 209 280 | Utf8Class.Utf8Head2, // 0xD2, Ò, 210 281 | Utf8Class.Utf8Head2, // 0xD3, Ó, 211 282 | Utf8Class.Utf8Head2, // 0xD4, Ô, 212 283 | Utf8Class.Utf8Head2, // 0xD5, Õ, 213 284 | Utf8Class.Utf8Head2, // 0xD6, Ö, 214 285 | Utf8Class.Utf8Head2, // 0xD7, ×, 215 286 | Utf8Class.Utf8Head2, // 0xD8, Ø, 216 287 | Utf8Class.Utf8Head2, // 0xD9, Ù, 217 288 | Utf8Class.Utf8Head2, // 0xDA, Ú, 218 289 | Utf8Class.Utf8Head2, // 0xDB, Û, 219 290 | Utf8Class.Utf8Head2, // 0xDC, Ü, 220 291 | Utf8Class.Utf8Head2, // 0xDD, Ý, 221 292 | Utf8Class.Utf8Head2, // 0xDE, Þ, 222 293 | Utf8Class.Utf8Head2, // 0xDF, ß, 223 294 | Utf8Class.Utf8Head3, // 0xE0, à, 224 295 | Utf8Class.Utf8Head3, // 0xE1, á, 225 296 | Utf8Class.Utf8Head3, // 0xE2, â, 226 297 | Utf8Class.Utf8Head3, // 0xE3, ã, 227 298 | Utf8Class.Utf8Head3, // 0xE4, ä, 228 299 | Utf8Class.Utf8Head3, // 0xE5, å, 229 300 | Utf8Class.Utf8Head3, // 0xE6, æ, 230 301 | Utf8Class.Utf8Head3, // 0xE7, ç, 231 302 | Utf8Class.Utf8Head3, // 0xE8, è, 232 303 | Utf8Class.Utf8Head3, // 0xE9, é, 233 304 | Utf8Class.Utf8Head3, // 0xEA, ê, 234 305 | Utf8Class.Utf8Head3, // 0xEB, ë, 235 306 | Utf8Class.Utf8Head3, // 0xEC, ì, 236 307 | Utf8Class.Utf8Head3, // 0xED, í, 237 308 | Utf8Class.Utf8Head3, // 0xEE, î, 238 309 | Utf8Class.Utf8Head3, // 0xEF, ï, 239 310 | Utf8Class.Utf8Head4, // 0xF0, ð, 240 311 | Utf8Class.Utf8Head4, // 0xF1, ñ, 241 312 | Utf8Class.Utf8Head4, // 0xF2, ò, 242 313 | Utf8Class.Utf8Head4, // 0xF3, ó, 243 314 | Utf8Class.Utf8Head4, // 0xF4, ô, 244 315 | Utf8Class.Utf8Head4, // 0xF5, õ, 245 316 | Utf8Class.Utf8Head4, // 0xF6, ö, 246 317 | Utf8Class.Utf8Head4, // 0xF7, ÷, 247 318 | Utf8Class.Invalid, // 0xF8, ø, 248 319 | Utf8Class.Invalid, // 0xF9, ù, 249 320 | Utf8Class.Invalid, // 0xFA, ú, 250 321 | Utf8Class.Invalid, // 0xFB, û, 251 322 | Utf8Class.Invalid, // 0xFC, ü, 252 323 | Utf8Class.Invalid, // 0xFD, ý, 253 324 | Utf8Class.Invalid, // 0xFE, þ, 254 325 | Utf8Class.Invalid, // 0xFF, ÿ, 255 326 | }); 327 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Helpers/Utf8String.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | using System.Text; 6 | 7 | namespace Stark.Compiler.Helpers; 8 | 9 | public readonly ref struct Utf8String 10 | { 11 | public Utf8String(IntPtr pointer, uint length) 12 | { 13 | Pointer = pointer; 14 | Length = length; 15 | } 16 | 17 | public IntPtr Pointer { get; } 18 | 19 | public uint Length { get; } 20 | 21 | public override bool Equals(object? obj) 22 | { 23 | return false; 24 | } 25 | 26 | public bool Equals(Utf8String str) 27 | { 28 | if (str.Length != this.Length) return false; 29 | if (str.Pointer == this.Pointer) return true; 30 | return AsSpan().SequenceEqual(str.AsSpan()); 31 | } 32 | 33 | public override int GetHashCode() 34 | { 35 | if (Pointer == IntPtr.Zero) return 0; 36 | unsafe 37 | { 38 | var hashCode = new HashCode(); 39 | var span = new Span((byte*)Pointer, (int)Length); 40 | hashCode.AddBytes(span); 41 | return hashCode.ToHashCode(); 42 | } 43 | } 44 | 45 | public Span AsSpan() 46 | { 47 | unsafe 48 | { 49 | return new Span((byte*)Pointer, (int)Length); 50 | } 51 | } 52 | 53 | public override string? ToString() 54 | { 55 | unsafe 56 | { 57 | if (Pointer == IntPtr.Zero) return null; 58 | return Encoding.UTF8.GetString((byte*)Pointer, (int)Length); 59 | } 60 | } 61 | 62 | public static bool operator ==(Utf8String left, Utf8String right) 63 | { 64 | return left.Equals(right); 65 | } 66 | 67 | public static bool operator !=(Utf8String left, Utf8String right) 68 | { 69 | return !left.Equals(right); 70 | } 71 | } 72 | 73 | public record struct Utf8StringHandle(uint Offset, uint Length); 74 | -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Parsing/KeywordHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | using System.Runtime.CompilerServices; 6 | using System.Text; 7 | using Stark.Compiler.Helpers; 8 | using Stark.Compiler.Syntax; 9 | 10 | namespace Stark.Compiler.Parsing; 11 | 12 | /// 13 | /// Helper class to categorize keywords from identifiers. 14 | /// 15 | internal static class KeywordHelper 16 | { 17 | private static readonly Dictionary KeywordHashToTokenKind = new(); 18 | 19 | public static TokenKind GetKeywordTokenKind(ReadOnlySpan identifier, int hash) 20 | { 21 | if (KeywordHashToTokenKind.TryGetValue(hash, out var pair)) 22 | { 23 | var keyword = new ReadOnlySpan(pair.Item1); 24 | if (keyword.SequenceEqual(identifier)) 25 | { 26 | return pair.Item2; 27 | } 28 | } 29 | 30 | return TokenKind.Identifier; 31 | } 32 | 33 | static KeywordHelper() 34 | { 35 | var keywords = new List<(string, TokenKind)>() 36 | { 37 | ("as", TokenKind.AsKeyword), 38 | ("async", TokenKind.AsyncKeyword), 39 | ("await", TokenKind.AwaitKeyword), 40 | ("break", TokenKind.BreakKeyword), 41 | ("catch", TokenKind.CatchKeyword), 42 | ("const", TokenKind.ConstKeyword), 43 | ("continue", TokenKind.ContinueKeyword), 44 | ("else", TokenKind.ElseKeyword), 45 | ("for", TokenKind.ForKeyword), 46 | ("func", TokenKind.FuncKeyword), 47 | ("if", TokenKind.IfKeyword), 48 | ("is", TokenKind.IsKeyword), 49 | ("let", TokenKind.LetKeyword), 50 | ("match", TokenKind.MatchKeyword), 51 | ("new", TokenKind.NewKeyword), 52 | ("not", TokenKind.NotKeyword), 53 | ("out", TokenKind.OutKeyword), 54 | ("ref", TokenKind.RefKeyword), 55 | ("return", TokenKind.ReturnKeyword), 56 | ("then", TokenKind.ThenKeyword), 57 | ("this", TokenKind.ThisKeyword), 58 | ("throw", TokenKind.ThrowKeyword), 59 | ("try", TokenKind.TryKeyword), 60 | ("unsafe", TokenKind.UnsafeKeyword), 61 | ("var", TokenKind.VarKeyword), 62 | ("while", TokenKind.WhileKeyword), 63 | ("alias", TokenKind.AliasKeyword), 64 | ("are", TokenKind.AreKeyword), 65 | ("attr", TokenKind.AttrKeyword), 66 | ("binary", TokenKind.BinaryKeyword), 67 | ("can", TokenKind.CanKeyword), 68 | ("case", TokenKind.CaseKeyword), 69 | ("constructor", TokenKind.ConstructorKeyword), 70 | ("enum", TokenKind.EnumKeyword), 71 | ("exclusive", TokenKind.ExclusiveKeyword), 72 | ("extends", TokenKind.ExtendsKeyword), 73 | ("extension", TokenKind.ExtensionKeyword), 74 | ("get", TokenKind.GetKeyword), 75 | ("has", TokenKind.HasKeyword), 76 | ("immutable", TokenKind.ImmutableKeyword), 77 | ("implements", TokenKind.ImplementsKeyword), 78 | ("import", TokenKind.ImportKeyword), 79 | ("in", TokenKind.InKeyword), 80 | ("indirect", TokenKind.IndirectKeyword), 81 | ("interface", TokenKind.InterfaceKeyword), 82 | ("isolated", TokenKind.IsolatedKeyword), 83 | ("kind", TokenKind.KindKeyword), 84 | ("lifetime", TokenKind.LifetimeKeyword), 85 | ("module", TokenKind.ModuleKeyword), 86 | ("macro", TokenKind.MacroKeyword), 87 | ("managed", TokenKind.ManagedKeyword), 88 | ("mutable", TokenKind.MutableKeyword), 89 | ("operator", TokenKind.OperatorKeyword), 90 | ("ownership", TokenKind.OwnershipKeyword), 91 | ("permission", TokenKind.PermissionKeyword), 92 | ("partial", TokenKind.PartialKeyword), 93 | ("pub", TokenKind.PubKeyword), 94 | ("readable", TokenKind.ReadableKeyword), 95 | ("requires", TokenKind.RequiresKeyword), 96 | ("rooted", TokenKind.RootedKeyword), 97 | ("set", TokenKind.SetKeyword), 98 | ("shared", TokenKind.SharedKeyword), 99 | ("static", TokenKind.StaticKeyword), 100 | ("struct", TokenKind.StructKeyword), 101 | ("transient", TokenKind.TransientKeyword), 102 | ("throws", TokenKind.ThrowsKeyword), 103 | ("type", TokenKind.TypeKeyword), 104 | ("unary", TokenKind.UnaryKeyword), 105 | ("union", TokenKind.UnionKeyword), 106 | ("unique", TokenKind.UniqueKeyword), 107 | ("unit", TokenKind.UnitKeyword), 108 | ("where", TokenKind.WhereKeyword), 109 | ("identifier", TokenKind.IdentifierKeyword), 110 | ("expression", TokenKind.ExpressionKeyword), 111 | ("statement", TokenKind.StatementKeyword), 112 | ("literal", TokenKind.LiteralKeyword), 113 | ("token", TokenKind.TokenKeyword), 114 | ("bool", TokenKind.BoolType), 115 | ("uint", TokenKind.UintType), 116 | ("u8", TokenKind.U8Type), 117 | ("u16", TokenKind.U16Type), 118 | ("u32", TokenKind.U32Type), 119 | ("u64", TokenKind.U64Type), 120 | ("int", TokenKind.IntType), 121 | ("i8", TokenKind.I8Type), 122 | ("i16", TokenKind.I16Type), 123 | ("i32", TokenKind.I32Type), 124 | ("i64", TokenKind.I64Type), 125 | ("f32", TokenKind.F32Type), 126 | ("f64", TokenKind.F64Type), 127 | ("v128", TokenKind.V128Type), 128 | ("v256", TokenKind.V256Type), 129 | }; 130 | 131 | foreach (var pair in keywords) 132 | { 133 | var bytes = Encoding.UTF8.GetBytes(pair.Item1); 134 | var hash = HashHelper.Hash(bytes); 135 | KeywordHashToTokenKind.Add(hash, (bytes, pair.Item2)); 136 | } 137 | } 138 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Parsing/LexerFileEntry.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | namespace Stark.Compiler.Parsing; 6 | 7 | /// 8 | /// A file entry used by the lexer. 9 | /// 10 | /// The path to the file. 11 | /// The length of the file. 12 | /// The first token index. 13 | /// The end token index (inclusive). 14 | public record struct LexerFileEntry(string Path, uint Length, uint BeginTokenIndex, uint EndTokenIndex); -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Parsing/LexerInputOutput.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | using System.Runtime.CompilerServices; 6 | using System.Text; 7 | using Stark.Compiler.Diagnostics; 8 | using Stark.Compiler.Helpers; 9 | using Stark.Compiler.Syntax; 10 | using Varena; 11 | 12 | namespace Stark.Compiler.Parsing; 13 | 14 | /// 15 | /// The Lexer Input/Output. Contains all generates tokens, spans and values as well as temporary buffer used by the lexer. 16 | /// 17 | public class LexerInputOutput 18 | { 19 | private readonly Dictionary _stringHandles; 20 | 21 | public LexerInputOutput(VirtualArenaManager manager) 22 | { 23 | Diagnostics = new DiagnosticBag(); 24 | Tokens = manager.CreateArray("Tokens", 1 << 30); 25 | TokenSpans = manager.CreateArray("TokenSpans", 1 << 30); 26 | TokenValues = manager.CreateArray("TokenValues", 1 << 30); 27 | InputBuffer = manager.CreateBuffer("InputBuffer", 1 << 30); 28 | TempBuffer = manager.CreateBuffer("LexerTempBuffer", 1 << 30); 29 | StringBuffer = manager.CreateBuffer("StringBuffer", 1 << 30); 30 | _stringHandles = new Dictionary(4096); 31 | FileLexerEntries = new List(); 32 | } 33 | 34 | public DiagnosticBag Diagnostics { get; } 35 | 36 | public VirtualArray Tokens { get; } 37 | 38 | public VirtualArray TokenSpans { get; } 39 | 40 | public VirtualArray TokenValues { get; } 41 | 42 | public VirtualBuffer InputBuffer { get; } 43 | 44 | public VirtualBuffer TempBuffer { get; } 45 | 46 | public VirtualBuffer StringBuffer { get; } 47 | 48 | public List FileLexerEntries { get; } 49 | 50 | public Utf8StringHandle GetStringHandle(ReadOnlySpan data, int hash) 51 | { 52 | unsafe 53 | { 54 | fixed (byte* ptr = data) 55 | { 56 | // Use the input temporarily 57 | var key = new Utf8InternalString((IntPtr)ptr, hash, (uint)data.Length); 58 | if (_stringHandles.TryGetValue(key, out var handle)) 59 | { 60 | return handle; 61 | } 62 | 63 | var offset = (uint)StringBuffer.AllocatedBytes; 64 | var pointer = (byte*)StringBuffer.BaseAddress + offset; 65 | data.CopyTo(StringBuffer.AllocateRange(data.Length)); 66 | key = new Utf8InternalString((IntPtr)pointer, hash, (uint)data.Length); 67 | handle = new Utf8StringHandle(offset, (uint)data.Length); 68 | _stringHandles.Add(key, handle); 69 | return handle; 70 | } 71 | } 72 | } 73 | 74 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 75 | public Utf8String GetString(Utf8StringHandle stringHandle) 76 | { 77 | return stringHandle.Length == 0 ? default : new Utf8String(IntPtr.Add(StringBuffer.BaseAddress, (int)stringHandle.Offset), stringHandle.Length); 78 | } 79 | 80 | public void Reset() 81 | { 82 | Reset(VirtualArenaResetKind.KeepMinimalCommitted); 83 | } 84 | 85 | public void Reset(VirtualArenaResetKind kind) 86 | { 87 | FileLexerEntries.Clear(); 88 | Diagnostics.Clear(); 89 | Tokens.Reset(kind); 90 | TokenSpans.Reset(kind); 91 | TokenValues.Reset(kind); 92 | InputBuffer.Reset(kind); 93 | TempBuffer.Reset(kind); 94 | } 95 | 96 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 97 | public void AddToken(TokenKind kind, TokenSpan span) 98 | { 99 | Tokens.Allocate() = kind; 100 | TokenSpans.Allocate() = span; 101 | TokenValues.Allocate() = default; 102 | } 103 | 104 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 105 | public void AddToken(TokenKind kind, TokenSpan span, TokenValue value) 106 | { 107 | Tokens.Allocate() = kind; 108 | TokenSpans.Allocate() = span; 109 | TokenValues.Allocate() = value; 110 | } 111 | 112 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 113 | public void AddToken(TokenKind kind, TokenSpan span, ReadOnlySpan value) 114 | { 115 | AddToken(kind, span, value, HashHelper.Hash(value)); 116 | } 117 | 118 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 119 | public void AddToken(TokenKind kind, TokenSpan span, ReadOnlySpan value, int hash) 120 | { 121 | Tokens.Allocate() = kind; 122 | TokenSpans.Allocate() = span; 123 | TokenValues.Allocate() = new TokenValue(GetStringHandle(value, hash)); 124 | } 125 | 126 | public void ResetInputBuffer() 127 | { 128 | InputBuffer.Reset(VirtualArenaResetKind.KeepMinimalCommitted); 129 | } 130 | 131 | public void ResetTempBuffer() 132 | { 133 | TempBuffer.Reset(VirtualArenaResetKind.KeepMinimalCommitted); 134 | } 135 | 136 | readonly struct Utf8InternalString : IEquatable 137 | { 138 | public Utf8InternalString(IntPtr pointer, int hashCode, uint length) 139 | { 140 | Pointer = pointer; 141 | HashCode = hashCode; 142 | Length = length; 143 | } 144 | 145 | public IntPtr Pointer { get; } 146 | 147 | public int HashCode { get; } 148 | 149 | public uint Length { get; } 150 | 151 | public override bool Equals(object? obj) => obj is Utf8InternalString str && Equals(str); 152 | 153 | public bool Equals(Utf8InternalString str) 154 | { 155 | if (str.Length != this.Length) return false; 156 | if (str.Pointer == this.Pointer) return true; 157 | return AsSpan().SequenceEqual(str.AsSpan()); 158 | } 159 | 160 | public override int GetHashCode() => HashCode; 161 | 162 | public ReadOnlySpan AsSpan() 163 | { 164 | unsafe 165 | { 166 | return new ReadOnlySpan((byte*)Pointer, (int)Length); 167 | } 168 | } 169 | 170 | public override string? ToString() 171 | { 172 | unsafe 173 | { 174 | if (Pointer == IntPtr.Zero) return null; 175 | return Encoding.UTF8.GetString((byte*)Pointer, (int)Length); 176 | } 177 | } 178 | } 179 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Stark.Compiler.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | preview 8 | True 9 | true 10 | $(DefineConstants)TRACE;WCWIDTH_VISIBILITY_INTERNAL 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Syntax/TokenKind.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | namespace Stark.Compiler.Syntax; 6 | 7 | /// 8 | /// The kind of a token. 9 | /// 10 | public enum TokenKind : byte 11 | { 12 | /// 13 | /// An invalid character. 14 | /// 15 | Invalid = 0, 16 | 17 | /// 18 | /// An invalid UTF8 character. 19 | /// 20 | InvalidUtf8, 21 | 22 | /// 23 | /// An invalid TAB character. 24 | /// 25 | InvalidTab, 26 | 27 | Eof, 28 | 29 | WhiteSpace, 30 | NewLine, 31 | Identifier, 32 | Integer, 33 | Float, 34 | CommentSingleLine, 35 | CommentDocumentationSingleLine, 36 | CommentMultiLine, 37 | Rune, 38 | String, 39 | StringInterpolatedMacro, 40 | StringInterpolatedPart, 41 | StringInterpolatedBegin, 42 | StringInterpolatedEnd, 43 | MultiLineStringBegin, 44 | MultiLineStringPart, 45 | MultiLineStringInterpolatedPart, 46 | MultiLineStringEnd, 47 | 48 | // 1 byte symbols 49 | Exclamation, // ! 50 | // DoubleQuote, // " not used alone, only used through string 51 | Hash, // # 52 | Dollar, // $ 53 | Percent, // % 54 | Ampersand, // & 55 | SingleQuote, // ' used for unit 56 | LeftParen, // ( 57 | RightParen, // ) 58 | Star, // * 59 | Plus, // + 60 | Comma, // , 61 | Minus, // - 62 | Dot, // . 63 | Slash, // / 64 | Colon, // : 65 | SemiColon, // ; 66 | LessThan, // < 67 | Equal, // = 68 | GreaterThan, // > 69 | Question, // ? 70 | At, // @ 71 | LeftBracket, // [ 72 | Backslash, // \ 73 | RightBracket, // ] 74 | Circumflex, // ^ 75 | Underscore, // _ 76 | Backtick, // ` 77 | LeftBrace, // { 78 | VerticalBar, // | 79 | RightBrace, // } 80 | Tilde, // ~ 81 | 82 | // 2-3 byte symbols 83 | DoubleAmpersand, // && 84 | DoubleVerticalBar, // || 85 | DoubleEqual, // == 86 | SlashEqual, // /= 87 | PercentEqual, // %= 88 | AmpersandEqual, // &= 89 | StarEqual, // *= 90 | PlusEqual, // += 91 | MinusEqual, // -= 92 | TildeEqual, // ~= 93 | CircumflexEqual, // ^= 94 | VerticalBarEqual, // |= 95 | LessThanEqual, // <= 96 | GreaterThanEqual, // >= 97 | EqualGreaterThan, // => 98 | MinusGreaterThan, // -> 99 | LessThanGreaterThan,// <> 100 | DoubleLessThanEqual,// <<= 101 | DoubleGreaterThanEqual,// >>= 102 | VerticalBarGreaterThan, // |> 103 | DoubleColon, // :: 104 | DoubleDot, // .. 105 | DoubleDotLessThan, // ..< 106 | TripleEqual, // === 107 | 108 | AsKeyword, 109 | AsyncKeyword, 110 | AwaitKeyword, 111 | BreakKeyword, 112 | CatchKeyword, 113 | ConstKeyword, 114 | ContinueKeyword, 115 | ElseKeyword, 116 | ForKeyword, 117 | FuncKeyword, 118 | IfKeyword, 119 | IsKeyword, 120 | LetKeyword, 121 | MatchKeyword, 122 | NewKeyword, 123 | NotKeyword, 124 | OutKeyword, 125 | RefKeyword, 126 | ReturnKeyword, 127 | ThenKeyword, 128 | ThisKeyword, 129 | ThrowKeyword, 130 | TryKeyword, 131 | UnsafeKeyword, 132 | VarKeyword, 133 | WhileKeyword, 134 | AliasKeyword, 135 | AreKeyword, 136 | AttrKeyword, 137 | BinaryKeyword, 138 | CanKeyword, 139 | CaseKeyword, 140 | ConstructorKeyword, 141 | EnumKeyword, 142 | ExclusiveKeyword, 143 | ExtendsKeyword, 144 | ExtensionKeyword, 145 | GetKeyword, 146 | HasKeyword, 147 | ImmutableKeyword, 148 | ImplementsKeyword, 149 | ImportKeyword, 150 | InKeyword, 151 | IndirectKeyword, 152 | InterfaceKeyword, 153 | IsolatedKeyword, 154 | KindKeyword, 155 | LifetimeKeyword, 156 | ModuleKeyword, 157 | MacroKeyword, 158 | ManagedKeyword, 159 | MutableKeyword, 160 | OperatorKeyword, 161 | OwnershipKeyword, 162 | PermissionKeyword, 163 | PartialKeyword, 164 | PubKeyword, 165 | ReadableKeyword, 166 | RequiresKeyword, 167 | RootedKeyword, 168 | SetKeyword, 169 | SharedKeyword, 170 | StaticKeyword, 171 | StructKeyword, 172 | TransientKeyword, 173 | ThrowsKeyword, 174 | TypeKeyword, 175 | UnaryKeyword, 176 | UnionKeyword, 177 | UniqueKeyword, 178 | UnitKeyword, 179 | WhereKeyword, 180 | IdentifierKeyword, 181 | ExpressionKeyword, 182 | StatementKeyword, 183 | LiteralKeyword, 184 | TokenKeyword, 185 | 186 | BoolType, 187 | UintType, 188 | U8Type, 189 | U16Type, 190 | U32Type, 191 | U64Type, 192 | IntType, 193 | I8Type, 194 | I16Type, 195 | I32Type, 196 | I64Type, 197 | F32Type, 198 | F64Type, 199 | V128Type, 200 | V256Type, 201 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/Syntax/TokenSpan.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | using System.Runtime.CompilerServices; 6 | using Stark.Compiler.Helpers; 7 | 8 | namespace Stark.Compiler.Syntax; 9 | 10 | public record struct TokenSpan(uint Offset, uint Length, uint Line, uint Column) 11 | { 12 | public uint Offset = Offset; 13 | 14 | public uint Length = Length; 15 | 16 | public uint Line = Line; 17 | 18 | public uint Column = Column; 19 | } 20 | 21 | public record struct TokenValue(ulong Data) 22 | { 23 | public TokenValue(Utf8StringHandle utf8StringHandle) : this((ulong)utf8StringHandle.Offset << 32 | utf8StringHandle.Length) 24 | { 25 | } 26 | 27 | public TokenValue(int value) : this((ulong)(value)) 28 | { 29 | } 30 | 31 | public TokenValue(double value) : this(Unsafe.As(ref value)) 32 | { 33 | } 34 | 35 | public Utf8StringHandle AsStringHandle() => new Utf8StringHandle((uint)(Data >> 32), (uint)Data); 36 | } -------------------------------------------------------------------------------- /src/compiler/Stark.Compiler/TextSpan.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // Licensed under the BSD-Clause 2 license. 3 | // See license.txt file in the project root for full license information. 4 | 5 | using System.Data.Common; 6 | 7 | namespace Stark.Compiler; 8 | 9 | public record struct TextSpan(TextLocation Start, TextLocation End) 10 | { 11 | public TextSpan(TextLocation location) : this(location, location) 12 | { 13 | } 14 | 15 | public string ToText() => $"({Start.ToText()}, {End.ToText()})"; 16 | } 17 | 18 | public record struct TextLocation(uint Offset, uint Line, uint Column) 19 | { 20 | public string ToText() => $"{Line + 1}, {Column + 1}"; 21 | } 22 | -------------------------------------------------------------------------------- /src/compiler/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "7.0.100-rc.1.22431.12" 4 | } 5 | } -------------------------------------------------------------------------------- /src/compiler/readme.md: -------------------------------------------------------------------------------- 1 | # Stark Compiler 2 | 3 | The old compiler prototype based on Roslyn was removed. Use the branch [roslyn-fork-prototype](https://github.com/stark-lang/stark/tree/roslyn-fork-prototype). 4 | 5 | The new compiler will be in entirely rewritten using a fully data oriented approach. -------------------------------------------------------------------------------- /src/ide/readme.md: -------------------------------------------------------------------------------- 1 | Basic syntax highlighting for Stark. 2 | 3 | Currently only VisualStudio code is supported. See [VSCode](vscode/stark/readme.md) -------------------------------------------------------------------------------- /src/ide/vscode/stark/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "extensionHost", 9 | "request": "launch", 10 | "name": "Launch", 11 | "runtimeExecutable": "${execPath}", 12 | "args": ["--extensionDevelopmentPath=${workspaceRoot}" ] 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /src/ide/vscode/stark/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "typescript", 8 | "tsconfig": "tsconfig.json", 9 | "problemMatcher": [ 10 | "$tsc" 11 | ] 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /src/ide/vscode/stark/language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | // symbol used for single line comment. Remove this entry if your language does not support line comments 4 | "lineComment": "//", 5 | // symbols used for start and end a block comment. Remove this entry if your language does not support block comments 6 | "blockComment": [ "/*", "*/" ] 7 | }, 8 | // symbols used as brackets 9 | "brackets": [ 10 | ["{", "}"], 11 | ["[", "]"], 12 | ["(", ")"] 13 | ], 14 | // symbols that are auto closed when typing 15 | "autoClosingPairs": [ 16 | ["{", "}"], 17 | ["{$", "$}"], 18 | ["<$", "$>"], 19 | ["[", "]"], 20 | ["(", ")"], 21 | ["\"", "\""], 22 | ["'", "'"] 23 | ], 24 | // symbols that that can be used to surround a selection 25 | "surroundingPairs": [ 26 | ["{", "}"], 27 | ["{$", "$}"], 28 | ["<$", "$>"], 29 | ["[", "]"], 30 | ["(", ")"], 31 | ["\"", "\""], 32 | ["'", "'"] 33 | ] 34 | } -------------------------------------------------------------------------------- /src/ide/vscode/stark/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stark", 3 | "displayName": "stark-lang", 4 | "description": "Stark Language Colorizer", 5 | "version": "0.0.1", 6 | "publisher": "xoofx", 7 | "engines": { 8 | "vscode": "^1.30.0" 9 | }, 10 | "categories": [ 11 | "Languages" 12 | ], 13 | "activationEvents": [ 14 | "onLanguage:plaintext" 15 | ], 16 | "main": "./out/extension", 17 | "contributes": { 18 | "languages": [{ 19 | "id": "stark", 20 | "aliases": ["Stark", "stark"], 21 | "extensions": [".sk"], 22 | "configuration": "./language-configuration.json" 23 | }], 24 | "grammars": [{ 25 | "language": "stark", 26 | "scopeName": "source.sk", 27 | "path": "./syntaxes/stark.tmLanguage" 28 | }] 29 | }, 30 | "scripts": { 31 | "vscode:prepublish": "tsc -p ./", 32 | "compile": "tsc -watch -p ./", 33 | "update-vscode": "node ./node_modules/vscode/bin/install", 34 | "postinstall": "node ./node_modules/vscode/bin/install" 35 | }, 36 | "devDependencies": { 37 | "@types/node": "^11.9.4", 38 | "typescript": "^3.3.3", 39 | "vscode": "^1.1.29" 40 | }, 41 | "dependencies": { 42 | "vscode-languageclient": "^5.2.1" 43 | } 44 | } -------------------------------------------------------------------------------- /src/ide/vscode/stark/readme.md: -------------------------------------------------------------------------------- 1 | VisualStudio code Extension for Stark to enable basic syntax highlighting for Stark keywords. 2 | 3 | Usage: 4 | 5 | ``` 6 | cd %USERPROFILE%\.vscode\extensions 7 | # example: mklink /D stark C:\...\stark\editors\vscode\stark 8 | mklink /D stark PATH_TO_VSCODE_STARK_DIRECTORY 9 | ``` -------------------------------------------------------------------------------- /src/ide/vscode/stark/src/extension.ts: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | * ------------------------------------------------------------------------------------------ */ 5 | // tslint:disable 6 | 'use strict'; 7 | 8 | import * as path from 'path'; 9 | 10 | import { workspace, Disposable, ExtensionContext } from 'vscode'; 11 | import { LanguageClient, LanguageClientOptions, SettingMonitor, ServerOptions, TransportKind, InitializeParams } from 'vscode-languageclient'; 12 | import { Trace } from 'vscode-jsonrpc'; 13 | 14 | export function activate(context: ExtensionContext) { 15 | // The server is implemented in node 16 | // let serverExe = 'dotnet'; 17 | let serverExe = path.join(context.asAbsolutePath("."), '..', '..', '..', 'compiler/StarkCompilerServer/bin/Debug/netcoreapp2.2/StarkCompilerServer.dll'); 18 | let dotnetExe = 'dotnet.exe'; 19 | 20 | // If the extension is launched in debug mode then the debug server options are used 21 | // Otherwise the run options are used 22 | let serverOptions: ServerOptions = { 23 | run: { command: dotnetExe, args: [serverExe, '-lsp', '-d'] }, 24 | debug: { command: dotnetExe, args: [serverExe, '-lsp', '-d'] } 25 | } 26 | 27 | // Options to control the language client 28 | let clientOptions: LanguageClientOptions = { 29 | // Register the server for plain text documents 30 | documentSelector: [ 31 | { 32 | pattern: '**/*.sk', 33 | }, 34 | ], 35 | synchronize: { 36 | // Synchronize the setting section 'languageServerExample' to the server 37 | configurationSection: 'languageServerExample', 38 | fileEvents: workspace.createFileSystemWatcher('**/*.sk') 39 | } 40 | } 41 | 42 | // Create the language client and start the client. 43 | const client = new LanguageClient('languageServerExample', 'Language Server Example', serverOptions, clientOptions); 44 | client.trace = Trace.Verbose; 45 | client.clientOptions.errorHandler 46 | let disposable = client.start(); 47 | 48 | // Push the disposable to the context's subscriptions so that the 49 | // client can be deactivated on extension deactivation 50 | context.subscriptions.push(disposable); 51 | } 52 | -------------------------------------------------------------------------------- /src/ide/vscode/stark/syntaxes/stark.YAML-tmLanguage: -------------------------------------------------------------------------------- 1 | # [PackageDev] target_format: plist, ext: tmLanguage 2 | name: Stark 3 | scopeName: source.sk 4 | fileTypes: [sk] 5 | uuid: 582789B5-991D-49E1-8E39-54327B3DBDFF 6 | 7 | patterns: 8 | - include: '#comment' 9 | - include: '#control-keywords' 10 | - include: '#keywords' 11 | - include: '#async-keywords' 12 | - include: '#builtin-types' 13 | - include: '#vector-types' 14 | - include: '#generic-modifiers' 15 | - include: '#inline-il' 16 | - include: '#type-attributes' 17 | - include: '#visibility-modifiers' 18 | - include: '#attribute-declaration' 19 | - include: '#import-declaration' 20 | - include: '#namespace-declaration' 21 | - include: '#module-declaration' 22 | - include: '#func-declaration' 23 | - include: '#macro-declaration' 24 | - include: '#invoke-declaration' 25 | - include: '#type-declaration' 26 | - include: '#definition-modulators' 27 | - include: '#lifetime-identifier' 28 | - include: '#macros' 29 | - include: '#keywords' 30 | - include: '#literals' 31 | - include: '#measure_type' 32 | 33 | repository: 34 | builtin-types: 35 | match: \b(bool|f64|f32|i64|i32|i16|i8|u64|u32|u16|u8|int|uint|x8|x16|x32|x64|x128|xint|i128|u128|string)\b 36 | captures: 37 | '1': {name: keyword.type.sk} 38 | vector-types: 39 | match: \b(v128|v256)\b 40 | captures: 41 | '1': {name: keyword.type.sk} 42 | generic-modifiers: 43 | name: storage.modifier.sk 44 | match: \b(lifetime|permission)\b 45 | visibility-modifiers: 46 | name: storage.modifier.sk 47 | match: (?)\s*)?\s+([_[:alpha:]][_[:alnum:]]*) 105 | captures: 106 | '1': { name: keyword.other.type.sk } 107 | '2': { name: keyword.other.soa_aos.sk } 108 | '3': { name: entity.name.type.class.sk } 109 | - match: \b(extend)(?:\s*`<.*?>)?\s*([_[:alpha:]][_[:alnum:]]*) 110 | captures: 111 | '1': { name: keyword.other.type.sk } 112 | '2': { name: entity.name.type.class.sk } 113 | - match: \b(attr)\b\s*([_[:alpha:]][_[:alnum:]]*) 114 | captures: 115 | '1': { name: keyword.other.attr.sk } 116 | '2': { name: entity.name.type.attr.sk } 117 | - name: keyword.other.type.sk 118 | match: \b(type)\b 119 | - name: keyword.other.union.sk 120 | match: \b(union)\b 121 | - name: keyword.other.struct.sk 122 | match: \b(struct)\b 123 | - name: keyword.other.class.sk 124 | match: \b(class)\b 125 | - name: keyword.other.interface.sk 126 | match: \b(interface)\b 127 | - name: keyword.other.enum.sk 128 | match: \b(enum)\b 129 | - name: keyword.other.attr.sk 130 | match: \b(attr)\b 131 | definition-modulators: 132 | patterns: 133 | - match: ^\s*(===)\s*$ 134 | captures: 135 | '1': { name: keyword.other.where.sk } 136 | - match: ^\s*(where)\s+([_[:alpha:]][_[:alnum:]]*) 137 | captures: 138 | '1': { name: keyword.other.where.sk } 139 | '2': { name: entity.name.type.class.sk } 140 | - match: ^\s*(where)\s+ 141 | captures: 142 | '1': { name: keyword.other.where.sk } 143 | - match: (^\s*(?:inherits|implements|throws))\b([_[:alpha:]][_[:alnum:]]*)? 144 | captures: 145 | '1': { name: keyword.other.requires.sk } 146 | '2': { name: entity.name.type.class.sk } 147 | - match: (^\s*(?:requires))\b 148 | captures: 149 | '1': { name: keyword.other.requires.sk } 150 | func-declaration: 151 | patterns: 152 | - match: \b((?:(?:dispatch|override|extern|rw|partial|async)\s+)*func(?:\s+rw\s+this|\s+this)?)\s+([_[:alpha:]][_[:alnum:]]*)\b 153 | captures: 154 | '1': { name: keyword.other.func.sk } 155 | '2': { name: entity.name.function.sk } 156 | - match: \b((?:(unsafe|partial)\s+)*operator(?:\s+(?:binary|unary)))\b 157 | captures: 158 | '1': { name: keyword.other.func.sk } 159 | - match: \b(constructor)(\s+[_[:alpha:]][_[:alnum:]]*)? 160 | captures: 161 | '1': { name: keyword.other.func.sk } 162 | '2': { name: entity.name.function.sk } 163 | - name: keyword.other.constructor.sk 164 | match: \bconstructor\b 165 | - name: keyword.other.destructor.sk 166 | match: \bdestructor\b 167 | - name: keyword.other.func.sk 168 | match: \bfunc\b 169 | 170 | macro-declaration: 171 | patterns: 172 | - match: \b(macro)\s+([_[:alpha:]][_[:alnum:]]*)\b 173 | captures: 174 | '1': { name: keyword.other.macro.sk } 175 | '2': { name: entity.name.function.sk } 176 | - name: keyword.other.macro.sk 177 | match: \bmacro\b 178 | 179 | invoke-declaration: 180 | patterns: 181 | - match: '([_[:alpha:]][_[:alnum:]]*)(?:\s*\()' 182 | captures: 183 | '1': { name: entity.name.function.sk } 184 | control-keywords: 185 | patterns: 186 | - name: keyword.control.conditional.if.sk 187 | match: \bif\b 188 | - name: keyword.control.conditional.then.sk 189 | match: \bthen\b 190 | - name: keyword.control.conditional.else.sk 191 | match: \belse\b 192 | - name: keyword.control.loop.do.sk 193 | match: \bdo\b 194 | - name: keyword.control.loop.while.sk 195 | match: \bwhile\b 196 | - name: keyword.control.loop.for.sk 197 | match: \bfor\b 198 | - name: keyword.control.try.sk 199 | match: \btry\b 200 | - name: keyword.control.catch.sk 201 | match: \bcatch\b 202 | - name: keyword.control.flow.yield.sk 203 | match: \byield\b 204 | - name: keyword.control.flow.return.sk 205 | match: \breturn\b 206 | - name: keyword.control.flow.break.sk 207 | match: \bbreak\b 208 | - name: keyword.control.flow.continue.sk 209 | match: \bcontinue\b 210 | - name: keyword.control.flow.throw.sk 211 | match: \bthrow\b 212 | - name: keyword.control.flow.ignore.sk 213 | match: \bignore\b 214 | - name: keyword.control.flow.abort.sk 215 | match: \babort\b 216 | - name: keyword.control.flow.switch.sk 217 | match: \bswitch\b 218 | - name: keyword.control.flow.case.sk 219 | match: \bcase\b 220 | - name: keyword.control.flow.with.sk 221 | match: \bwith\b 222 | - name: constant.language.boolean.true.sk 223 | match: \btrue\b 224 | - name: constant.language.boolean.false.sk 225 | match: \bfalse\b 226 | - name: constant.language.class.null.sk 227 | match: \bnull\b 228 | keywords: 229 | name: keyword.type.sk 230 | match: \b(alias|as|base|default|fatal|get|is|has|let|match|implicit|out|params|ref|in|set|sizeof|this|typeof|value|var)\b 231 | async-keywords: 232 | name: keyword.type.sk 233 | match: \b(async|await|spawn)\b 234 | comment: 235 | patterns: 236 | - name: comment.block.sk 237 | begin: /\* 238 | beginCaptures: 239 | '0': {name: punctuation.definition.comment.sk} 240 | end: \*/ 241 | endCaptures: 242 | '0': {name: punctuation.definition.comment.sk} 243 | - begin: (^\s+)?(?=//) 244 | beginCaptures: 245 | '1': {name: punctuation.whitespace.comment.leading.sk} 246 | end: (?=$) 247 | patterns: 248 | - name: comment.block.documentation.sk 249 | begin: (?|\{\$+|\$+\})' 333 | 334 | verbatim-string-literal: 335 | name: string.quoted.double.sk 336 | begin: '\\"' 337 | beginCaptures: 338 | '0': {name: punctuation.definition.string.begin.sk} 339 | end: '"' 340 | endCaptures: 341 | '0': {name: punctuation.definition.string.end.sk} 342 | patterns: 343 | - include: '#verbatim-string-character-escape' 344 | -------------------------------------------------------------------------------- /src/ide/vscode/stark/syntaxes/stark.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Stark 7 | scopeName 8 | source.sk 9 | fileTypes 10 | 11 | sk 12 | 13 | uuid 14 | 582789B5-991D-49E1-8E39-54327B3DBDFF 15 | patterns 16 | 17 | 18 | include 19 | #comment 20 | 21 | 22 | include 23 | #control-keywords 24 | 25 | 26 | include 27 | #keywords 28 | 29 | 30 | include 31 | #async-keywords 32 | 33 | 34 | include 35 | #builtin-types 36 | 37 | 38 | include 39 | #vector-types 40 | 41 | 42 | include 43 | #generic-modifiers 44 | 45 | 46 | include 47 | #inline-il 48 | 49 | 50 | include 51 | #type-attributes 52 | 53 | 54 | include 55 | #visibility-modifiers 56 | 57 | 58 | include 59 | #attribute-declaration 60 | 61 | 62 | include 63 | #import-declaration 64 | 65 | 66 | include 67 | #namespace-declaration 68 | 69 | 70 | include 71 | #module-declaration 72 | 73 | 74 | include 75 | #func-declaration 76 | 77 | 78 | include 79 | #macro-declaration 80 | 81 | 82 | include 83 | #invoke-declaration 84 | 85 | 86 | include 87 | #type-declaration 88 | 89 | 90 | include 91 | #definition-modulators 92 | 93 | 94 | include 95 | #lifetime-identifier 96 | 97 | 98 | include 99 | #macros 100 | 101 | 102 | include 103 | #keywords 104 | 105 | 106 | include 107 | #literals 108 | 109 | 110 | include 111 | #measure_type 112 | 113 | 114 | repository 115 | 116 | builtin-types 117 | 118 | match 119 | \b(bool|f64|f32|i64|i32|i16|i8|u64|u32|u16|u8|int|uint|x8|x16|x32|x64|x128|xint|i128|u128|string)\b 120 | captures 121 | 122 | 1 123 | 124 | name 125 | keyword.type.sk 126 | 127 | 128 | 129 | vector-types 130 | 131 | match 132 | \b(v128|v256)\b 133 | captures 134 | 135 | 1 136 | 137 | name 138 | keyword.type.sk 139 | 140 | 141 | 142 | generic-modifiers 143 | 144 | name 145 | storage.modifier.sk 146 | match 147 | \b(lifetime|permission)\b 148 | 149 | visibility-modifiers 150 | 151 | name 152 | storage.modifier.sk 153 | match 154 | (?<!\.)\b(abstract|const|extern|internal|new|rnew|ropen|rtemp|rdelete|override|partial|public|pub|dynamic|static|unsafe|virtual)\b 155 | 156 | module-declaration 157 | 158 | patterns 159 | 160 | 161 | match 162 | \b(module)\b\s*([_[:alpha:]][_[:alnum:]]*) 163 | captures 164 | 165 | 1 166 | 167 | name 168 | keyword.other.module.sk 169 | 170 | 2 171 | 172 | name 173 | entity.name.type.module.sk 174 | 175 | 176 | 177 | 178 | 179 | attribute-declaration 180 | 181 | patterns 182 | 183 | 184 | match 185 | (@)\s*([_[:alpha:]][_[:alnum:]]*(?:\s*\.\s*[_[:alpha:]][_[:alnum:]]*)*) 186 | captures 187 | 188 | 1 189 | 190 | name 191 | markup.underline.sk 192 | 193 | 2 194 | 195 | patterns 196 | 197 | 198 | match 199 | [_[:alpha:]][_[:alnum:]]* 200 | name 201 | entity.name.type.attribute.sk 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | inline-il 210 | 211 | patterns 212 | 213 | 214 | match 215 | \b(unsafe)\s+(il)\b 216 | captures 217 | 218 | 1 219 | 220 | name 221 | keyword.other.unsafe.sk 222 | 223 | 2 224 | 225 | name 226 | keyword.other.il.sk 227 | 228 | 229 | 230 | 231 | 232 | import-declaration 233 | 234 | patterns 235 | 236 | 237 | match 238 | \b(import)\b\s*([_[:alpha:]][_[:alnum:]]*(?:\s*::\s*[_[:alpha:]][_[:alnum:]]*)*) 239 | captures 240 | 241 | 1 242 | 243 | name 244 | keyword.other.import.sk 245 | 246 | 2 247 | 248 | patterns 249 | 250 | 251 | match 252 | [_[:alpha:]][_[:alnum:]]* 253 | name 254 | entity.name.type.import.sk 255 | 256 | 257 | 258 | 259 | 260 | 261 | match 262 | \b(import)\b 263 | captures 264 | 265 | 1 266 | 267 | name 268 | keyword.other.import.sk 269 | 270 | 271 | 272 | 273 | 274 | namespace-declaration 275 | 276 | patterns 277 | 278 | 279 | match 280 | \b(namespace)\b\s*([_[:alpha:]][_[:alnum:]]*(?:\s*\.\s*[_[:alpha:]][_[:alnum:]]*)*) 281 | captures 282 | 283 | 1 284 | 285 | name 286 | keyword.other.namespace.sk 287 | 288 | 2 289 | 290 | patterns 291 | 292 | 293 | match 294 | [_[:alpha:]][_[:alnum:]]* 295 | name 296 | entity.name.type.namespace.sk 297 | 298 | 299 | 300 | 301 | 302 | 303 | match 304 | \b(namespace)\b 305 | captures 306 | 307 | 1 308 | 309 | name 310 | keyword.other.namespace.sk 311 | 312 | 313 | 314 | 315 | 316 | type-attributes 317 | 318 | patterns 319 | 320 | 321 | match 322 | `(immutable|rw|ropen|transient|retainable|shared|rooted|unique|readable|soa|aos)\b 323 | captures 324 | 325 | 1 326 | 327 | name 328 | keyword.other.type.sk 329 | 330 | 331 | 332 | 333 | match 334 | `([_[:alpha:]][_[:alnum:]]*)\b 335 | captures 336 | 337 | 1 338 | 339 | name 340 | entity.name.type.class.sk 341 | 342 | 343 | 344 | 345 | 346 | type-declaration 347 | 348 | patterns 349 | 350 | 351 | match 352 | \b((?:(?:rw|transient|\??linear|region|ref)\s+)*struct|process|union|enum|interface|unit|type)(\s*`(?:soa|aos)\s*)?(?:\s*`(?:\w+|<.*?>)\s*)?\s+([_[:alpha:]][_[:alnum:]]*) 353 | captures 354 | 355 | 1 356 | 357 | name 358 | keyword.other.type.sk 359 | 360 | 2 361 | 362 | name 363 | keyword.other.soa_aos.sk 364 | 365 | 3 366 | 367 | name 368 | entity.name.type.class.sk 369 | 370 | 371 | 372 | 373 | match 374 | \b(extend)(?:\s*`<.*?>)?\s*([_[:alpha:]][_[:alnum:]]*) 375 | captures 376 | 377 | 1 378 | 379 | name 380 | keyword.other.type.sk 381 | 382 | 2 383 | 384 | name 385 | entity.name.type.class.sk 386 | 387 | 388 | 389 | 390 | match 391 | \b(attr)\b\s*([_[:alpha:]][_[:alnum:]]*) 392 | captures 393 | 394 | 1 395 | 396 | name 397 | keyword.other.attr.sk 398 | 399 | 2 400 | 401 | name 402 | entity.name.type.attr.sk 403 | 404 | 405 | 406 | 407 | name 408 | keyword.other.type.sk 409 | match 410 | \b(type)\b 411 | 412 | 413 | name 414 | keyword.other.union.sk 415 | match 416 | \b(union)\b 417 | 418 | 419 | name 420 | keyword.other.struct.sk 421 | match 422 | \b(struct)\b 423 | 424 | 425 | name 426 | keyword.other.class.sk 427 | match 428 | \b(class)\b 429 | 430 | 431 | name 432 | keyword.other.interface.sk 433 | match 434 | \b(interface)\b 435 | 436 | 437 | name 438 | keyword.other.enum.sk 439 | match 440 | \b(enum)\b 441 | 442 | 443 | name 444 | keyword.other.attr.sk 445 | match 446 | \b(attr)\b 447 | 448 | 449 | 450 | definition-modulators 451 | 452 | patterns 453 | 454 | 455 | match 456 | ^\s*(===)\s*$ 457 | captures 458 | 459 | 1 460 | 461 | name 462 | keyword.other.where.sk 463 | 464 | 465 | 466 | 467 | match 468 | ^\s*(where)\s+([_[:alpha:]][_[:alnum:]]*) 469 | captures 470 | 471 | 1 472 | 473 | name 474 | keyword.other.where.sk 475 | 476 | 2 477 | 478 | name 479 | entity.name.type.class.sk 480 | 481 | 482 | 483 | 484 | match 485 | ^\s*(where)\s+ 486 | captures 487 | 488 | 1 489 | 490 | name 491 | keyword.other.where.sk 492 | 493 | 494 | 495 | 496 | match 497 | (^\s*(?:inherits|implements|throws))\b([_[:alpha:]][_[:alnum:]]*)? 498 | captures 499 | 500 | 1 501 | 502 | name 503 | keyword.other.requires.sk 504 | 505 | 2 506 | 507 | name 508 | entity.name.type.class.sk 509 | 510 | 511 | 512 | 513 | match 514 | (^\s*(?:requires))\b 515 | captures 516 | 517 | 1 518 | 519 | name 520 | keyword.other.requires.sk 521 | 522 | 523 | 524 | 525 | 526 | func-declaration 527 | 528 | patterns 529 | 530 | 531 | match 532 | \b((?:(?:dispatch|override|extern|rw|partial|async)\s+)*func(?:\s+rw\s+this|\s+this)?)\s+([_[:alpha:]][_[:alnum:]]*)\b 533 | captures 534 | 535 | 1 536 | 537 | name 538 | keyword.other.func.sk 539 | 540 | 2 541 | 542 | name 543 | entity.name.function.sk 544 | 545 | 546 | 547 | 548 | match 549 | \b((?:(unsafe|partial)\s+)*operator(?:\s+(?:binary|unary)))\b 550 | captures 551 | 552 | 1 553 | 554 | name 555 | keyword.other.func.sk 556 | 557 | 558 | 559 | 560 | match 561 | \b(constructor)(\s+[_[:alpha:]][_[:alnum:]]*)? 562 | captures 563 | 564 | 1 565 | 566 | name 567 | keyword.other.func.sk 568 | 569 | 2 570 | 571 | name 572 | entity.name.function.sk 573 | 574 | 575 | 576 | 577 | name 578 | keyword.other.constructor.sk 579 | match 580 | \bconstructor\b 581 | 582 | 583 | name 584 | keyword.other.destructor.sk 585 | match 586 | \bdestructor\b 587 | 588 | 589 | name 590 | keyword.other.func.sk 591 | match 592 | \bfunc\b 593 | 594 | 595 | 596 | macro-declaration 597 | 598 | patterns 599 | 600 | 601 | match 602 | \b(macro)\s+([_[:alpha:]][_[:alnum:]]*)\b 603 | captures 604 | 605 | 1 606 | 607 | name 608 | keyword.other.macro.sk 609 | 610 | 2 611 | 612 | name 613 | entity.name.function.sk 614 | 615 | 616 | 617 | 618 | name 619 | keyword.other.macro.sk 620 | match 621 | \bmacro\b 622 | 623 | 624 | 625 | invoke-declaration 626 | 627 | patterns 628 | 629 | 630 | match 631 | ([_[:alpha:]][_[:alnum:]]*)(?:\s*\() 632 | captures 633 | 634 | 1 635 | 636 | name 637 | entity.name.function.sk 638 | 639 | 640 | 641 | 642 | 643 | control-keywords 644 | 645 | patterns 646 | 647 | 648 | name 649 | keyword.control.conditional.if.sk 650 | match 651 | \bif\b 652 | 653 | 654 | name 655 | keyword.control.conditional.then.sk 656 | match 657 | \bthen\b 658 | 659 | 660 | name 661 | keyword.control.conditional.else.sk 662 | match 663 | \belse\b 664 | 665 | 666 | name 667 | keyword.control.loop.do.sk 668 | match 669 | \bdo\b 670 | 671 | 672 | name 673 | keyword.control.loop.while.sk 674 | match 675 | \bwhile\b 676 | 677 | 678 | name 679 | keyword.control.loop.for.sk 680 | match 681 | \bfor\b 682 | 683 | 684 | name 685 | keyword.control.try.sk 686 | match 687 | \btry\b 688 | 689 | 690 | name 691 | keyword.control.catch.sk 692 | match 693 | \bcatch\b 694 | 695 | 696 | name 697 | keyword.control.flow.yield.sk 698 | match 699 | \byield\b 700 | 701 | 702 | name 703 | keyword.control.flow.return.sk 704 | match 705 | \breturn\b 706 | 707 | 708 | name 709 | keyword.control.flow.break.sk 710 | match 711 | \bbreak\b 712 | 713 | 714 | name 715 | keyword.control.flow.continue.sk 716 | match 717 | \bcontinue\b 718 | 719 | 720 | name 721 | keyword.control.flow.throw.sk 722 | match 723 | \bthrow\b 724 | 725 | 726 | name 727 | keyword.control.flow.ignore.sk 728 | match 729 | \bignore\b 730 | 731 | 732 | name 733 | keyword.control.flow.abort.sk 734 | match 735 | \babort\b 736 | 737 | 738 | name 739 | keyword.control.flow.switch.sk 740 | match 741 | \bswitch\b 742 | 743 | 744 | name 745 | keyword.control.flow.case.sk 746 | match 747 | \bcase\b 748 | 749 | 750 | name 751 | keyword.control.flow.with.sk 752 | match 753 | \bwith\b 754 | 755 | 756 | name 757 | constant.language.boolean.true.sk 758 | match 759 | \btrue\b 760 | 761 | 762 | name 763 | constant.language.boolean.false.sk 764 | match 765 | \bfalse\b 766 | 767 | 768 | name 769 | constant.language.class.null.sk 770 | match 771 | \bnull\b 772 | 773 | 774 | 775 | keywords 776 | 777 | name 778 | keyword.type.sk 779 | match 780 | \b(alias|as|base|default|fatal|get|is|has|let|match|implicit|out|params|ref|in|set|sizeof|this|typeof|value|var)\b 781 | 782 | async-keywords 783 | 784 | name 785 | keyword.type.sk 786 | match 787 | \b(async|await|spawn)\b 788 | 789 | comment 790 | 791 | patterns 792 | 793 | 794 | name 795 | comment.block.sk 796 | begin 797 | /\* 798 | beginCaptures 799 | 800 | 0 801 | 802 | name 803 | punctuation.definition.comment.sk 804 | 805 | 806 | end 807 | \*/ 808 | endCaptures 809 | 810 | 0 811 | 812 | name 813 | punctuation.definition.comment.sk 814 | 815 | 816 | 817 | 818 | begin 819 | (^\s+)?(?=//) 820 | beginCaptures 821 | 822 | 1 823 | 824 | name 825 | punctuation.whitespace.comment.leading.sk 826 | 827 | 828 | end 829 | (?=$) 830 | patterns 831 | 832 | 833 | name 834 | comment.block.documentation.sk 835 | begin 836 | (?<!/)///(?!/) 837 | beginCaptures 838 | 839 | 0 840 | 841 | name 842 | punctuation.definition.comment.sk 843 | 844 | 845 | end 846 | (?=$) 847 | 848 | 849 | name 850 | comment.line.double-slash.sk 851 | begin 852 | (?<!/)//(?!/) 853 | beginCaptures 854 | 855 | 0 856 | 857 | name 858 | punctuation.definition.comment.sk 859 | 860 | 861 | end 862 | (?=$) 863 | 864 | 865 | 866 | 867 | 868 | literals 869 | 870 | patterns 871 | 872 | 873 | include 874 | #numeric-literal 875 | 876 | 877 | include 878 | #char-literal 879 | 880 | 881 | include 882 | #string-literal 883 | 884 | 885 | include 886 | #verbatim-string-literal 887 | 888 | 889 | 890 | numeric-literal 891 | 892 | patterns 893 | 894 | 895 | name 896 | constant.numeric.hex.sk 897 | match 898 | \b0(x|X)[0-9a-fA-F_]+(i8|i16|i32|i64|u8|u16|u32|u64)?\b 899 | 900 | 901 | name 902 | constant.numeric.binary.sk 903 | match 904 | \b0(b|B)[01_]+(i8|i16|i32|i64|u8|u16|u32|u64)?\b 905 | 906 | 907 | name 908 | constant.numeric.decimal.sk 909 | match 910 | \b([0-9_]+)?\.[0-9_]+((e|E)[0-9]+)?(f32|64)?\b 911 | 912 | 913 | name 914 | constant.numeric.decimal.sk 915 | match 916 | \b[0-9_]+(e|E)[0-9_]+(f32|f64)?\b 917 | 918 | 919 | name 920 | constant.numeric.decimal.sk 921 | match 922 | \b[0-9_]+(f32|f64)\b 923 | 924 | 925 | name 926 | constant.numeric.decimal.sk 927 | match 928 | \b[0-9_]+(i8|i16|i32|i64|u8|u16|u32|u64)?\b 929 | 930 | 931 | 932 | char-literal 933 | 934 | name 935 | string.quoted.single.sk 936 | match 937 | '(\s+|[\w\\]+)' 938 | 939 | measure_type 940 | 941 | match 942 | '([a-zA-Z_][a-zA-Z_0-9]*) 943 | captures 944 | 945 | 1 946 | 947 | name 948 | entity.name.type.unit.sk 949 | 950 | 951 | 952 | string-character-escape 953 | 954 | name 955 | constant.character.escape.sk 956 | match 957 | \\. 958 | 959 | string-literal 960 | 961 | name 962 | string.quoted.double.sk 963 | begin 964 | (?<!\\)" 965 | beginCaptures 966 | 967 | 0 968 | 969 | name 970 | punctuation.definition.string.begin.sk 971 | 972 | 973 | end 974 | (")|((?:[^\\\n])$) 975 | endCaptures 976 | 977 | 1 978 | 979 | name 980 | punctuation.definition.string.end.sk 981 | 982 | 2 983 | 984 | name 985 | invalid.illegal.newline.sk 986 | 987 | 988 | patterns 989 | 990 | 991 | include 992 | #string-character-escape 993 | 994 | 995 | 996 | verbatim-string-character-escape 997 | 998 | name 999 | constant.character.escape.sk 1000 | match 1001 | "" 1002 | 1003 | lifetime-identifier 1004 | 1005 | patterns 1006 | 1007 | 1008 | name 1009 | variable.storage.lifetime1.sk 1010 | match 1011 | ##+ 1012 | 1013 | 1014 | name 1015 | variable.storage.lifetime2.sk 1016 | match 1017 | #[A-Za-z_][A-Za-z_0-9]* 1018 | 1019 | 1020 | 1021 | macros 1022 | 1023 | patterns 1024 | 1025 | 1026 | name 1027 | variable.storage.macro.sk 1028 | match 1029 | \$+[A-Za-z_][A-Za-z_0-9]* 1030 | 1031 | 1032 | name 1033 | invalid.sk 1034 | match 1035 | (<\$+|\$+>|\{\$+|\$+\}) 1036 | 1037 | 1038 | 1039 | verbatim-string-literal 1040 | 1041 | name 1042 | string.quoted.double.sk 1043 | begin 1044 | \\" 1045 | beginCaptures 1046 | 1047 | 0 1048 | 1049 | name 1050 | punctuation.definition.string.begin.sk 1051 | 1052 | 1053 | end 1054 | " 1055 | endCaptures 1056 | 1057 | 0 1058 | 1059 | name 1060 | punctuation.definition.string.end.sk 1061 | 1062 | 1063 | patterns 1064 | 1065 | 1066 | include 1067 | #verbatim-string-character-escape 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | -------------------------------------------------------------------------------- /src/ide/vscode/stark/theme/file_type_stark.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | file_type_stark 24 | 25 | 26 | 27 | 29 | 49 | file_type_stark 51 | 61 | 71 | 81 | s 93 | 100 | 103 | 110 | 111 | k 123 | 126 | 133 | 134 | 137 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /src/ide/vscode/stark/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "outDir": "out", 7 | "lib": [ "es2016" ], 8 | "sourceMap": true 9 | }, 10 | "exclude": [ 11 | "node_modules", 12 | "server" 13 | ] 14 | } -------------------------------------------------------------------------------- /src/runtime/readme.md: -------------------------------------------------------------------------------- 1 | # Stark Runtime 2 | 3 | The old runtime prototype based on Roslyn was removed. Use the branch [roslyn-fork-prototype](https://github.com/stark-lang/stark/tree/roslyn-fork-prototype). 4 | 5 | The new runtime is not going to be available soon as the compiler needs to be developed first. --------------------------------------------------------------------------------