├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── build.bat ├── publish └── current │ ├── bin │ └── external │ │ ├── llc.exe │ │ ├── lld-link.exe │ │ └── opt.exe │ ├── bugs │ ├── .vscode │ │ ├── launch.json │ │ ├── settings.json │ │ └── tasks.json │ ├── main.prag │ └── system │ │ ├── linux.prag │ │ ├── math.prag │ │ ├── memory.prag │ │ ├── opengl.prag │ │ ├── png.prag │ │ ├── png_test.prag │ │ ├── preamble.prag │ │ ├── random.prag │ │ ├── simd.prag │ │ ├── vec.prag │ │ ├── vec_simd.prag │ │ ├── windows.prag │ │ ├── work_queue.prag │ │ ├── xml.prag │ │ └── zlib.prag │ ├── include │ └── system │ │ ├── bmp.prag │ │ ├── linux.prag │ │ ├── math.prag │ │ ├── memory.prag │ │ ├── opengl.prag │ │ ├── png.prag │ │ ├── png_test.prag │ │ ├── preamble.prag │ │ ├── qoi.prag │ │ ├── random.prag │ │ ├── simd.prag │ │ ├── vec.prag │ │ ├── vec3_4x.prag │ │ ├── vec3_8x.prag │ │ ├── windows.prag │ │ ├── work_queue.prag │ │ ├── xml.prag │ │ └── zlib.prag │ ├── lib │ ├── Gdi32.Lib │ ├── Ole32.Lib │ ├── OpenGL32.Lib │ ├── User32.Lib │ ├── WinMM.Lib │ ├── kernel32.Lib │ ├── libopenlibm.a │ └── shcore.lib │ ├── new_samples │ ├── hello_world │ │ └── hello_world.prag │ └── opengl │ │ ├── fs.glsl │ │ ├── opengl.prag │ │ ├── opengl_sample.prag │ │ └── vs.glsl │ ├── samples │ ├── .vscode │ │ ├── launch.json │ │ ├── settings.json │ │ └── tasks.json │ ├── basics │ │ ├── advent │ │ │ └── advent_2017.prag │ │ ├── game_of_threes.prag │ │ ├── hello_world.prag │ │ ├── nintendo │ │ │ └── nintendo.prag │ │ └── test_simd.prag │ ├── bootstrap │ │ └── prag.prag │ ├── demo_scene │ │ └── demo.prag │ ├── editor │ │ ├── edit.prag │ │ ├── edit_commands.prag │ │ ├── edit_compile.prag │ │ ├── edit_font.prag │ │ ├── edit_lexer.prag │ │ ├── edit_opengl.prag │ │ ├── edit_text.prag │ │ └── edit_win.prag │ ├── handmade │ │ ├── handmade.prag │ │ ├── handmade_interface.prag │ │ ├── handmade_math.prag │ │ ├── handmade_memory.prag │ │ └── win32_handmade.prag │ ├── ld46 │ │ ├── game.prag │ │ ├── ld.prag │ │ └── renderer.prag │ ├── linux.prag │ ├── math.prag │ ├── memory.prag │ ├── nn │ │ └── nn.prag │ ├── opengl │ │ ├── font.prag │ │ ├── fs.glsl │ │ ├── opengl.prag │ │ ├── test_opengl.prag │ │ └── vs.glsl │ ├── png.prag │ ├── png_test.prag │ ├── preamble.prag │ ├── random.prag │ ├── raytracer │ │ ├── raytracer.prag │ │ └── raytracer_simd.prag │ ├── simd.prag │ ├── smallpt │ │ ├── cpp │ │ │ ├── explicit.cpp │ │ │ ├── forward.cpp │ │ │ └── smallpt.cpp │ │ └── smallpt_win.prag │ ├── test │ │ ├── array.prag │ │ └── bugs.prag │ ├── vec.prag │ ├── vec_simd.prag │ ├── vulkan │ │ ├── vulkan.prag │ │ └── vulkan_test.prag │ ├── wasapi │ │ └── wasapi.prag │ ├── windows.prag │ ├── work_queue.prag │ ├── xml.prag │ └── zlib.prag │ └── template │ ├── launch.json │ ├── main.prag │ ├── settings.json │ └── tasks.json ├── src ├── .vs │ ├── PragmaCore │ │ ├── DesignTimeBuild │ │ │ └── .dtbcache.v2 │ │ ├── project-colors.json │ │ └── v17 │ │ │ └── .futdcache.v1 │ ├── ProjectSettings.json │ ├── VSWorkspaceState.json │ ├── slnx.sqlite │ └── src │ │ ├── FileContentIndex │ │ ├── 2b503f25-0658-48c7-9de3-5564bc78b801.vsidx │ │ ├── 8dd15cf9-c6cf-4b58-a061-bc287799e336.vsidx │ │ ├── e9a7709f-110d-41f2-94d3-46f14184cd56.vsidx │ │ ├── f8e6a904-ea51-4967-92f7-57770534f802.vsidx │ │ └── read.lock │ │ ├── project-colors.json │ │ └── v17 │ │ ├── .wsuo │ │ └── workspaceFileList.bin ├── .vscode │ ├── launch.json │ ├── settings.json │ └── tasks.json ├── AST.Nodes.cs ├── AST.Parser.cs ├── AST.cs ├── Backend.Builder.cs ├── Backend.DI.cs ├── Backend.LL.cs ├── Backend.cs ├── CommandLineOptions.cs ├── Compiler.cs ├── Exceptions.cs ├── Extensions.cs ├── FrontendTypes.cs ├── ParseTreeTransformations.cs ├── PragmaCore.csproj ├── Preprocessor.cs ├── Program.cs ├── SSA.cs ├── Scope.cs ├── Token.cs ├── Tools.cs ├── TypeChecker.cs ├── postbuild.py ├── publish.py ├── src.sln ├── temp │ ├── main.prag │ └── system │ │ ├── linux.prag │ │ ├── math.prag │ │ ├── memory.prag │ │ ├── png.prag │ │ ├── png_test.prag │ │ ├── preamble.prag │ │ ├── random.prag │ │ ├── simd.prag │ │ ├── vec.prag │ │ ├── vec_simd.prag │ │ ├── windows.prag │ │ ├── work_queue.prag │ │ ├── xml.prag │ │ └── zlib.prag └── todo.txt └── tools ├── PragmaLangClient ├── .eslintrc.json ├── .gitattributes ├── .gitignore ├── .vscode │ ├── extensions.json │ ├── launch.json │ ├── settings.json │ └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── README.md ├── language-configuration.json ├── package-lock.json ├── package.bat ├── package.json ├── server │ ├── PragmaLangServer.deps.json │ ├── PragmaLangServer.runtimeconfig.json │ └── System.Reactive.xml ├── src │ ├── extension.ts │ └── test │ │ ├── runTest.ts │ │ └── suite │ │ ├── extension.test.ts │ │ └── index.ts ├── syntaxes │ └── pragma.tmLanguage.json ├── tsconfig.json └── vsc-extension-quickstart.md └── PragmaLangServer ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── BufferManager.cs ├── CompletionHandler.cs ├── Debugger.cs ├── DefinitionHandler.cs ├── LanguageHelper.cs ├── PragmaLangServer.csproj ├── PragmaLangServer.sln ├── Program.cs ├── SignatureHelpHandler.cs ├── TextDocumentSyncHandler.cs └── UriHelper.cs /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | .prag diff 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | publish/releases/* 2 | 3 | *.exe 4 | *.dll 5 | *.libcolo 6 | *.manifest 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | 16 | 17 | # Build results 18 | [Dd]ebug/ 19 | [Dd]ebugPublic/ 20 | [Rr]elease/ 21 | x64/ 22 | Builds/ 23 | build/ 24 | bld/ 25 | [Bb]in/ 26 | [Oo]bj/ 27 | 28 | # Roslyn cache directories 29 | *.ide/ 30 | 31 | # MSTest test Results 32 | [Tt]est[Rr]esult*/ 33 | [Bb]uild[Ll]og.* 34 | 35 | #NUNIT 36 | *.VisualState.xml 37 | TestResult.xml 38 | 39 | # Build Results of an ATL Project 40 | [Dd]ebugPS/ 41 | [Rr]eleasePS/ 42 | dlldata.c 43 | 44 | *_i.c 45 | *_p.c 46 | *_i.h 47 | *.ilk 48 | *.meta 49 | *.obj 50 | *.pch 51 | *.pdb 52 | *.pgc 53 | *.pgd 54 | *.rsp 55 | *.sbr 56 | *.tlb 57 | *.tli 58 | *.tlh 59 | *.tmp 60 | *.tmp_proj 61 | *.log 62 | *.vspscc 63 | *.vssscc 64 | .builds 65 | *.pidb 66 | *.svclog 67 | *.scc 68 | 69 | # Chutzpah Test files 70 | _Chutzpah* 71 | 72 | # Visual C++ cache files 73 | ipch/ 74 | *.aps 75 | *.ncb 76 | *.opensdf 77 | *.sdf 78 | *.cachefile 79 | 80 | # Visual Studio profiler 81 | *.psess 82 | *.vsp 83 | *.vspx 84 | 85 | # TFS 2012 Local Workspace 86 | $tf/ 87 | 88 | # Guidance Automation Toolkit 89 | *.gpState 90 | 91 | # ReSharper is a .NET coding add-in 92 | _ReSharper*/ 93 | *.[Rr]e[Ss]harper 94 | *.DotSettings.user 95 | 96 | # JustCode is a .NET coding addin-in 97 | .JustCode 98 | 99 | # TeamCity is a build add-in 100 | _TeamCity* 101 | 102 | # DotCover is a Code Coverage Tool 103 | *.dotCover 104 | 105 | # NCrunch 106 | _NCrunch_* 107 | .*crunch*.local.xml 108 | 109 | # MightyMoose 110 | *.mm.* 111 | AutoTest.Net/ 112 | 113 | # Web workbench (sass) 114 | .sass-cache/ 115 | 116 | # Installshield output folder 117 | [Ee]xpress/ 118 | 119 | # DocProject is a documentation generator add-in 120 | DocProject/buildhelp/ 121 | DocProject/Help/*.HxT 122 | DocProject/Help/*.HxC 123 | DocProject/Help/*.hhc 124 | DocProject/Help/*.hhk 125 | DocProject/Help/*.hhp 126 | DocProject/Help/Html2 127 | DocProject/Help/html 128 | 129 | # Publish Web Output 130 | *.[Pp]ublish.xml 131 | *.azurePubxml 132 | ## TODO: Comment the next line if you want to checkin your 133 | ## web deploy settings but do note that will include unencrypted 134 | ## passwords 135 | #*.pubxml 136 | 137 | # NuGet Packages Directory 138 | packages/* 139 | ## TODO: If the tool you use requires repositories.config 140 | ## uncomment the next line 141 | #!packages/repositories.config 142 | 143 | # Enable "build/" folder in the NuGet Packages folder since 144 | # NuGet packages use it for MSBuild targets. 145 | # This line needs to be after the ignore of the build folder 146 | # (and the packages folder if the line above has been uncommented) 147 | !packages/build/ 148 | 149 | # Windows Azure Build Output 150 | csx/ 151 | *.build.csdef 152 | 153 | # Windows Store app package directory 154 | AppPackages/ 155 | 156 | # Others 157 | sql/ 158 | *.Cache 159 | ClientBin/ 160 | [Ss]tyle[Cc]op.* 161 | ~$* 162 | *~ 163 | *.dbmdl 164 | *.dbproj.schemaview 165 | *.pfx 166 | *.publishsettings 167 | node_modules/ 168 | bower_components/ 169 | 170 | # RIA/Silverlight projects 171 | Generated_Code/ 172 | 173 | # Backup & report files from converting an old project file 174 | # to a newer Visual Studio version. Backup files are not needed, 175 | # because we have git ;-) 176 | _UpgradeReport_Files/ 177 | Backup*/ 178 | UpgradeLog*.XML 179 | UpgradeLog*.htm 180 | 181 | # SQL Server files 182 | *.mdf 183 | *.ldf 184 | 185 | # Business Intelligence projects 186 | *.rdl.data 187 | *.bim.layout 188 | *.bim_*.settings 189 | 190 | # Microsoft Fakes 191 | FakesAssemblies/ 192 | 193 | # LightSwitch generated files 194 | GeneratedArtifacts/ 195 | _Pvt_Extensions/ 196 | ModelManifest.xml 197 | 198 | Browse.VC.db 199 | Browse.VC.opendb 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 pragmascript 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # pragma 3 | A programming language that aims to be slightly more comfy than C without sacrificing performance. 4 | 5 | ## Small Pathtracer Example 6 | 7 | [![Video](http://i.imgur.com/0HdTMz6.jpg)](https://www.youtube.com/watch?v=KslrcXqJ4iU) 8 | 9 | ## Syntax Example (everything is still in flux) 10 | 11 | ```csharp 12 | import "preamble.prag" 13 | 14 | [ 15 | "compile.output": "hello_world.exe", 16 | "compile.entry" : "true", 17 | "compile.debug" : "true", 18 | "compile.opt" : "0", 19 | "compile.run" : "true", 20 | "compile.libs" : "kernel32.lib", 21 | "compile.path" : "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.14393.0\um\x64" 22 | ] 23 | let main = fun () => void 24 | { 25 | print_string("hello, world!\n"); 26 | for (var i = 0; i < 12; ++i) { 27 | print_i32(i + 1); 28 | if (i != 11) { 29 | print_string(", "); 30 | } 31 | } 32 | print_string("\n"); 33 | } 34 | 35 | ``` 36 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | cd src 2 | call dotnet build -c %1 3 | 4 | cd.. 5 | cd tools 6 | cd PragmaLangServer 7 | call dotnet publish -c %1 8 | 9 | cd .. 10 | cd .. 11 | cd tools 12 | cd PragmaLangClient 13 | call package.bat %1 14 | call code --install-extension pragmalangclient-0.0.1.vsix 15 | cd .. 16 | cd .. 17 | -------------------------------------------------------------------------------- /publish/current/bin/external/llc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/publish/current/bin/external/llc.exe -------------------------------------------------------------------------------- /publish/current/bin/external/lld-link.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/publish/current/bin/external/lld-link.exe -------------------------------------------------------------------------------- /publish/current/bin/external/opt.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/publish/current/bin/external/opt.exe -------------------------------------------------------------------------------- /publish/current/bugs/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "(Windows) Launch", 6 | "type": "cppvsdbg", 7 | "request": "launch", 8 | "program": "${workspaceRoot}/bin/output.exe", 9 | "args": [], 10 | "stopAtEntry": false, 11 | "cwd": "${workspaceRoot}/bin/", 12 | "environment": [], 13 | "externalConsole": true 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /publish/current/bugs/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "debug.allowBreakpointsEverywhere": true, 4 | "pragma.includeDirectory": "C:\\Projects\\dotnet\\PragmaScript\\publish\\current\\include" 5 | } -------------------------------------------------------------------------------- /publish/current/bugs/.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 | "label": "build", 8 | "type": "shell", 9 | "windows": { 10 | "command": "pragma" 11 | }, 12 | "linux": { 13 | "command": "pragma" 14 | }, 15 | "group": { 16 | "kind": "build", 17 | "isDefault": true 18 | }, 19 | "args": [ 20 | "build", 21 | "-d", 22 | "\"${file}\"" 23 | ], 24 | "problemMatcher": [ 25 | { 26 | "fileLocation": "absolute", 27 | "pattern": { 28 | "regexp": "error: (.*?) at \\(.*?file \"(.*?)\".*?line (.*?),.*?pos (.*?),", 29 | "message": 1, 30 | "file": 2, 31 | "line": 3, 32 | "column": 4 33 | }, 34 | "applyTo": "allDocuments", 35 | "severity": "error" 36 | }, 37 | { 38 | "fileLocation": "absolute", 39 | "pattern": { 40 | "regexp": "(Assertion) failed at: \\(file \"(.*?)\".*?line (.*?),.*?pos (.*?)\\)", 41 | "message": 1, 42 | "file": 2, 43 | "line": 3, 44 | "column": 4 45 | }, 46 | "applyTo": "allDocuments" 47 | } 48 | ] 49 | }, 50 | { 51 | "label": "build release", 52 | "type": "shell", 53 | "command": "pragma", 54 | "group": "build", 55 | "args": [ 56 | "build", 57 | "${file}" 58 | ], 59 | "problemMatcher": [ 60 | { 61 | "fileLocation": "absolute", 62 | "pattern": { 63 | "regexp": "error: (.*?) at \\(.*?file \"(.*?)\".*?line (.*?),.*?pos (.*?),", 64 | "message": 1, 65 | "file": 2, 66 | "line": 3, 67 | "column": 4 68 | }, 69 | "applyTo": "allDocuments", 70 | "severity": "error" 71 | }, 72 | { 73 | "fileLocation": "absolute", 74 | "pattern": { 75 | "regexp": "(Assertion) failed at: \\(file \"(.*?)\".*?line (.*?),.*?pos (.*?)\\)", 76 | "message": 1, 77 | "file": 2, 78 | "line": 3, 79 | "column": 4 80 | }, 81 | "applyTo": "allDocuments" 82 | } 83 | ] 84 | } 85 | ], 86 | } -------------------------------------------------------------------------------- /publish/current/bugs/main.prag: -------------------------------------------------------------------------------- 1 | import "system/preamble.prag" 2 | 3 | [ 4 | "compile.entry", 5 | "compile.run":"true", 6 | "compile.opt": "0", 7 | "compile.debuginfo": "true" 8 | ] 9 | let main = fun () => void { 10 | print("hello, world!\n"); 11 | var x = 3; 12 | debug_print("x", x); 13 | x += 7; 14 | debug_print("x", x); 15 | } 16 | -------------------------------------------------------------------------------- /publish/current/bugs/system/linux.prag: -------------------------------------------------------------------------------- 1 | mod Linux 2 | { 3 | ["stub"] 4 | let __write = extern fun(fd: i32; buf: ptr; size: mm) => i64; 5 | 6 | ["stub"] 7 | let __read = extern fun(fd: i32; buf: ptr; size: mm) => i64; 8 | 9 | ["stub"] 10 | let __open = extern fun(filename: i8*; flags: i32; mode: i32) => i32; 11 | 12 | ["stub"] 13 | let __close = extern fun(fd: i32) => i32; 14 | 15 | ["stub"] 16 | let __openat = extern fun(dirfd: i32; filename: i8*; flags: i32; mode: i32) => i32; 17 | 18 | ["stub"] 19 | let __mmap = extern fun(addr: ptr; length: mm; prot: i32; flags: i32; fd: i32; offset: mm) => ptr; 20 | 21 | ["stub"] 22 | let __munmap = extern fun(addr: ptr; length: mm) => i32; 23 | 24 | 25 | // *** Dumping AST Record Layout 26 | // 0 | struct stat 27 | // 0 | __dev_t st_dev 28 | // 8 | __ino_t st_ino 29 | // 16 | __nlink_t st_nlink 30 | // 24 | __mode_t st_mode 31 | // 28 | __uid_t st_uid 32 | // 32 | __gid_t st_gid 33 | // 36 | int __pad0 34 | // 40 | __dev_t st_rdev 35 | // 48 | __off_t st_size 36 | // 56 | __blksize_t st_blksize 37 | // 64 | __blkcnt_t st_blocks 38 | // 72 | struct timespec st_atim 39 | // 72 | __time_t tv_sec 40 | // 80 | __syscall_slong_t tv_nsec 41 | // 88 | struct timespec st_mtim 42 | // 88 | __time_t tv_sec 43 | // 96 | __syscall_slong_t tv_nsec 44 | // 104 | struct timespec st_ctim 45 | // 104 | __time_t tv_sec 46 | // 112 | __syscall_slong_t tv_nsec 47 | // 120 | __syscall_slong_t [3] __glibc_reserved 48 | // | [sizeof=144, dsize=144, align=8, 49 | // | nvsize=144, nvalign=8] 50 | 51 | 52 | let timespec = struct( 53 | tv_sec: i64; 54 | tv_nsec: i64; 55 | ); 56 | 57 | ["packed"] 58 | let stat = struct( 59 | st_dev: i64; 60 | st_ino: i64; 61 | st_nlink: i64; 62 | st_mode: i32; 63 | st_uid: i32; 64 | st_gid: i32; 65 | __pad0: i32; 66 | st_rdev: i64; 67 | st_size: i64; 68 | st_blksize: i64; 69 | st_blocks: i64; 70 | st_atim: timespec; 71 | st_mtim: timespec; 72 | st_ctim: timespec; 73 | reserved: i64[3]; 74 | ); 75 | 76 | ["stub"] 77 | let __fstatat = extern fun(dfd: i32; filename: i8*; statbuf: i8*; flag: i32) => i32; 78 | 79 | let MAP_SHARED = 0x01; 80 | let MAP_PRIVATE = 0x02; 81 | let MAP_TYPE = 0x0F; 82 | let MAP_FIXED = 0x10; 83 | let MAP_ANON = 0x20; 84 | let MAP_ANONYMOUS = MAP_ANON; 85 | let MAP_NORESERVE = 0x4000; 86 | let MAP_GROWSDOWN = 0x0100; 87 | let MAP_DENYWRITE = 0x0800; 88 | let MAP_EXECUTABLE = 0x1000; 89 | let MAP_LOCKED = 0x2000; 90 | let MAP_POPULATE = 0x8000; 91 | let MAP_NONBLOCK = 0x10000; 92 | let MAP_STACK = 0x20000; 93 | let MAP_HUGETLB = 0x40000; 94 | let MAP_FILE = 0; 95 | 96 | let PROT_NONE = 0; 97 | let PROT_READ = 1; 98 | let PROT_WRITE = 2; 99 | let PROT_EXEC = 4; 100 | let PROT_GROWSDOWN = 0x01000000; 101 | let PROT_GROWSUP = 0x02000000; 102 | 103 | let MS_ASYNC = 1; 104 | let MS_INVALIDATE = 2; 105 | let MS_SYNC = 4; 106 | 107 | let MCL_CURRENT = 1; 108 | let MCL_FUTURE = 2; 109 | let MCL_ONFAULT = 4; 110 | 111 | let POSIX_MADV_NORMAL = 0; 112 | let POSIX_MADV_RANDOM = 1; 113 | let POSIX_MADV_SEQUENTIAL = 2; 114 | let POSIX_MADV_WILLNEED = 3; 115 | let POSIX_MADV_DONTNEED = 4; 116 | 117 | let O_ACCMODE = 0x0003; 118 | let O_RDONLY = 0x0000; 119 | let O_WRONLY = 0x0001; 120 | let O_RDWR = 0x0002; 121 | let O_CREAT = 0x0040; 122 | let O_EXCL = 0x0080; 123 | let O_NOCTTY = 0x0100; 124 | let O_TRUNC = 0x0200; 125 | let O_APPEND = 0x0400; 126 | let O_NONBLOCK = 0x0800; 127 | let O_NDELAY = O_NONBLOCK; 128 | let O_SYNC = 0x101000; 129 | let O_FSYNC = O_SYNC; 130 | let O_ASYNC = 0x2000; 131 | let O_LARGEFILE = 0x8000; 132 | 133 | let AT_FDCWD = -100; 134 | 135 | 136 | } -------------------------------------------------------------------------------- /publish/current/bugs/system/math.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | // http://openlibm.org/ 3 | mod Math 4 | { 5 | let pi: f64 = 3.1415926535897932384626433832795028841971693993751058209749445923078164062; 6 | let half_pi = pi / 2.0; 7 | let pi_32 = pi@f32; 8 | let half_pi_32 = half_pi@f32; 9 | let tau = 2.0 * pi; 10 | let tau_32 = 2.0 * pi_32; 11 | 12 | ["READNONE"] 13 | let sin = extern("llvm.sin.f32") fun (x: f32) => f32; 14 | ["READNONE"] 15 | let cos = extern("llvm.cos.f32") fun (x: f32) => f32; 16 | ["READNONE"] 17 | let tan = extern("tanf") fun (x: f32) => f32; 18 | ["READNONE"] 19 | let asin = extern("asinf") fun (x: f32) => f32; 20 | ["READNONE"] 21 | let acos = extern("acosf") fun (x: f32) => f32; 22 | ["READNONE"] 23 | let atan = extern("atanf") fun (x: f32) => f32; 24 | ["READNONE"] 25 | let atan2 = extern("atan2f") fun (x: f32) => f32; 26 | ["READNONE"] 27 | let sqrt = extern("llvm.sqrt.f32") fun (x: f32) => f32; 28 | ["READNONE"] 29 | let pow = extern("llvm.pow.f32") fun (x: f32; p: f32) => f32; 30 | ["READNONE"] 31 | let abs = extern("llvm.fabs.f32") fun (x: f32) => f32; 32 | ["READNONE"] 33 | let floor = extern("llvm.floor.f32") fun (x: f32) => f32; 34 | ["READNONE"] 35 | let trunc = extern("llvm.trunc.f32") fun (x: f32) => f32; 36 | ["READNONE"] 37 | let ceil = extern("llvm.ceil.f32") fun (x: f32) => f32; 38 | ["READNONE"] 39 | let round = extern("llvm.round.f32") fun (x: f32) => f32; 40 | ["READNONE"] 41 | let exp = extern("llvm.exp.f32") fun (x: f32) => f32; 42 | ["READNONE"] 43 | let exp2 = extern("llvm.exp2.f32") fun (x: f32) => f32; 44 | ["READNONE"] 45 | let log = extern("llvm.log.f32") fun (x: f32) => f32; 46 | ["READNONE"] 47 | let log2 = extern("llvm.log2.f32") fun (x: f32) => f32; 48 | ["READNONE"] 49 | let log10 = extern("llvm.log10.f32") fun (x: f32) => f32; 50 | 51 | ["READNONE"] 52 | let exp = extern("llvm.exp.f32") fun (x: f32_4x) => f32_4x; 53 | ["READNONE"] 54 | let log = extern("llvm.log.f32") fun (x: f32_4x) => f32_4x; 55 | 56 | 57 | // ["READNONE"] 58 | // let min = extern("llvm.minnum.f32") fun (a: f32; b: f32) => f32; 59 | // ["READNONE"] 60 | // let max = extern("llvm.maxnum.f32") fun (a: f32; b: f32) => f32; 61 | 62 | ["READNONE"] 63 | let min = fun(a: f32; b: f32) => f32 { 64 | if (a < b) { 65 | return a; 66 | } else { 67 | return b; 68 | } 69 | } 70 | 71 | ["READNONE"] 72 | let max = fun(a: f32; b: f32) => f32 { 73 | if (a > b) { 74 | return a; 75 | } else { 76 | return b; 77 | } 78 | } 79 | 80 | ["READNONE"] 81 | let max = fun(a: i32; b: i32) => i32 { 82 | if (a > b) { 83 | return a; 84 | } else { 85 | return b; 86 | } 87 | } 88 | 89 | ["READNONE"] 90 | let min = fun(a: i32; b: i32) => i32 { 91 | if (a < b) { 92 | return a; 93 | } else { 94 | return b; 95 | } 96 | } 97 | 98 | let swap = fun (a: f32*; b: f32*) => void { 99 | var temp = *a; 100 | *a = *b; 101 | *b = temp; 102 | } 103 | 104 | ["READNONE"] 105 | let round_to_i32 = fun (x: f32) => i32 { 106 | return round(x)@i32; 107 | } 108 | ["READNONE"] 109 | let remainder = fun(x: f32; y: f32) => f32 110 | { 111 | return x - floor(x / y) * y; 112 | } 113 | ["READNONE"] 114 | let lerp = fun(a: f32; b: f32; t: f32) => f32 115 | { 116 | return a + (b-a)*t; 117 | } 118 | ["READNONE"] 119 | let abs = fun (value: i32) => i32 120 | { 121 | if (value >= 0) { 122 | return value; 123 | } else { 124 | return -value; 125 | } 126 | } 127 | 128 | ["READNONE"] 129 | let sign = fun (value: f32) => f32 { 130 | if (value > 0) { 131 | return 1.0; 132 | } elif (value < 0) { 133 | return -1.0; 134 | } else { 135 | return 0.0; 136 | } 137 | } 138 | 139 | ["READNONE"] 140 | let clamp = fun 141 | ( 142 | value: i32; 143 | min: i32; 144 | max: i32 145 | ) => i32 146 | { 147 | assert(min <= max); 148 | var result = value; 149 | if (result < min) { 150 | result = min; 151 | } elif (result > max) { 152 | result = max; 153 | } 154 | return result; 155 | } 156 | 157 | ["READNONE"] 158 | let clamp = fun (value: f32; min: f32; max: f32) => f32 159 | { 160 | assert(min <= max); 161 | var result = value; 162 | if (result < min) { 163 | result = min; 164 | } elif (result > max) { 165 | result = max; 166 | } 167 | return result; 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /publish/current/bugs/system/memory.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | 3 | let memory_arena = struct( 4 | size: mm; 5 | base: ptr; 6 | used: mm; 7 | ); 8 | 9 | let align_4 = fun(value: mm) => mm{ 10 | return (value + 3) & (~3); 11 | } 12 | let align_8 = fun(value: mm) => mm { 13 | return (value + 7) & (~7); 14 | } 15 | let align_16 = fun(value: mm) => mm { 16 | return (value + 15) & (~15); 17 | } 18 | 19 | let push = fun(@arena: memory_arena*; push_size: mm) => ptr { 20 | var result = base + used; 21 | // result = align_16(result@mm)@ptr; 22 | 23 | used = result@mm - base@mm + push_size@mm; 24 | 25 | if (used > size) { 26 | assert(false); 27 | return nullptr; 28 | } 29 | return result; 30 | } 31 | 32 | let start_temp = fun(@arena: memory_arena*;) => mm { 33 | return used; 34 | } 35 | 36 | let stop_temp = fun(@arena: memory_arena*; temp_used: mm) => void { 37 | used = temp_used; 38 | } 39 | mod _INTERNAL { 40 | // TODO(pragma): this stuff should be thread local? 41 | var temp_memory_stack_pos: i32; 42 | var temp_memory_stack: mm[32]; 43 | } 44 | 45 | 46 | // TODO(pragma): make this threadsafe 47 | let push_temp = fun(@arena: memory_arena* = &temp_memory_arena) => void { 48 | _INTERNAL::temp_memory_stack[_INTERNAL::temp_memory_stack_pos++] = start_temp(arena); 49 | if (_INTERNAL::temp_memory_stack_pos@mm >= len(_INTERNAL::temp_memory_stack)) { 50 | assert(false, "Exceeded max temp memory stack size!"); 51 | } 52 | } 53 | 54 | // TODO(pragma): make this threadsafe 55 | let pop_temp = fun(@arena: memory_arena* = &temp_memory_arena) => void { 56 | _INTERNAL::temp_memory_stack_pos--; 57 | if (_INTERNAL::temp_memory_stack_pos < 0) { 58 | assert(false, "Inbalanced push_temp pop_temp operations. Stack pos below 0!"); 59 | } 60 | stop_temp(arena, _INTERNAL::temp_memory_stack[_INTERNAL::temp_memory_stack_pos]); 61 | } 62 | 63 | let create_arena = fun(size: mm) => memory_arena { 64 | var data = allocate(size); 65 | var result: memory_arena; 66 | if (data != nullptr) { 67 | result.size = size; 68 | result.base = data; 69 | result.used = 0; 70 | } else { 71 | result.size = 0; 72 | result.base = nullptr; 73 | result.used = 0; 74 | } 75 | return result; 76 | } 77 | 78 | let get_slice = fun(@arena: memory_arena*) => i8[] { 79 | var result = base[:used@i32]; 80 | return result; 81 | } 82 | -------------------------------------------------------------------------------- /publish/current/bugs/system/random.prag: -------------------------------------------------------------------------------- 1 | 2 | mod Random 3 | { 4 | let seed0 = 12345; 5 | let seed1 = 33333; 6 | let seed2 = 982845; 7 | let seed3 = 11293929; 8 | 9 | let state = struct 10 | ( 11 | z1: i32_4x; 12 | z2: i32_4x; 13 | z3: i32_4x; 14 | z4: i32_4x; 15 | ); 16 | 17 | // var state: state = state{seed0, seed0, seed0, seed0}; 18 | var state: state = state { 19 | i32_4x {seed0, seed1, seed2, seed3}, 20 | i32_4x {seed0, seed1, seed2, seed3}, 21 | i32_4x {seed0, seed1, seed2, seed3}, 22 | i32_4x {seed0, seed1, seed2, seed3} 23 | }; 24 | 25 | 26 | let init_seed = fun (seed: i32_4x; state: state*) => void { 27 | state.z1 = seed; 28 | state.z2 = seed; 29 | state.z3 = seed; 30 | state.z4 = seed; 31 | } 32 | 33 | let rand_i32_4x = fun (@state: state*) => i32_4x { 34 | let vi_2 = i32_4x { 2, 2, 2, 2 }; 35 | let vi_3 = i32_4x { 3, 3, 3, 3 }; 36 | let vi_6 = i32_4x { 6, 6, 6, 6 }; 37 | let vi_7 = i32_4x { 7, 7, 7, 7 }; 38 | let vi_12 = i32_4x { 12, 12, 12, 12 }; 39 | let vi_13 = i32_4x { 13, 13, 13, 13}; 40 | let vi_18 = i32_4x { 18, 18, 18, 18}; 41 | let vi_21 = i32_4x { 21, 21, 21, 21}; 42 | let vi_27 = i32_4x { 27, 27, 27, 27}; 43 | let vi_m0 = i32_4x { 4294967294, 4294967294, 4294967294, 4294967294 }; 44 | let vi_m1 = i32_4x { 4294967288, 4294967288, 4294967288, 4294967288 }; 45 | let vi_m2 = i32_4x { 4294967280, 4294967280, 4294967280, 4294967280 }; 46 | let vi_m3 = i32_4x { 4294967168, 4294967168, 4294967168, 4294967168 }; 47 | 48 | var b: i32_4x; 49 | b = ((z1 << vi_6) ^ z1) >>\ vi_13; 50 | z1 = ((z1 & vi_m0) << vi_18) ^ b; 51 | b = ((z2 << vi_2) ^ z2) >>\ vi_27; 52 | z2 = ((z2 & vi_m1) << vi_2) ^ b; 53 | b = ((z3 << vi_13) ^ z3) >>\ vi_21; 54 | z3 = ((z3 & vi_m2) << vi_7) ^ b; 55 | b = ((z4 << vi_3) ^ z4) >>\ vi_12; 56 | z4 = ((z4 & vi_m3) << vi_13) ^ b; 57 | return (z1 ^ z2 ^ z3 ^ z4); 58 | } 59 | 60 | let rand_f32_4x = fun(min: f32_4x = f32_4x { 0.0, 0.0, 0.0, 0.0 }; max: f32_4x = f32_4x { 1.0, 1.0, 1.0, 1.0 }; state: state* = &state) => f32_4x { 61 | let div = f32_4x { 4294967295.0, 4294967295.0, 4294967295.0, 4294967295.0 }; 62 | var x = rand_i32_4x(state); 63 | var result = @\f32_4x x / div; 64 | result = min + result * (max - min); 65 | return result; 66 | } 67 | 68 | let rand_i32 = fun(state: state* = &state) => i32 { 69 | var result = rand_i32_4x(state); 70 | return result[0]; 71 | } 72 | 73 | let rand_f32 = fun (min: f32 = 0.0; max: f32 = 1.0; state: state* = &state;) => f32 { 74 | var x = rand_i32(state); 75 | var result = @\f32 x / 4294967295.0; 76 | result = min + result * (max - min); 77 | return result; 78 | } 79 | let rand_xkcd = fun () => i32 { 80 | return 4; // chosen by fair dice roll. 81 | // guaranteed to be random. 82 | } 83 | } -------------------------------------------------------------------------------- /publish/current/bugs/system/simd.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | mod SIMD 3 | { 4 | // declare <4 x float> @llvm.x86.sse.max.ps(<4 x float>, <4 x float>) 5 | 6 | let max_ps = extern("llvm.x86.sse.max.ps") fun (a: f32_4x; b: f32_4x) => f32_4x; 7 | let min_ps = extern("llvm.x86.sse.min.ps") fun (a: f32_4x; b: f32_4x) => f32_4x; 8 | 9 | 10 | let set1_ps = fun(v: f32) => f32_4x { 11 | return f32_4x { v, v, v, v }; 12 | } 13 | let set1_epi32 = fun(v: i32) => i32_4x { 14 | return i32_4x {v, v, v, v}; 15 | } 16 | let cvtepi32_ps = fun(v: i32_4x) => f32_4x { 17 | return v@f32_4x; 18 | } 19 | 20 | let rcp_ps = extern("llvm.x86.sse.rcp.ps") fun(v: f32_4x) => f32_4x; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /publish/current/bugs/system/work_queue.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | import "windows.prag" 3 | import "random.prag" 4 | import "math.prag" 5 | 6 | let work_queue_callback = fun(queue: work_queue*; data: ptr) => void; 7 | 8 | let work_queue_entry = struct( 9 | callback: work_queue_callback; 10 | data: ptr; 11 | ); 12 | 13 | let work_queue = struct( 14 | ["VOLATILE"] 15 | completion_goal: i32; 16 | ["VOLATILE"] 17 | completion_count: i32; 18 | ["VOLATILE"] 19 | next_entry_to_write: i32; 20 | ["VOLATILE"] 21 | next_entry_to_read: i32; 22 | semaphore_handle: mm; 23 | entries: work_queue_entry[1024]; 24 | ); 25 | 26 | 27 | let add_entry = fun(@queue: work_queue*; data: ptr; callback: work_queue_callback) => void { 28 | var entry = create_work_entry(data, callback); 29 | add_entry(queue, entry); 30 | } 31 | 32 | let add_entry = fun (@queue: work_queue*; entry: work_queue_entry) => void { 33 | var temp_queue = queue; 34 | var target_next_entry_to_write = next_entry_to_write + 1; 35 | if (target_next_entry_to_write >= len(entries)@i32) { 36 | assert(target_next_entry_to_write == len(entries)@i32); 37 | target_next_entry_to_write = 0; 38 | } 39 | assert(target_next_entry_to_write != next_entry_to_read); 40 | entries[next_entry_to_write] = entry; 41 | queue.completion_goal += 1; 42 | 43 | _WriteBarrier(); 44 | 45 | queue.next_entry_to_write = target_next_entry_to_write; 46 | Windows::ReleaseSemaphore(semaphore_handle, 1, 0@i32*); 47 | } 48 | 49 | let next_entry = fun(@queue: work_queue*) => bool 50 | { 51 | var temp_queue = queue; 52 | var should_sleep = false; 53 | var original_next_entry_to_read = queue.next_entry_to_read; 54 | var target_next_entry_to_read = original_next_entry_to_read + 1; 55 | if (target_next_entry_to_read >= len(entries)@i32) { 56 | assert(target_next_entry_to_read == len(entries)@i32); 57 | target_next_entry_to_read = 0; 58 | } 59 | if (original_next_entry_to_read != next_entry_to_write) { 60 | var idx = atomic_compare_and_swap( 61 | &next_entry_to_read, 62 | target_next_entry_to_read, 63 | original_next_entry_to_read 64 | ); 65 | if (idx == original_next_entry_to_read) { 66 | var entry = entries[idx]; 67 | entry.callback(queue, entry.data); 68 | atomic_inc(&queue.completion_count); 69 | } 70 | } else { 71 | should_sleep = true; 72 | } 73 | return should_sleep; 74 | } 75 | 76 | let wait_for_completion = fun(queue: work_queue*) => void { 77 | var temp_queue = queue; 78 | while (queue.completion_goal != queue.completion_count) { 79 | Windows::Sleep(10); 80 | // if (!next_entry(queue)) { 81 | // debug_print("percent", Math::round_to_i32(100.0 * queue.completion_count@f32 / queue.completion_goal@f32)); 82 | // } 83 | } 84 | debug_print("percent", Math::round_to_i32(100.0 * queue.completion_count@f32 / queue.completion_goal@f32)); 85 | } 86 | 87 | let work_queue_thread_proc = fun(data: ptr) => void { 88 | var queue = data@work_queue*; 89 | while (true) { 90 | if (next_entry(queue)) { 91 | Windows::WaitForSingleObject(queue.semaphore_handle, Windows::INFINITE); 92 | } 93 | } 94 | } 95 | 96 | let init_work_queue = fun(queue: work_queue*; worker_count: i32) => void { 97 | var temp_queue = queue; 98 | queue.completion_goal = 0; 99 | queue.completion_count = 0; 100 | queue.next_entry_to_write = 0; 101 | queue.next_entry_to_read = 0; 102 | var initial_count = 0; 103 | queue.semaphore_handle = Windows::CreateSemaphoreA(nullptr, initial_count, worker_count + 1, nullptr); 104 | for (var worker_idx = 0; worker_idx < worker_count; ++worker_idx) { 105 | var handle = Windows::CreateThread(nullptr, 0, work_queue_thread_proc@Windows::ThreadProc, queue@ptr, 0, 0@mm*); 106 | Windows::CloseHandle(handle); 107 | } 108 | } 109 | 110 | let create_work_entry = fun(data: ptr; callback: work_queue_callback) => work_queue_entry 111 | { 112 | var result = work_queue_entry {}; 113 | result.data = data; 114 | result.callback = callback; 115 | return result; 116 | } 117 | 118 | 119 | let test_sleep_rnd = fun(queue: work_queue*; data: ptr) => void { 120 | var temp_queue = queue; 121 | var state: Random::state; 122 | var seed = data@i32; 123 | debug_print("seed", seed); 124 | 125 | Random::init_seed(i32_4x{ seed, seed^3023141, seed^82318, seed^113 }, &state); 126 | var ms = Random::rand_i32(&state) % 5000; 127 | debug_print("sleeping for [ms]", ms); 128 | Windows::Sleep(ms); 129 | } 130 | 131 | 132 | #if false 133 | [ 134 | "compile.output": "test_work_queue.exe", 135 | "compile.debuginfo": "true", 136 | "compile.entry" : "true", 137 | "compile.ll" : "true", 138 | "compile.asm" : "false", 139 | "compile.opt" : "0", 140 | "compile.run" : "false", 141 | "compile.libs" : "kernel32.lib" 142 | ] 143 | let main = fun () => void { 144 | var queue = work_queue { }; 145 | init_work_queue(&queue, 8); 146 | 147 | for (var work_idx = 0; work_idx < 12; ++work_idx) { 148 | add_entry(&queue, (work_idx + 1)@ptr, test_sleep_rnd@work_queue_callback); 149 | } 150 | 151 | wait_for_completion(&queue); 152 | print("exit this thingy.\n"); 153 | Windows::ExitProcess(0); 154 | } 155 | #endif 156 | 157 | 158 | -------------------------------------------------------------------------------- /publish/current/include/system/bmp.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | 3 | ["PACKED"] 4 | let rgba_color = struct ( 5 | r: i8; 6 | g: i8; 7 | b: i8; 8 | a: i8; 9 | ); 10 | let bitmap = struct ( 11 | width: i32; 12 | height: i32; 13 | pixels: i8*; 14 | ); 15 | 16 | ["PACKED"] 17 | let bmp_file_header = struct( 18 | magic: i16; 19 | size: i32; 20 | reserverd: i32; 21 | offset: i32; 22 | ); 23 | 24 | let load_bitmap = fun(file: string) => bitmap { 25 | var result = bitmap { }; 26 | var bmp = read_file(file); 27 | var file_header = bmp.data@bmp_file_header*; 28 | assert(file_header.magic == 0x4D42); 29 | assert(file_header.size <= bmp.length); 30 | 31 | var bmp_info = (bmp.data + size_of(bmp_file_header))@Windows::BITMAPV4HEADER*; 32 | assert(bmp_info.biPlanes == 1); 33 | assert(bmp_info.biCompression == 0 || bmp_info.biCompression == 3); 34 | assert(bmp_info.biBitCount == 24 || bmp_info.biBitCount == 32); 35 | result.width = bmp_info.biWidth; 36 | result.height = bmp_info.biHeight; 37 | result.pixels = bmp.data + file_header.offset; 38 | assert(result.width > 0 && result.width < 4096); 39 | assert(result.height > 0 && result.height < 4096); 40 | 41 | return result; 42 | } 43 | 44 | let channel = fun(pixel: i32*; idx: i32) => i32 { 45 | var byte_ptr = pixel@i8*; 46 | assert(idx >= 0 && idx < 4); 47 | var result = (*(byte_ptr + idx))@\i32; 48 | return result; 49 | } 50 | 51 | let save_bitmap = fun(file: string; bmp: bitmap) => void { 52 | var header = bmp_file_header { }; 53 | header.magic = 0x4D42; 54 | 55 | header.offset = size_of(bmp_file_header)@\i32 + size_of(Windows::BITMAPV4HEADER)@i32; 56 | header.size = header.offset + bmp.width * bmp.height * 4; 57 | header.reserverd = 0; 58 | var dib = Windows::BITMAPV4HEADER{ }; 59 | dib.biSize = size_of(Windows::BITMAPV4HEADER)@i32; 60 | dib.biWidth = bmp.width; 61 | dib.biHeight = -bmp.height; 62 | dib.biPlanes = 1; 63 | dib.biCompression = 3; 64 | dib.biBitCount = 32; 65 | dib.biSizeImage = bmp.width * bmp.height * 4; 66 | dib.biRedMask = 0x00FF0000; 67 | dib.biGreenMask = 0x0000FF00; 68 | dib.biBlueMask = 0x000000FF; 69 | dib.biAlphaMask = 0xFF000000; 70 | dib.biCSType = 1934772034; 71 | 72 | var buffer = allocate(header.size@mm); 73 | var buf_ptr = buffer; 74 | 75 | *(buf_ptr@bmp_file_header*) = header; 76 | buf_ptr += size_of(bmp_file_header); 77 | *(buf_ptr@Windows::BITMAPV4HEADER*) = dib; 78 | buf_ptr += size_of(Windows::BITMAPV4HEADER); 79 | 80 | var src = bmp.pixels@i32*; 81 | var dst = buf_ptr@i32*; 82 | 83 | var width = bmp.width; 84 | var height = bmp.height; 85 | for (var j = 0; j < height; ++j) { 86 | for (var i = 0; i < width; ++i) { 87 | var r = channel(src, 0); 88 | var g = channel(src, 1); 89 | var b = channel(src, 2); 90 | var a = channel(src, 3); 91 | var dest_pixel = b + (g << 8) + (r << 16) + (a << 24); 92 | *dst++ = dest_pixel; 93 | src++; 94 | } 95 | } 96 | 97 | // memcpy(buf_ptr, bmp.pixels, (bmp.width * bmp.height * 4)@mm); 98 | write_file(file, buffer[:header.size]); 99 | free(buffer); 100 | } 101 | -------------------------------------------------------------------------------- /publish/current/include/system/linux.prag: -------------------------------------------------------------------------------- 1 | mod Linux 2 | { 3 | ["stub"] 4 | let __write = extern fun(fd: i32; buf: ptr; size: mm) => i64; 5 | 6 | ["stub"] 7 | let __read = extern fun(fd: i32; buf: ptr; size: mm) => i64; 8 | 9 | ["stub"] 10 | let __open = extern fun(filename: i8*; flags: i32; mode: i32) => i32; 11 | 12 | ["stub"] 13 | let __close = extern fun(fd: i32) => i32; 14 | 15 | ["stub"] 16 | let __openat = extern fun(dirfd: i32; filename: i8*; flags: i32; mode: i32) => i32; 17 | 18 | ["stub"] 19 | let __mmap = extern fun(addr: ptr; length: mm; prot: i32; flags: i32; fd: i32; offset: mm) => ptr; 20 | 21 | ["stub"] 22 | let __munmap = extern fun(addr: ptr; length: mm) => i32; 23 | 24 | 25 | // *** Dumping AST Record Layout 26 | // 0 | struct stat 27 | // 0 | __dev_t st_dev 28 | // 8 | __ino_t st_ino 29 | // 16 | __nlink_t st_nlink 30 | // 24 | __mode_t st_mode 31 | // 28 | __uid_t st_uid 32 | // 32 | __gid_t st_gid 33 | // 36 | int __pad0 34 | // 40 | __dev_t st_rdev 35 | // 48 | __off_t st_size 36 | // 56 | __blksize_t st_blksize 37 | // 64 | __blkcnt_t st_blocks 38 | // 72 | struct timespec st_atim 39 | // 72 | __time_t tv_sec 40 | // 80 | __syscall_slong_t tv_nsec 41 | // 88 | struct timespec st_mtim 42 | // 88 | __time_t tv_sec 43 | // 96 | __syscall_slong_t tv_nsec 44 | // 104 | struct timespec st_ctim 45 | // 104 | __time_t tv_sec 46 | // 112 | __syscall_slong_t tv_nsec 47 | // 120 | __syscall_slong_t [3] __glibc_reserved 48 | // | [sizeof=144, dsize=144, align=8, 49 | // | nvsize=144, nvalign=8] 50 | 51 | 52 | let timespec = struct( 53 | tv_sec: i64; 54 | tv_nsec: i64; 55 | ); 56 | 57 | ["packed"] 58 | let stat = struct( 59 | st_dev: i64; 60 | st_ino: i64; 61 | st_nlink: i64; 62 | st_mode: i32; 63 | st_uid: i32; 64 | st_gid: i32; 65 | __pad0: i32; 66 | st_rdev: i64; 67 | st_size: i64; 68 | st_blksize: i64; 69 | st_blocks: i64; 70 | st_atim: timespec; 71 | st_mtim: timespec; 72 | st_ctim: timespec; 73 | reserved: i64[3]; 74 | ); 75 | 76 | ["stub"] 77 | let __fstatat = extern fun(dfd: i32; filename: i8*; statbuf: i8*; flag: i32) => i32; 78 | 79 | let MAP_SHARED = 0x01; 80 | let MAP_PRIVATE = 0x02; 81 | let MAP_TYPE = 0x0F; 82 | let MAP_FIXED = 0x10; 83 | let MAP_ANON = 0x20; 84 | let MAP_ANONYMOUS = MAP_ANON; 85 | let MAP_NORESERVE = 0x4000; 86 | let MAP_GROWSDOWN = 0x0100; 87 | let MAP_DENYWRITE = 0x0800; 88 | let MAP_EXECUTABLE = 0x1000; 89 | let MAP_LOCKED = 0x2000; 90 | let MAP_POPULATE = 0x8000; 91 | let MAP_NONBLOCK = 0x10000; 92 | let MAP_STACK = 0x20000; 93 | let MAP_HUGETLB = 0x40000; 94 | let MAP_FILE = 0; 95 | 96 | let PROT_NONE = 0; 97 | let PROT_READ = 1; 98 | let PROT_WRITE = 2; 99 | let PROT_EXEC = 4; 100 | let PROT_GROWSDOWN = 0x01000000; 101 | let PROT_GROWSUP = 0x02000000; 102 | 103 | let MS_ASYNC = 1; 104 | let MS_INVALIDATE = 2; 105 | let MS_SYNC = 4; 106 | 107 | let MCL_CURRENT = 1; 108 | let MCL_FUTURE = 2; 109 | let MCL_ONFAULT = 4; 110 | 111 | let POSIX_MADV_NORMAL = 0; 112 | let POSIX_MADV_RANDOM = 1; 113 | let POSIX_MADV_SEQUENTIAL = 2; 114 | let POSIX_MADV_WILLNEED = 3; 115 | let POSIX_MADV_DONTNEED = 4; 116 | 117 | let O_ACCMODE = 0x0003; 118 | let O_RDONLY = 0x0000; 119 | let O_WRONLY = 0x0001; 120 | let O_RDWR = 0x0002; 121 | let O_CREAT = 0x0040; 122 | let O_EXCL = 0x0080; 123 | let O_NOCTTY = 0x0100; 124 | let O_TRUNC = 0x0200; 125 | let O_APPEND = 0x0400; 126 | let O_NONBLOCK = 0x0800; 127 | let O_NDELAY = O_NONBLOCK; 128 | let O_SYNC = 0x101000; 129 | let O_FSYNC = O_SYNC; 130 | let O_ASYNC = 0x2000; 131 | let O_LARGEFILE = 0x8000; 132 | 133 | let AT_FDCWD = -100; 134 | 135 | 136 | } -------------------------------------------------------------------------------- /publish/current/include/system/math.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | // http://openlibm.org/ 3 | mod Math 4 | { 5 | let pi: f64 = 3.1415926535897932384626433832795028841971693993751058209749445923078164062; 6 | let half_pi = pi / 2.0; 7 | let pi_32 = pi@f32; 8 | let half_pi_32 = half_pi@f32; 9 | let tau = 2.0 * pi; 10 | let tau_32 = 2.0 * pi_32; 11 | 12 | ["READNONE"] 13 | let sin = extern("llvm.sin.f32") fun (x: f32) => f32; 14 | ["READNONE"] 15 | let cos = extern("llvm.cos.f32") fun (x: f32) => f32; 16 | ["READNONE"] 17 | let tan = extern("tanf") fun (x: f32) => f32; 18 | ["READNONE"] 19 | let asin = extern("asinf") fun (x: f32) => f32; 20 | ["READNONE"] 21 | let acos = extern("acosf") fun (x: f32) => f32; 22 | ["READNONE"] 23 | let atan = extern("atanf") fun (x: f32) => f32; 24 | ["READNONE"] 25 | let atan2 = extern("atan2f") fun (x: f32) => f32; 26 | ["READNONE"] 27 | let sqrt = extern("llvm.sqrt.f32") fun (x: f32) => f32; 28 | ["READNONE"] 29 | let pow = extern("llvm.pow.f32") fun (x: f32; p: f32) => f32; 30 | ["READNONE"] 31 | let abs = extern("llvm.fabs.f32") fun (x: f32) => f32; 32 | ["READNONE"] 33 | let floor = extern("llvm.floor.f32") fun (x: f32) => f32; 34 | ["READNONE"] 35 | let trunc = extern("llvm.trunc.f32") fun (x: f32) => f32; 36 | ["READNONE"] 37 | let ceil = extern("llvm.ceil.f32") fun (x: f32) => f32; 38 | ["READNONE"] 39 | let round = extern("llvm.round.f32") fun (x: f32) => f32; 40 | ["READNONE"] 41 | let exp = extern("llvm.exp.f32") fun (x: f32) => f32; 42 | ["READNONE"] 43 | let exp2 = extern("llvm.exp2.f32") fun (x: f32) => f32; 44 | ["READNONE"] 45 | let log = extern("llvm.log.f32") fun (x: f32) => f32; 46 | ["READNONE"] 47 | let log2 = extern("llvm.log2.f32") fun (x: f32) => f32; 48 | ["READNONE"] 49 | let log10 = extern("llvm.log10.f32") fun (x: f32) => f32; 50 | 51 | ["READNONE"] 52 | let exp = extern("llvm.exp.f32") fun (x: f32_4x) => f32_4x; 53 | ["READNONE"] 54 | let log = extern("llvm.log.f32") fun (x: f32_4x) => f32_4x; 55 | 56 | 57 | // ["READNONE"] 58 | // let min = extern("llvm.minnum.f32") fun (a: f32; b: f32) => f32; 59 | // ["READNONE"] 60 | // let max = extern("llvm.maxnum.f32") fun (a: f32; b: f32) => f32; 61 | 62 | ["READNONE"] 63 | let min = fun(a: f32; b: f32) => f32 { 64 | if (a < b) { 65 | return a; 66 | } else { 67 | return b; 68 | } 69 | } 70 | 71 | ["READNONE"] 72 | let max = fun(a: f32; b: f32) => f32 { 73 | if (a > b) { 74 | return a; 75 | } else { 76 | return b; 77 | } 78 | } 79 | 80 | ["READNONE"] 81 | let max = fun(a: i32; b: i32) => i32 { 82 | if (a > b) { 83 | return a; 84 | } else { 85 | return b; 86 | } 87 | } 88 | 89 | ["READNONE"] 90 | let min = fun(a: i32; b: i32) => i32 { 91 | if (a < b) { 92 | return a; 93 | } else { 94 | return b; 95 | } 96 | } 97 | 98 | let swap = fun (a: f32*; b: f32*) => void { 99 | var temp = *a; 100 | *a = *b; 101 | *b = temp; 102 | } 103 | 104 | ["READNONE"] 105 | let round_to_i32 = fun (x: f32) => i32 { 106 | return round(x)@i32; 107 | } 108 | ["READNONE"] 109 | let remainder = fun(x: f32; y: f32) => f32 110 | { 111 | return x - floor(x / y) * y; 112 | } 113 | ["READNONE"] 114 | let lerp = fun(a: f32; b: f32; t: f32) => f32 115 | { 116 | return a + (b-a)*t; 117 | } 118 | let inverse_lerp = fun(a: f32; b: f32; x: f32) => f32 119 | { 120 | return (x - a) / (b - a); 121 | } 122 | ["READNONE"] 123 | let abs = fun (value: i32) => i32 124 | { 125 | if (value >= 0) { 126 | return value; 127 | } else { 128 | return -value; 129 | } 130 | } 131 | 132 | ["READNONE"] 133 | let sign = fun (value: f32) => f32 { 134 | if (value > 0) { 135 | return 1.0; 136 | } elif (value < 0) { 137 | return -1.0; 138 | } else { 139 | return 0.0; 140 | } 141 | } 142 | 143 | ["READNONE"] 144 | let clamp = fun 145 | ( 146 | value: i32; 147 | min: i32; 148 | max: i32 149 | ) => i32 150 | { 151 | assert(min <= max); 152 | var result = value; 153 | if (result < min) { 154 | result = min; 155 | } elif (result > max) { 156 | result = max; 157 | } 158 | return result; 159 | } 160 | 161 | ["READNONE"] 162 | let clamp = fun (value: f32; min: f32=0.0; max: f32=1.0) => f32 163 | { 164 | assert(min <= max); 165 | var result = value; 166 | if (result < min) { 167 | result = min; 168 | } elif (result > max) { 169 | result = max; 170 | } 171 | return result; 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /publish/current/include/system/memory.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | 3 | let memory_arena = struct( 4 | size: mm; 5 | base: ptr; 6 | used: mm; 7 | ); 8 | 9 | let align_4 = fun(value: mm) => mm{ 10 | return (value + 3) & (~3); 11 | } 12 | let align_8 = fun(value: mm) => mm { 13 | return (value + 7) & (~7); 14 | } 15 | let align_16 = fun(value: mm) => mm { 16 | return (value + 15) & (~15); 17 | } 18 | let align_32 = fun(value: mm) => mm { 19 | return (value + 31) & (~31); 20 | } 21 | let align_64 = fun(value: mm) => mm { 22 | return (value + 63) & (~63); 23 | } 24 | let align_n = fun(value: mm; n: i32) => mm { 25 | return (value + (n - 1)@mm) & (~(n - 1))@mm; 26 | } 27 | 28 | let push = fun(@arena: memory_arena*; push_size: mm; align: i32 = 4) => ptr { 29 | var result = base + align_n(arena.used, align); 30 | used = result@mm - base@mm + push_size@mm; 31 | if (used > size) { 32 | assert(false); 33 | return nullptr; 34 | } 35 | return result; 36 | } 37 | 38 | let start_temp = fun(@arena: memory_arena*;) => mm { 39 | return used; 40 | } 41 | 42 | let stop_temp = fun(@arena: memory_arena*; temp_used: mm) => void { 43 | used = temp_used; 44 | } 45 | mod _INTERNAL { 46 | // TODO(pragma): this stuff should be thread local? 47 | var temp_memory_stack_pos: i32; 48 | var temp_memory_stack: mm[32]; 49 | } 50 | 51 | // TODO(pragma): make this threadsafe 52 | let push_temp = fun(@arena: memory_arena* = &temp_memory_arena) => void { 53 | _INTERNAL::temp_memory_stack[_INTERNAL::temp_memory_stack_pos++] = start_temp(arena); 54 | if (_INTERNAL::temp_memory_stack_pos@mm >= len(_INTERNAL::temp_memory_stack)) { 55 | assert(false, "Exceeded max temp memory stack size!"); 56 | } 57 | } 58 | 59 | // TODO(pragma): make this threadsafe 60 | let pop_temp = fun(@arena: memory_arena* = &temp_memory_arena) => void { 61 | _INTERNAL::temp_memory_stack_pos--; 62 | if (_INTERNAL::temp_memory_stack_pos < 0) { 63 | assert(false, "Inbalanced push_temp pop_temp operations. Stack pos below 0!"); 64 | } 65 | stop_temp(arena, _INTERNAL::temp_memory_stack[_INTERNAL::temp_memory_stack_pos]); 66 | } 67 | 68 | let create_arena = fun(size: mm) => memory_arena { 69 | var data = allocate(size); 70 | var result: memory_arena; 71 | if (data != nullptr) { 72 | result.size = size; 73 | result.base = data; 74 | result.used = 0; 75 | } else { 76 | result.size = 0; 77 | result.base = nullptr; 78 | result.used = 0; 79 | } 80 | return result; 81 | } 82 | 83 | let get_slice = fun(@arena: memory_arena*) => i8[] { 84 | var result = base[:used@i32]; 85 | return result; 86 | } 87 | -------------------------------------------------------------------------------- /publish/current/include/system/random.prag: -------------------------------------------------------------------------------- 1 | 2 | mod Random 3 | { 4 | let seed0 = 12345; 5 | let seed1 = 33333; 6 | let seed2 = 982845; 7 | let seed3 = 11293929; 8 | 9 | let state = struct 10 | ( 11 | z1: i32_4x; 12 | z2: i32_4x; 13 | z3: i32_4x; 14 | z4: i32_4x; 15 | ); 16 | 17 | // var state: state = state{seed0, seed0, seed0, seed0}; 18 | var state: state = state { 19 | i32_4x {seed0, seed1, seed2, seed3}, 20 | i32_4x {seed0, seed1, seed2, seed3}, 21 | i32_4x {seed0, seed1, seed2, seed3}, 22 | i32_4x {seed0, seed1, seed2, seed3} 23 | }; 24 | 25 | 26 | let init_seed = fun (seed: i32_4x; state: state*) => void { 27 | state.z1 = seed; 28 | state.z2 = seed; 29 | state.z3 = seed; 30 | state.z4 = seed; 31 | } 32 | 33 | let rand_i32_4x = fun (@state: state*) => i32_4x { 34 | let vi_2 = i32_4x { 2, 2, 2, 2 }; 35 | let vi_3 = i32_4x { 3, 3, 3, 3 }; 36 | let vi_6 = i32_4x { 6, 6, 6, 6 }; 37 | let vi_7 = i32_4x { 7, 7, 7, 7 }; 38 | let vi_12 = i32_4x { 12, 12, 12, 12 }; 39 | let vi_13 = i32_4x { 13, 13, 13, 13}; 40 | let vi_18 = i32_4x { 18, 18, 18, 18}; 41 | let vi_21 = i32_4x { 21, 21, 21, 21}; 42 | let vi_27 = i32_4x { 27, 27, 27, 27}; 43 | let vi_m0 = i32_4x { 4294967294, 4294967294, 4294967294, 4294967294 }; 44 | let vi_m1 = i32_4x { 4294967288, 4294967288, 4294967288, 4294967288 }; 45 | let vi_m2 = i32_4x { 4294967280, 4294967280, 4294967280, 4294967280 }; 46 | let vi_m3 = i32_4x { 4294967168, 4294967168, 4294967168, 4294967168 }; 47 | 48 | var b: i32_4x; 49 | b = ((z1 << vi_6) ^ z1) >>\ vi_13; 50 | z1 = ((z1 & vi_m0) << vi_18) ^ b; 51 | b = ((z2 << vi_2) ^ z2) >>\ vi_27; 52 | z2 = ((z2 & vi_m1) << vi_2) ^ b; 53 | b = ((z3 << vi_13) ^ z3) >>\ vi_21; 54 | z3 = ((z3 & vi_m2) << vi_7) ^ b; 55 | b = ((z4 << vi_3) ^ z4) >>\ vi_12; 56 | z4 = ((z4 & vi_m3) << vi_13) ^ b; 57 | return (z1 ^ z2 ^ z3 ^ z4); 58 | } 59 | 60 | let rand_f32_4x = fun(min: f32_4x = f32_4x { 0.0, 0.0, 0.0, 0.0 }; max: f32_4x = f32_4x { 1.0, 1.0, 1.0, 1.0 }; state: state* = &state) => f32_4x { 61 | let div = f32_4x { 4294967295.0, 4294967295.0, 4294967295.0, 4294967295.0 }; 62 | var x = rand_i32_4x(state); 63 | var result = @\f32_4x x / div; 64 | result = min + result * (max - min); 65 | return result; 66 | } 67 | 68 | 69 | let rand_i32 = fun(state: state* = &state) => i32 { 70 | var result = rand_i32_4x(state); 71 | return result[0]; 72 | } 73 | 74 | let rand_f32 = fun (min: f32 = 0.0; max: f32 = 1.0; state: state* = &state;) => f32 { 75 | var x = rand_i32(state); 76 | var result = @\f32 x / 4294967295.0; 77 | result = min + result * (max - min); 78 | return result; 79 | } 80 | let rand_xkcd = fun () => i32 { 81 | return 4; // chosen by fair dice roll. 82 | // guaranteed to be random. 83 | } 84 | } -------------------------------------------------------------------------------- /publish/current/include/system/simd.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | import "math.prag" 3 | mod SIMD 4 | { 5 | let ZERO_f32_8x = f32_8x {}; 6 | let ONE_f32_8x = f32_8x { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; 7 | 8 | let _CMP_EQ_OQ: i8 = 0x00; 9 | let _CMP_LT_OS: i8 = 0x01; 10 | let _CMP_LE_OS: i8 = 0x02; 11 | let _CMP_UNORD_Q: i8 = 0x03; 12 | let _CMP_NEQ_UQ: i8 = 0x04; 13 | let _CMP_NLT_US: i8 = 0x05; 14 | let _CMP_NLE_US: i8 = 0x06; 15 | let _CMP_ORD_Q: i8 = 0x07; 16 | let _CMP_EQ_UQ: i8 = 0x08; 17 | let _CMP_NGE_US: i8 = 0x09; 18 | let _CMP_NGT_US: i8 = 0x0A; 19 | let _CMP_FALSE_OQ: i8 = 0x0B; 20 | let _CMP_NEQ_OQ: i8 = 0x0C; 21 | let _CMP_GE_OS: i8 = 0x0D; 22 | let _CMP_GT_OS: i8 = 0x0E; 23 | let _CMP_TRUE_UQ: i8 = 0x0F; 24 | let _CMP_EQ_OS: i8 = 0x10; 25 | let _CMP_LT_OQ: i8 = 0x11; 26 | let _CMP_LE_OQ: i8 = 0x12; 27 | let _CMP_UNORD_S: i8 = 0x13; 28 | let _CMP_NEQ_US: i8 = 0x14; 29 | let _CMP_NLT_UQ: i8 = 0x15; 30 | let _CMP_NLE_UQ: i8 = 0x16; 31 | let _CMP_ORD_S: i8 = 0x17; 32 | let _CMP_EQ_US: i8 = 0x18; 33 | let _CMP_NGE_UQ: i8 = 0x19; 34 | let _CMP_NGT_UQ: i8 = 0x1A; 35 | let _CMP_FALSE_OS: i8 = 0x1B; 36 | let _CMP_NEQ_OS: i8 = 0x1C; 37 | let _CMP_GE_OQ: i8 = 0x1D; 38 | let _CMP_GT_OQ: i8 = 0x1E; 39 | let _CMP_TRUE_US: i8 = 0x1F; 40 | 41 | let _MM_FROUND_TO_NEAREST_INT = 0x00; 42 | let _MM_FROUND_TO_NEG_INF = 0x01; 43 | let _MM_FROUND_TO_POS_INF = 0x02; 44 | let _MM_FROUND_TO_ZERO = 0x03; 45 | let _MM_FROUND_CUR_DIRECTION = 0x04; 46 | let _MM_FROUND_NO_EXC = 0x08; 47 | let _MM_FROUND_RAISE_EXC = 0x00; 48 | 49 | 50 | let max_ps = extern("llvm.x86.sse.max.ps") fun (a: f32_4x; b: f32_4x) => f32_4x; 51 | let max_ps = extern("llvm.x86.avx.max.ps.256") fun (a: f32_8x; b: f32_8x) => f32_8x; 52 | 53 | let min_ps = extern("llvm.x86.sse.min.ps") fun (a: f32_4x; b: f32_4x) => f32_4x; 54 | let min_ps = extern("llvm.x86.avx.min.ps.256") fun (a: f32_8x; b: f32_8x) => f32_8x; 55 | 56 | // let xor_ps = extern("llvm.x86.sse.xor.ps") fun (a: f32_4x; b: f32_4x) => f32_4x; 57 | // let xor_ps = extern("llvm.x86.avx.xor.ps.256") fun (a: f32_8x; b: f32_8x) => f32_8x; 58 | 59 | 60 | // let and_ps = extern("llvm.x86.sse.and.ps") fun (a: f32_4x; b: f32_4x) => f32_4x; 61 | // let and_ps = extern("llvm.x86.avx.and.ps.256") fun (a: f32_8x; b: f32_8x) => f32_8x; 62 | 63 | let blendv_ps = extern("llvm.x86.avx.blendv.ps.256") fun (a: f32_8x; b: f32_8x; mask: f32_8x) => f32_8x; 64 | 65 | let cmp_ps = extern("llvm.x86.avx.cmp.ps.256") fun (a: f32_8x; b: f32_8x; flag: i8) => f32_8x; 66 | 67 | let set1_ps = fun(v: f32) => f32_4x { 68 | return f32_4x { v, v, v, v }; 69 | } 70 | let set1_ps_256 = fun(v: f32) => f32_8x { 71 | return f32_8x { v, v, v, v, v, v, v, v }; 72 | } 73 | 74 | let set1_epi32 = fun(v: i32) => i32_4x { 75 | return i32_4x {v, v, v, v}; 76 | } 77 | let cvtepi32_ps = fun(v: i32_4x) => f32_4x { 78 | return v@f32_4x; 79 | } 80 | 81 | let rcp_ps = extern("llvm.x86.sse.rcp.ps") fun(v: f32_4x) => f32_4x; 82 | let rcp_ps = extern("llvm.x86.avx.rcp.ps.256") fun(v: f32_8x) => f32_8x; 83 | let round_ps = extern("llvm.x86.avx.round.ps") fun(v: f32_4x; rounding: i32) => f32_4x; 84 | let round_ps = extern("llvm.x86.avx.round.ps.256") fun(v: f32_8x; rounding: i32) => f32_8x; 85 | 86 | 87 | 88 | let mod_ps = fun(a: f32_8x; b: f32_8x) => f32_8x { 89 | return a - round_ps(a / b, _MM_FROUND_TO_ZERO|_MM_FROUND_NO_EXC) * b; 90 | // return a - (((a / b)@i32_8x)@f32_8x) * b; 91 | } 92 | let xor_ps = fun (a: f32_8x; b: f32_8x) => f32_8x { 93 | // TODO(magnus): we need to specify SIMD:: here because of stupid special function machanism, 94 | return SIMD::cast_si_ps((SIMD::cast_ps_si(a) ^ SIMD::cast_ps_si(b))); 95 | } 96 | let neg_ps = fun(a: f32_8x) => f32_8x { 97 | // TODO(magnus): -0.0f does not actually return the right hex float. 98 | return xor_ps(a, set1_ps_256(NEG_ZERO_F32)); 99 | } 100 | 101 | let cos_8x = fun(x: f32_8x) => f32_8x { 102 | let one_8x = SIMD::set1_ps_256(1.0); 103 | var x_mod_2pi = mod_ps(x, set1_ps_256(Math::tau_32)); 104 | var mask_a = cmp_ps(x_mod_2pi, set1_ps_256(Math::pi_32), _CMP_GT_OS); 105 | var mask_b = cmp_ps(x_mod_2pi, set1_ps_256(-Math::pi_32), _CMP_LT_OS); 106 | var mask = SIMD::cast_si_ps(SIMD::cast_ps_si(mask_a) | SIMD::cast_ps_si(mask_b)); 107 | var x_r = mod_ps(x, set1_ps_256(Math::pi_32)); 108 | var x2 = x_r * x_r; 109 | var x4 = x2 * x2; 110 | var x6 = x4 * x2; 111 | var x8 = x6 * x2; 112 | var pos_result = one_8x 113 | - (x2 / set1_ps_256(2.0)) 114 | + (x4 / set1_ps_256(24.0)) 115 | - (x6 / set1_ps_256(720.0)) 116 | + (x8 / set1_ps_256(40320.0)); 117 | var neg_result = neg_ps(pos_result); 118 | var result = blendv_ps(pos_result, neg_result, mask); 119 | return result; 120 | } 121 | 122 | let sin_8x = fun(x: f32_8x) => f32_8x { 123 | return cos_8x(x - set1_ps_256(Math::half_pi_32)); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /publish/current/include/system/work_queue.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | import "windows.prag" 3 | import "random.prag" 4 | import "math.prag" 5 | 6 | let work_queue_callback = fun(queue: work_queue*; data: ptr) => void; 7 | 8 | let work_queue_entry = struct( 9 | callback: work_queue_callback; 10 | data: ptr; 11 | ); 12 | 13 | let work_queue = struct( 14 | ["VOLATILE"] 15 | completion_goal: i32; 16 | ["VOLATILE"] 17 | completion_count: i32; 18 | ["VOLATILE"] 19 | next_entry_to_write: i32; 20 | ["VOLATILE"] 21 | next_entry_to_read: i32; 22 | semaphore_handle: mm; 23 | entries: work_queue_entry[1024]; 24 | ); 25 | 26 | 27 | let add_entry = fun(@queue: work_queue*; data: ptr; callback: work_queue_callback) => void { 28 | var entry = create_work_entry(data, callback); 29 | add_entry(queue, entry); 30 | } 31 | 32 | let add_entry = fun (@queue: work_queue*; entry: work_queue_entry) => void { 33 | var temp_queue = queue; 34 | var target_next_entry_to_write = next_entry_to_write + 1; 35 | if (target_next_entry_to_write >= len(entries)@i32) { 36 | assert(target_next_entry_to_write == len(entries)@i32); 37 | target_next_entry_to_write = 0; 38 | } 39 | assert(target_next_entry_to_write != next_entry_to_read); 40 | entries[next_entry_to_write] = entry; 41 | queue.completion_goal += 1; 42 | 43 | _WriteBarrier(); 44 | 45 | queue.next_entry_to_write = target_next_entry_to_write; 46 | Windows::ReleaseSemaphore(semaphore_handle, 1, 0@i32*); 47 | } 48 | 49 | let next_entry = fun(@queue: work_queue*) => bool 50 | { 51 | var temp_queue = queue; 52 | var should_sleep = false; 53 | var original_next_entry_to_read = queue.next_entry_to_read; 54 | var target_next_entry_to_read = original_next_entry_to_read + 1; 55 | if (target_next_entry_to_read >= len(entries)@i32) { 56 | assert(target_next_entry_to_read == len(entries)@i32); 57 | target_next_entry_to_read = 0; 58 | } 59 | if (original_next_entry_to_read != next_entry_to_write) { 60 | var idx = atomic_compare_and_swap( 61 | &next_entry_to_read, 62 | target_next_entry_to_read, 63 | original_next_entry_to_read 64 | ); 65 | if (idx == original_next_entry_to_read) { 66 | var entry = entries[idx]; 67 | entry.callback(queue, entry.data); 68 | atomic_inc(&queue.completion_count); 69 | } 70 | } else { 71 | should_sleep = true; 72 | } 73 | return should_sleep; 74 | } 75 | 76 | let wait_for_completion = fun(queue: work_queue*) => void { 77 | var temp_queue = queue; 78 | while (queue.completion_goal != queue.completion_count) { 79 | Windows::Sleep(10); 80 | // if (!next_entry(queue)) { 81 | // debug_print("percent", Math::round_to_i32(100.0 * queue.completion_count@f32 / queue.completion_goal@f32)); 82 | // } 83 | } 84 | debug_print("percent", Math::round_to_i32(100.0 * queue.completion_count@f32 / queue.completion_goal@f32)); 85 | } 86 | 87 | let work_queue_thread_proc = fun(data: ptr) => void { 88 | var queue = data@work_queue*; 89 | while (true) { 90 | if (next_entry(queue)) { 91 | Windows::WaitForSingleObject(queue.semaphore_handle, Windows::INFINITE); 92 | } 93 | } 94 | } 95 | 96 | let init_work_queue = fun(queue: work_queue*; worker_count: i32) => void { 97 | var temp_queue = queue; 98 | queue.completion_goal = 0; 99 | queue.completion_count = 0; 100 | queue.next_entry_to_write = 0; 101 | queue.next_entry_to_read = 0; 102 | var initial_count = 0; 103 | queue.semaphore_handle = Windows::CreateSemaphoreA(nullptr, initial_count, worker_count + 1, nullptr); 104 | for (var worker_idx = 0; worker_idx < worker_count; ++worker_idx) { 105 | var handle = Windows::CreateThread(nullptr, 0, work_queue_thread_proc@Windows::ThreadProc, queue@ptr, 0, 0@mm*); 106 | Windows::CloseHandle(handle); 107 | } 108 | } 109 | 110 | let create_work_entry = fun(data: ptr; callback: work_queue_callback) => work_queue_entry 111 | { 112 | var result = work_queue_entry {}; 113 | result.data = data; 114 | result.callback = callback; 115 | return result; 116 | } 117 | 118 | 119 | let test_sleep_rnd = fun(queue: work_queue*; data: ptr) => void { 120 | var temp_queue = queue; 121 | var state: Random::state; 122 | var seed = data@i32; 123 | debug_print("seed", seed); 124 | 125 | Random::init_seed(i32_4x{ seed, seed^3023141, seed^82318, seed^113 }, &state); 126 | var ms = Random::rand_i32(&state) % 5000; 127 | debug_print("sleeping for [ms]", ms); 128 | Windows::Sleep(ms); 129 | } 130 | 131 | 132 | #if false 133 | [ 134 | "compile.output": "test_work_queue.exe", 135 | "compile.debuginfo": "true", 136 | "compile.entry" : "true", 137 | "compile.ll" : "true", 138 | "compile.asm" : "false", 139 | "compile.opt" : "0", 140 | "compile.run" : "false", 141 | "compile.libs" : "kernel32.lib" 142 | ] 143 | let main = fun () => void { 144 | var queue = work_queue { }; 145 | init_work_queue(&queue, 8); 146 | 147 | for (var work_idx = 0; work_idx < 12; ++work_idx) { 148 | add_entry(&queue, (work_idx + 1)@ptr, test_sleep_rnd@work_queue_callback); 149 | } 150 | 151 | wait_for_completion(&queue); 152 | print("exit this thingy.\n"); 153 | Windows::ExitProcess(0); 154 | } 155 | #endif 156 | 157 | 158 | -------------------------------------------------------------------------------- /publish/current/lib/Gdi32.Lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/publish/current/lib/Gdi32.Lib -------------------------------------------------------------------------------- /publish/current/lib/Ole32.Lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/publish/current/lib/Ole32.Lib -------------------------------------------------------------------------------- /publish/current/lib/OpenGL32.Lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/publish/current/lib/OpenGL32.Lib -------------------------------------------------------------------------------- /publish/current/lib/User32.Lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/publish/current/lib/User32.Lib -------------------------------------------------------------------------------- /publish/current/lib/WinMM.Lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/publish/current/lib/WinMM.Lib -------------------------------------------------------------------------------- /publish/current/lib/kernel32.Lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/publish/current/lib/kernel32.Lib -------------------------------------------------------------------------------- /publish/current/lib/libopenlibm.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/publish/current/lib/libopenlibm.a -------------------------------------------------------------------------------- /publish/current/lib/shcore.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/publish/current/lib/shcore.lib -------------------------------------------------------------------------------- /publish/current/new_samples/hello_world/hello_world.prag: -------------------------------------------------------------------------------- 1 | import "../../system/preamble.prag" 2 | 3 | 4 | [ 5 | "compile.entry", 6 | "compile.run":"true", 7 | "compile.opt": "0", 8 | "compile.debuginfo": "true" 9 | ] 10 | let main = fun () => void { 11 | var x = ord("\\"); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /publish/current/new_samples/opengl/fs.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 7 | } -------------------------------------------------------------------------------- /publish/current/new_samples/opengl/vs.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | void main() 5 | { 6 | gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); 7 | } -------------------------------------------------------------------------------- /publish/current/samples/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "(Windows) Launch", 6 | "type": "cppvsdbg", 7 | //"type": "cppdbg", 8 | "request": "launch", 9 | // "preLaunchTask": "build", 10 | "program": "${workspaceRoot}/editor/bin/edit.exe", 11 | "args": [ 12 | "..\\." 13 | ], 14 | "stopAtEntry": false, 15 | "cwd": "${workspaceRoot}/editor/bin/", 16 | "environment": [], 17 | "externalConsole": true 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /publish/current/samples/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "editor.fontSize": 12, 4 | "workbench.editor.showIcons": true, 5 | // "files.associations": { 6 | // "*.prag": "csharp" 7 | // }, 8 | "problems.autoReveal": true, 9 | "debug.allowBreakpointsEverywhere": true, 10 | "lldb.displayFormat": "auto", 11 | "lldb.dereferencePointers": true, 12 | "lldb.showDisassembly": "always" 13 | } -------------------------------------------------------------------------------- /publish/current/samples/.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 | "label": "build", 8 | "type": "shell", 9 | "windows": { 10 | "command": "..\\bin\\pragma.exe" 11 | }, 12 | "linux": { 13 | "command": "../bin/pragma" 14 | }, 15 | "group": { 16 | "kind": "build", 17 | "isDefault": true 18 | }, 19 | "args": [ 20 | // "-v", 21 | "build", 22 | "-d", 23 | "\"${file}\"" 24 | ], 25 | "problemMatcher": [ 26 | { 27 | "fileLocation": "absolute", 28 | "pattern": { 29 | "regexp": "error: (.*?) at \\(.*?file \"(.*?)\".*?line (.*?),.*?pos (.*?),", 30 | "message": 1, 31 | "file": 2, 32 | "line": 3, 33 | "column": 4 34 | }, 35 | "applyTo": "allDocuments", 36 | "severity": "error" 37 | }, 38 | { 39 | "fileLocation": "absolute", 40 | "pattern": { 41 | "regexp": "(Assertion) failed at: \\(file \"(.*?)\".*?line (.*?),.*?pos (.*?)\\)", 42 | "message": 1, 43 | "file": 2, 44 | "line": 3, 45 | "column": 4 46 | }, 47 | "applyTo": "allDocuments" 48 | } 49 | ] 50 | }, 51 | { 52 | "label": "build release", 53 | "type": "shell", 54 | "command": "..\\bin\\pragma.exe", 55 | "group": "build", 56 | "args": [ 57 | "build", 58 | "${file}" 59 | ], 60 | "problemMatcher": [ 61 | { 62 | "fileLocation": "absolute", 63 | "pattern": { 64 | "regexp": "error: (.*?) at \\(.*?file \"(.*?)\".*?line (.*?),.*?pos (.*?),", 65 | "message": 1, 66 | "file": 2, 67 | "line": 3, 68 | "column": 4 69 | }, 70 | "applyTo": "allDocuments", 71 | "severity": "error" 72 | }, 73 | { 74 | "fileLocation": "absolute", 75 | "pattern": { 76 | "regexp": "(Assertion) failed at: \\(file \"(.*?)\".*?line (.*?),.*?pos (.*?)\\)", 77 | "message": 1, 78 | "file": 2, 79 | "line": 3, 80 | "column": 4 81 | }, 82 | "applyTo": "allDocuments" 83 | } 84 | ] 85 | } 86 | ], 87 | } -------------------------------------------------------------------------------- /publish/current/samples/basics/advent/advent_2017.prag: -------------------------------------------------------------------------------- 1 | import "../../preamble.prag" 2 | import "../../windows.prag" 3 | 4 | with Windows; 5 | 6 | [ 7 | "compile.output": "adv.exe", 8 | "compile.debuginfo": "true", 9 | "compile.entry" : "true", 10 | "compile.ll" : "true", 11 | "compile.asm" : "false", 12 | "compile.opt" : "0", 13 | "compile.run" : "true", 14 | "compile.libs" : "kernel32.lib" 15 | ] 16 | let main = fun () => void { 17 | day_01(); 18 | day_02(); 19 | } 20 | 21 | let read_file = fun (name: string) => i8[] 22 | { 23 | var result: i8[]; 24 | result.data = nullptr; 25 | result.length = 0; 26 | var handle = CreateFileA(cstr(name), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, 0); 27 | if (handle == null) { 28 | return result; 29 | } 30 | 31 | var size: i64 = 0; 32 | var fsr = GetFileSizeEx(handle, &size); 33 | if (fsr == 0 || size == 0) { 34 | CloseHandle(handle); 35 | return result; 36 | } 37 | 38 | var buffer = VirtualAlloc(nullptr, size@mm, MEM_COMMIT, PAGE_READWRITE); 39 | if (buffer@mm == null) { 40 | CloseHandle(handle); 41 | return result; 42 | } 43 | assert(size@mm <=\ gigabytes(4)); 44 | var size_32 = @i32 size; 45 | var bytes_read: i32; 46 | var rfr = ReadFile(handle, buffer, size_32, &bytes_read, nullptr); 47 | assert(bytes_read == size_32); 48 | if (rfr == 0) { 49 | VirtualFree(buffer, null, MEM_RELEASE); 50 | CloseHandle(handle); 51 | return result; 52 | } 53 | 54 | result.data = buffer; 55 | result.length = size_32; 56 | CloseHandle(handle); 57 | return result; 58 | } 59 | 60 | 61 | let day_01 = fun() => void { 62 | print("*****************************************\n"); 63 | print(" day 01\n"); 64 | var input = "3294199471327195994824832197564859876682638188889768298894243832665654681412886862234525991553276578641265589959178414218389329361496673991614673626344552179413995562266818138372393213966143124914469397692587251112663217862879233226763533911128893354536353213847122251463857894159819828724827969576432191847787772732881266875469721189331882228146576832921314638221317393256471998598117289632684663355273845983933845721713497811766995367795857965222183668765517454263354111134841334631345111596131682726196574763165187889337599583345634413436165539744188866156771585647718555182529936669683581662398618765391487164715724849894563314426959348119286955144439452731762666568741612153254469131724137699832984728937865956711925592628456617133695259554548719328229938621332325125972547181236812263887375866231118312954369432937359357266467383318326239572877314765121844831126178173988799765218913178825966268816476559792947359956859989228917136267178571776316345292573489873792149646548747995389669692188457724414468727192819919448275922166321158141365237545222633688372891451842434458527698774342111482498999383831492577615154591278719656798277377363284379468757998373193231795767644654155432692988651312845433511879457921638934877557575241394363721667237778962455961493559848522582413748218971212486373232795878362964873855994697149692824917183375545192119453587398199912564474614219929345185468661129966379693813498542474732198176496694746111576925715493967296487258237854152382365579876894391815759815373319159213475555251488754279888245492373595471189191353244684697662848376529881512529221627313527441221459672786923145165989611223372241149929436247374818467481641931872972582295425936998535194423916544367799522276914445231582272368388831834437562752119325286474352863554693373718848649568451797751926315617575295381964426843625282819524747119726872193569785611959896776143539915299968276374712996485367853494734376257511273443736433464496287219615697341973131715166768916149828396454638596713572963686159214116763"; 65 | 66 | { 67 | var input_test_0 = "1122"; 68 | var input_test_1 = "1111"; 69 | var input_test_2 = "1234"; 70 | var input_test_3 = "91212129"; 71 | var sum = 0; 72 | var test = input; 73 | for (var idx = 0; idx < test.length; ++idx) { 74 | var idx_next = idx + 1; 75 | if (idx_next >= test.length) { 76 | assert(idx_next == test.length); 77 | idx_next = 0; 78 | } 79 | if (test[idx] == test[idx_next]) { 80 | var value = test[idx]@i32 - ord("0"); 81 | sum += value; 82 | } 83 | } 84 | debug_print("sum_1", sum); 85 | } 86 | 87 | { 88 | var input_test_0 = "1212"; 89 | var input_test_1 = "1221"; 90 | var input_test_2 = "123425"; 91 | var input_test_3 = "123123"; 92 | var input_test_4 = "12131415"; 93 | var sum = 0; 94 | var test = input; 95 | for (var idx = 0; idx < test.length; ++idx) { 96 | var delta = test.length / 2; 97 | var idx_next = idx + delta; 98 | idx_next %= test.length; 99 | if (test[idx] == test[idx_next]) { 100 | var value = test[idx]@i32 - ord("0"); 101 | sum += value; 102 | } 103 | } 104 | debug_print("sum_2", sum); 105 | } 106 | print("*****************************************\n"); 107 | } 108 | 109 | let day_02 = fun() => void { 110 | print("*****************************************\n"); 111 | print("day 02\n"); 112 | 113 | var input = read_file("input_day_02.txt\0"); 114 | 115 | var line_idx = 0; 116 | var pos = 0; 117 | while (pos < input.length) { 118 | var char = input[pos]; 119 | if (char@i32 == ord("\n")) { 120 | line_idx++; 121 | debug_print("line", line_idx); 122 | } 123 | pos++; 124 | } 125 | print("*****************************************\n"); 126 | } -------------------------------------------------------------------------------- /publish/current/samples/basics/game_of_threes.prag: -------------------------------------------------------------------------------- 1 | import "../preamble.prag" 2 | [ 3 | "compile.output": "game_of_threes.exe", 4 | "compile.entry" : "true", 5 | "compile.opt" : "0", 6 | "compile.run" : "true", 7 | "compile.libs" : "kernel32.lib, libopenlibm.a" 8 | ] 9 | let main = fun () => void 10 | { 11 | var value = 100; 12 | 13 | while (value != 1) { 14 | print(value); 15 | var rem = value % 3; 16 | if (rem == 0) { 17 | print(" 0\n"); 18 | } elif (rem == 1) { 19 | value--; 20 | print(" -1\n"); 21 | } else { 22 | value++; 23 | print(" 1\n"); 24 | } 25 | value /= 3; 26 | } 27 | print("1\n"); 28 | Windows::ExitProcess(0); 29 | } 30 | -------------------------------------------------------------------------------- /publish/current/samples/basics/hello_world.prag: -------------------------------------------------------------------------------- 1 | import "../../test.prag" 2 | import "../preamble.prag" 3 | import "../windows.prag" 4 | 5 | 6 | let to_upper = fun(str: string) => void { 7 | for (var char_idx = 0; char_idx < str.length; ++char_idx) { 8 | if (str[char_idx] >= ord("a") && str[char_idx] <= ord("z")) { 9 | str[char_idx] += ord("A") - ord("a"); 10 | } 11 | } 12 | } 13 | 14 | [ 15 | "compile.entry", 16 | "compile.run":"true", 17 | "compile.opt": "0", 18 | "compile.debuginfo": "true" 19 | ] 20 | let main = fun () => void { 21 | print("hello, world!\n"); 22 | 23 | var sa = Windows::SECURITY_ATTRIBUTES {}; 24 | sa.nLength = size_of(Windows::SECURITY_ATTRIBUTES)@i32; 25 | sa.InheritHandle = 1; 26 | 27 | var stdin_pipe_read: mm = 0; 28 | var stdin_pipe_write: mm = 0; 29 | var stdout_pipe_read: mm = 0; 30 | var stdout_pipe_write: mm = 0; 31 | 32 | var success = 1; 33 | success = Windows::CreatePipe(&stdin_pipe_read, &stdin_pipe_write, &sa, 0); 34 | assert(success != 0); 35 | success = Windows::CreatePipe(&stdout_pipe_read, &stdout_pipe_write, &sa, 0); 36 | assert(success != 0); 37 | 38 | 39 | var si = Windows::STARTUPINFOA {}; 40 | si.cb = size_of(Windows::STARTUPINFOA)@i32; 41 | si.dwFlags = Windows::STARTF_USESTDHANDLES; 42 | si.hStdError = stdout_pipe_write; 43 | si.hStdOutput = stdout_pipe_write; 44 | si.hStdInput = stdin_pipe_read; 45 | 46 | var pi = Windows::PROCESS_INFORMATION {}; 47 | var cmd = "C:\\Windows\\System32\\cmd.exe /c dir\0"; 48 | Windows::CreateProcessA(nullptr, cstr(cmd), nullptr, nullptr, 1, 0, nullptr, nullptr, &si, &pi); 49 | 50 | Windows::CloseHandle(stdout_pipe_write); 51 | Windows::CloseHandle(stdin_pipe_read); 52 | 53 | var buf: i8[1025]; 54 | memset(&buf[0], 0, len(buf)); 55 | 56 | var bytes_read = 0; 57 | success = Windows::ReadFile(stdout_pipe_read, &buf[0], 1024, &bytes_read, nullptr); 58 | while (success != 0) { 59 | debug_print("output", buf[:bytes_read]); 60 | print("\n"); 61 | success = Windows::ReadFile(stdout_pipe_read, &buf[0], 1024, &bytes_read, nullptr); 62 | } 63 | Windows::CloseHandle(stdout_pipe_read); 64 | Windows::CloseHandle(stdin_pipe_write); 65 | 66 | Windows::CloseHandle(pi.hProcess); 67 | Windows::CloseHandle(pi.hThread); 68 | print("exit..."); 69 | } 70 | -------------------------------------------------------------------------------- /publish/current/samples/basics/nintendo/nintendo.prag: -------------------------------------------------------------------------------- 1 | import "../../preamble.prag" 2 | import "../../memory.prag" 3 | 4 | 5 | let make_array_i32 = fun(length: i32; arena: memory_arena* = &temp_memory_arena) => i32[] { 6 | var result: i32[]; 7 | result.length = length; 8 | result.data = push(arena, size_of(i32) * length@mm)@i32*; 9 | return result; 10 | } 11 | 12 | let make_string_array = fun(length: i32; arena: memory_arena* = &temp_memory_arena) => string[] { 13 | var result: string[]; 14 | result.length = length; 15 | result.data = push(arena, size_of(string) * length@mm)@string*; 16 | return result; 17 | } 18 | 19 | let print_hex = fun(value: i32) => void { 20 | print("0x"); 21 | print(to_hex_str(value)); 22 | } 23 | 24 | [ 25 | "compile.output": "nintendo.exe", 26 | "compile.debuginfo": "true", 27 | "compile.entry" : "true", 28 | "compile.ll" : "true", 29 | "compile.asm" : "false", 30 | "compile.opt" : "0", 31 | "compile.run" : "true", 32 | "compile.libs" : "kernel32.lib" 33 | ] 34 | let main = fun () => void { 35 | var test_0 = ["32", "b0c152f9", "ebf2831f"]; 36 | var test_1 = ["32", "ebf2831f", "b0c152f9"]; 37 | 38 | var test = test_1; 39 | var test_idx = 0; 40 | // let x = 3; 41 | // x = 4; 42 | 43 | var b_0 = make_string_array(32); 44 | 45 | let max_str_length = 1024; 46 | 47 | for (var idx = 0; idx < b_0.length; ++idx) { 48 | b_0[idx] = "0"; 49 | } 50 | 51 | var str = test[test_idx++]; 52 | var size: i32; 53 | if (from_str(str, &size)) { 54 | var a = make_array_i32(size / 16); 55 | var b = make_array_i32(size / 16); 56 | for (var idx = 0; idx < a.length; ++idx) { 57 | var value: i32; 58 | if (from_hex_str(test[test_idx++], &value)) { 59 | print("\n"); 60 | a[idx] = value; 61 | } else { 62 | assert(false); 63 | } 64 | b[idx] = 0; 65 | } 66 | // for (var i = 0; i < size; ++i) { 67 | // for (var j = 0; j < size; ++j) { 68 | // var idx = (i + j) / 32; 69 | // assert(idx < b.length); 70 | // // print(idx); 71 | // var value = 72 | // ( 73 | // (a[i / 32] >> (i % 32)) & 74 | // (a[j / 32 + size / 32] >> (j % 32)) 75 | // & 1 76 | // ) << ((i + j) % 32); 77 | // b[idx] ^= value; 78 | // //print(j / 32); 79 | // print(i / 32 + size / 32); 80 | // print(" "); 81 | // } 82 | // print("\n"); 83 | // } 84 | for (var i = 0; i < 32; ++i) { 85 | for (var j = 0; j < 32; ++j) { 86 | var idx = (i + j) / 32; 87 | 88 | if (idx == 0) { 89 | var pv = (i + j) % 32; 90 | if (pv <= 9) { 91 | print("0"); 92 | } 93 | print(pv); 94 | } else { 95 | print(" "); 96 | } 97 | var value = ((a[0] >> (i % 32)) & (a[1] >> (j % 32)) & 1) << ((i + j) % 32); 98 | b[idx] ^= value; 99 | print(" "); 100 | } 101 | print("\n"); 102 | } 103 | print("\n"); 104 | for (var i = 0; i < 32; ++i) { 105 | for (var j = 0; j < 32; ++j) { 106 | var idx = (i + j) / 32; 107 | 108 | var value = ((a[0] >> (i % 32)) & (a[1] >> (j % 32)) & 1) << ((i + j) % 32); 109 | b[idx] ^= value; 110 | if (idx == 0) { 111 | var pv = i % 32; 112 | if (pv <= 9) { 113 | print("0"); 114 | } 115 | print(pv); 116 | } else { 117 | print(" "); 118 | } 119 | print(" "); 120 | } 121 | print("\n"); 122 | } 123 | 124 | 125 | print("\n"); 126 | for (var i = 0; i < 32; ++i) { 127 | for (var j = 0; j < 32; ++j) { 128 | var idx = (i + j) / 32; 129 | var value = ((a[0] >> (i % 32)) & (a[1] >> (j % 32)) & 1) << ((i + j) % 32); 130 | b[idx] ^= value; 131 | if (idx == 0) { 132 | var pv = j % 32; 133 | if (pv <= 9) { 134 | print("0"); 135 | } 136 | print(pv); 137 | } else { 138 | print(" "); 139 | } 140 | print(" "); 141 | var bit_idx = (i + j) % 32; 142 | var str = b_0[bit_idx]; 143 | str = concat(str, " + "); 144 | str = concat(str, to_str(i % 32)); 145 | str = concat(str, "*"); 146 | str = concat(str, to_str(j % 32)); 147 | b_0[bit_idx] = str; 148 | } 149 | print("\n"); 150 | 151 | } 152 | 153 | for (var idx = 0; idx < b_0.length; ++idx) { 154 | print("bit: "); 155 | print(idx); 156 | print("\n"); 157 | print(b_0[idx]); 158 | print("\n\n"); 159 | } 160 | 161 | for (var i = 0; i < b.length; ++i) { 162 | if (i > 0) { 163 | print(" "); 164 | } 165 | print_hex(b[i]); 166 | } 167 | print("\n"); 168 | 169 | } else { 170 | assert(false); 171 | } 172 | 173 | } 174 | -------------------------------------------------------------------------------- /publish/current/samples/basics/test_simd.prag: -------------------------------------------------------------------------------- 1 | import "../preamble.prag" 2 | import "../random.prag" 3 | import "../simd.prag" 4 | import "../math.prag" 5 | 6 | let print_vec = fun(v: f32_4x) => void { 7 | print("v: "); 8 | print(v[0]); 9 | print(", "); 10 | print(v[1]); 11 | print(", "); 12 | print(v[2]); 13 | print(", "); 14 | print(v[3]); 15 | print("\n"); 16 | } 17 | 18 | let print_vec = fun(v: i32_4x) => void { 19 | print("v: "); 20 | print(v[0]); 21 | print(", "); 22 | print(v[1]); 23 | print(", "); 24 | print(v[2]); 25 | print(", "); 26 | print(v[3]); 27 | print("\n"); 28 | } 29 | 30 | #if FALSE 31 | let print_vec = fun(v: f32_8x) => void { 32 | print("v: "); 33 | for (var i = 0; i < 8; ++i) { 34 | print(v[0]); 35 | if (i != 7) { 36 | print(", "); 37 | } 38 | } 39 | print("\n"); 40 | } 41 | #endif 42 | 43 | 44 | let foo = struct ( 45 | a: i32; 46 | b: i32; 47 | ); 48 | 49 | 50 | [ 51 | "compile.output": "test_simd.exe", 52 | "compile.debuginfo": "true", 53 | "compile.entry" : "true", 54 | "compile.ll" : "true", 55 | "compile.asm" : "false", 56 | "compile.opt" : "0", 57 | "compile.run" : "true", 58 | "compile.libs" : "kernel32.lib, libopenlibm.a" 59 | ] 60 | let main = fun () => void { 61 | // print_vec(Random::rand_v4()); 62 | // print_vec(Random::rand_v4()); 63 | // print_vec(Random::rand_v4()); 64 | // print_vec(Random::rand_v4()); 65 | // print_vec(Random::rand_v4()); 66 | // print_vec(Random::rand_v4()); 67 | 68 | // var arr = [SIMD::set1_ps(0.0), SIMD::set1_ps(1.0), SIMD::set1_ps(2.0)]; 69 | 70 | // var a = i32_4x { 1, 2, 3, 4}; 71 | // var b = SIMD::srli_si128(a, 3); 72 | // debug_print("a", a); 73 | // debug_print("b", b); 74 | 75 | 76 | var mask = SIMD::set1_epi32(0x00FF00FF); 77 | var test = SIMD::cvtepi32_ps(mask); 78 | debug_print("mask", mask); 79 | debug_print("test", test); 80 | 81 | 82 | // var foobarzuz = Random::rand_f32_4x() < Random::rand_f32_4x(); 83 | 84 | 85 | // var y = Math::exp(x); 86 | 87 | 88 | // debug_print("rnd", Random::rand_i32()); 89 | // debug_print("rnd", Random::rand_i32()); 90 | // debug_print("rnd", Random::rand_i32()); 91 | // debug_print("rnd", Random::rand_i32()); 92 | // debug_print("rnd", Random::rand_i32()); 93 | // debug_print("rnd", Random::rand_i32()); 94 | // debug_print("rnd", Random::rand_i32()); 95 | // debug_print("rnd", Random::rand_i32()); 96 | 97 | } -------------------------------------------------------------------------------- /publish/current/samples/editor/edit_compile.prag: -------------------------------------------------------------------------------- 1 | import "../preamble.prag" 2 | import "../windows.prag" 3 | import "edit.prag" 4 | 5 | 6 | let compiler_message_type = enum( 7 | none = 0; error; warning 8 | ); 9 | let compiler_message = struct( 10 | message_type: compiler_message_type; 11 | message: string; 12 | file_path: string; 13 | line: i32; 14 | pos: i32; 15 | ); 16 | 17 | let parse_compiler_message = fun(msg: string) => compiler_message { 18 | var result = compiler_message { }; 19 | 20 | if (msg.data == nullptr || msg.length == 0) { 21 | return result; 22 | } 23 | 24 | if (starts_with("error: ", msg)) { 25 | var s = msg[7:]; 26 | var idx_at = first_index_of(" at (", s); 27 | if (idx_at == -1) { 28 | return result; 29 | } 30 | var error_msg = s[:idx_at]; 31 | var loc = trim_right(s[idx_at + 4:]); 32 | var file_idx = first_index_of(", file \"", loc) + 8; 33 | var file_idx_end = first_index_of("\", ", loc, file_idx); 34 | var file_path = loc[file_idx:file_idx_end]; 35 | loc = loc[file_idx_end + 8:]; 36 | var line_str = loc[:first_index_of(",", loc)]; 37 | loc = loc[line_str.length + 6:]; 38 | var pos_str = loc[:first_index_of(",", loc)]; 39 | 40 | result.message_type = compiler_message_type::error; 41 | result.message = error_msg; 42 | result.file_path = file_path; 43 | from_str(line_str, &result.line); 44 | from_str(pos_str, &result.pos); 45 | } 46 | return result; 47 | } 48 | 49 | let compile_buffer = fun(path: string; just_syntax: bool) => compiler_message { 50 | // TODO(pragma): this is stupid 51 | var cmd: string; 52 | if (just_syntax) 53 | { 54 | cmd = "pragma build -d --dry-run "; 55 | } 56 | else 57 | { 58 | cmd = "pragma build -d "; 59 | } 60 | 61 | cmd = concat(cmd, path); 62 | cmd = concat(cmd, "\0"); 63 | 64 | var sa = Windows::SECURITY_ATTRIBUTES {}; 65 | sa.nLength = size_of(Windows::SECURITY_ATTRIBUTES)@i32; 66 | sa.InheritHandle = 1; 67 | 68 | var stdin_pipe_read: mm = 0; 69 | var stdin_pipe_write: mm = 0; 70 | var stdout_pipe_read: mm = 0; 71 | var stdout_pipe_write: mm = 0; 72 | 73 | var success = 1; 74 | success = Windows::CreatePipe(&stdin_pipe_read, &stdin_pipe_write, &sa, 0); 75 | assert(success != 0); 76 | success = Windows::CreatePipe(&stdout_pipe_read, &stdout_pipe_write, &sa, 0); 77 | assert(success != 0); 78 | 79 | 80 | var si = Windows::STARTUPINFOA {}; 81 | si.cb = size_of(Windows::STARTUPINFOA)@i32; 82 | si.dwFlags = Windows::STARTF_USESTDHANDLES; 83 | si.hStdError = stdout_pipe_write; 84 | si.hStdOutput = stdout_pipe_write; 85 | si.hStdInput = stdin_pipe_read; 86 | 87 | var pi = Windows::PROCESS_INFORMATION {}; 88 | Windows::CreateProcessA(nullptr, cstr(cmd), nullptr, nullptr, 1, 0, nullptr, nullptr, &si, &pi); 89 | Windows::CloseHandle(stdout_pipe_write); 90 | Windows::CloseHandle(stdin_pipe_read); 91 | 92 | var watermark = start_temp(&temp_memory_arena); 93 | // TODO(pragma): we are leaking this memory 94 | 95 | let MAX_MSG_SIZE = 1024*1024; 96 | var buf = make_string(MAX_MSG_SIZE); 97 | var total_bytes_read = 0; 98 | while (true) { 99 | var max_size = MAX_MSG_SIZE - 1 - total_bytes_read; 100 | var bytes_read = 0; 101 | assert(max_size > 0); 102 | success = Windows::ReadFile(stdout_pipe_read, &buf[total_bytes_read], max_size, &bytes_read, nullptr); 103 | total_bytes_read += bytes_read; 104 | if (success == 0) { 105 | // debug_print("GetLastError", Windows::GetLastError()); 106 | break; 107 | } 108 | } 109 | var result = parse_compiler_message(buf[:total_bytes_read]); 110 | 111 | Windows::CloseHandle(stdout_pipe_read); 112 | Windows::CloseHandle(stdin_pipe_write); 113 | 114 | Windows::CloseHandle(pi.hProcess); 115 | Windows::CloseHandle(pi.hThread); 116 | 117 | return result; 118 | } -------------------------------------------------------------------------------- /publish/current/samples/handmade/handmade_interface.prag: -------------------------------------------------------------------------------- 1 | mod Handmade 2 | { 3 | let game_sound_output = struct 4 | ( 5 | samples_per_second: i32; 6 | num_channels: i32; 7 | start_buffer: i16*; 8 | end_buffer: i16*; 9 | ); 10 | 11 | let game_button = struct 12 | ( 13 | pressed: bool; 14 | down: bool; 15 | up: bool; 16 | ); 17 | 18 | let game_time = struct 19 | ( 20 | dt: f32; 21 | t: f32; 22 | ); 23 | 24 | let game_input = struct 25 | ( 26 | time: game_time; 27 | 28 | up_arrow: game_button; 29 | left_arrow: game_button; 30 | right_arrow: game_button; 31 | down_arrow: game_button; 32 | 33 | left_mb: game_button; 34 | right_mb: game_button; 35 | middle_mb: game_button; 36 | mouse_x: i32; 37 | mouse_y: i32; 38 | mouse_z: i32; 39 | 40 | 41 | request_quit: bool; 42 | ); 43 | 44 | let game_render_target = struct 45 | ( 46 | memory: ptr; 47 | width: i32; 48 | height: i32; 49 | pitch: i32; 50 | ); 51 | 52 | 53 | let game_memory = struct 54 | ( 55 | platform: platform_interface*; 56 | permanent_size: mm; 57 | permanent_data: ptr; 58 | 59 | transient_size: mm; 60 | transient_data: ptr; 61 | ); 62 | 63 | let game_update_and_render = fun 64 | ( 65 | memory: game_memory*; 66 | input: game_input*; 67 | render_target: game_render_target*; 68 | ) => bool; 69 | 70 | let game_output_sound = fun 71 | ( 72 | game_memory: game_memory*; 73 | @sound_output: game_sound_output*; 74 | ) => void; 75 | 76 | // ******************************************************** 77 | 78 | let platform_write_file = fun (name: string; buffer: i8[]) => bool; 79 | let platform_read_file = fun (name: string) => i8[]; 80 | let platform_free_file_memory = fun (mem: ptr) => void; 81 | let platform_interface = struct 82 | ( 83 | write_file: platform_write_file; 84 | read_file: platform_read_file; 85 | free_file_memory: platform_free_file_memory; 86 | ); 87 | } -------------------------------------------------------------------------------- /publish/current/samples/handmade/handmade_math.prag: -------------------------------------------------------------------------------- 1 | mod Handmade 2 | { 3 | let vec2 = struct 4 | ( 5 | x: f32; y: f32; 6 | ); 7 | let vec3 = struct 8 | ( 9 | x: f32; y: f32; z: f32; 10 | ); 11 | let vec4 = struct 12 | ( 13 | x: f32; y: f32; z: f32; w: f32; 14 | ); 15 | let color = struct 16 | ( 17 | r: f32; g: f32; b: f32; a: f32; 18 | ); 19 | let rectangle = struct 20 | ( 21 | pos: vec2; 22 | size: vec2; 23 | ); 24 | 25 | let min_max_rect = fun (min_x: i32; min_y: i32; max_x: i32; max_y: i32) => rectangle 26 | { 27 | var pos = vec2 { min_x@f32, min_y@f32 }; 28 | var size = vec2 { (max_x - min_x)@f32, (max_y - min_y)@f32 }; 29 | var result = rectangle{pos, size}; 30 | return result; 31 | } 32 | 33 | let center_half_size_rect = fun (x: i32; y: i32; half_size: i32) => rectangle 34 | { 35 | 36 | var pos = vec2 { (x - half_size)@f32, (y - half_size)@f32 }; 37 | var size = vec2 { (2 * half_size)@f32, (2 * half_size)@f32 }; 38 | var result = rectangle{pos, size}; 39 | return result; 40 | } 41 | } -------------------------------------------------------------------------------- /publish/current/samples/handmade/handmade_memory.prag: -------------------------------------------------------------------------------- 1 | import "../preamble.prag" 2 | 3 | mod Handmade::Memory 4 | { 5 | let memory_arena = struct ( 6 | base: ptr; 7 | size: mm; 8 | used: i32; 9 | ); 10 | 11 | let init = fun (arena: memory_arena*; base: ptr; size: mm) { 12 | arena.base = ptr; 13 | arena.size = size; 14 | arena.used = 0; 15 | } 16 | 17 | let push = fun (arena: memory_arena*; size: mm) => ptr { 18 | assert(arena.used + size <= arena.size); 19 | var result = arena.ptr + used; 20 | used += size; 21 | return result; 22 | } 23 | 24 | 25 | } -------------------------------------------------------------------------------- /publish/current/samples/ld46/game.prag: -------------------------------------------------------------------------------- 1 | import "ld.prag" 2 | 3 | let word_map = struct( 4 | ); 5 | let world_chunk_size = 64; 6 | let world_chunk = struct( 7 | ); 8 | let camera = struct( 9 | ); 10 | 11 | let update = fun(tile_map: tile_map*; time: f32) => void { 12 | var uvs0 = tile_map.uvs0; 13 | var uvs1 = tile_map.uvs1; 14 | var tcx = tile_map.tile_count_x; 15 | var tcy = tile_map.tile_count_y; 16 | var offset = 4 * tcx; 17 | for (var j = 0; j < tcy - 1; ++j) { 18 | for (var i = 0; i < 4*tcx; ++i) { 19 | uvs0[j * tcx * 4 + i] = uvs0[j * tcx * 4 + offset + i]; 20 | uvs1[j * tcx * 4 + i] = uvs1[j * tcx * 4 + offset + i]; 21 | } 22 | } 23 | for (var i = 0; i < tcx; ++i) { 24 | set_tile(tile_map, uvs0, get_random_grass(), i, 0); 25 | if (Random::rand_i32() % 4 == 0) { 26 | set_tile(tile_map, uvs1, get_random_tree(), i, 0); 27 | } 28 | else 29 | { 30 | set_tile(tile_map, uvs1, basic_tiles::_e0, i, 0); 31 | } 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /publish/current/samples/linux.prag: -------------------------------------------------------------------------------- 1 | mod Linux 2 | { 3 | ["stub"] 4 | let __write = extern fun(fd: i32; buf: ptr; size: mm) => i64; 5 | 6 | ["stub"] 7 | let __read = extern fun(fd: i32; buf: ptr; size: mm) => i64; 8 | 9 | ["stub"] 10 | let __open = extern fun(filename: i8*; flags: i32; mode: i32) => i32; 11 | 12 | ["stub"] 13 | let __close = extern fun(fd: i32) => i32; 14 | 15 | ["stub"] 16 | let __openat = extern fun(dirfd: i32; filename: i8*; flags: i32; mode: i32) => i32; 17 | 18 | ["stub"] 19 | let __mmap = extern fun(addr: ptr; length: mm; prot: i32; flags: i32; fd: i32; offset: mm) => ptr; 20 | 21 | ["stub"] 22 | let __munmap = extern fun(addr: ptr; length: mm) => i32; 23 | 24 | 25 | // *** Dumping AST Record Layout 26 | // 0 | struct stat 27 | // 0 | __dev_t st_dev 28 | // 8 | __ino_t st_ino 29 | // 16 | __nlink_t st_nlink 30 | // 24 | __mode_t st_mode 31 | // 28 | __uid_t st_uid 32 | // 32 | __gid_t st_gid 33 | // 36 | int __pad0 34 | // 40 | __dev_t st_rdev 35 | // 48 | __off_t st_size 36 | // 56 | __blksize_t st_blksize 37 | // 64 | __blkcnt_t st_blocks 38 | // 72 | struct timespec st_atim 39 | // 72 | __time_t tv_sec 40 | // 80 | __syscall_slong_t tv_nsec 41 | // 88 | struct timespec st_mtim 42 | // 88 | __time_t tv_sec 43 | // 96 | __syscall_slong_t tv_nsec 44 | // 104 | struct timespec st_ctim 45 | // 104 | __time_t tv_sec 46 | // 112 | __syscall_slong_t tv_nsec 47 | // 120 | __syscall_slong_t [3] __glibc_reserved 48 | // | [sizeof=144, dsize=144, align=8, 49 | // | nvsize=144, nvalign=8] 50 | 51 | 52 | let timespec = struct( 53 | tv_sec: i64; 54 | tv_nsec: i64; 55 | ); 56 | 57 | ["packed"] 58 | let stat = struct( 59 | st_dev: i64; 60 | st_ino: i64; 61 | st_nlink: i64; 62 | st_mode: i32; 63 | st_uid: i32; 64 | st_gid: i32; 65 | __pad0: i32; 66 | st_rdev: i64; 67 | st_size: i64; 68 | st_blksize: i64; 69 | st_blocks: i64; 70 | st_atim: timespec; 71 | st_mtim: timespec; 72 | st_ctim: timespec; 73 | reserved: i64[3]; 74 | ); 75 | 76 | ["stub"] 77 | let __fstatat = extern fun(dfd: i32; filename: i8*; statbuf: i8*; flag: i32) => i32; 78 | 79 | let MAP_SHARED = 0x01; 80 | let MAP_PRIVATE = 0x02; 81 | let MAP_TYPE = 0x0F; 82 | let MAP_FIXED = 0x10; 83 | let MAP_ANON = 0x20; 84 | let MAP_ANONYMOUS = MAP_ANON; 85 | let MAP_NORESERVE = 0x4000; 86 | let MAP_GROWSDOWN = 0x0100; 87 | let MAP_DENYWRITE = 0x0800; 88 | let MAP_EXECUTABLE = 0x1000; 89 | let MAP_LOCKED = 0x2000; 90 | let MAP_POPULATE = 0x8000; 91 | let MAP_NONBLOCK = 0x10000; 92 | let MAP_STACK = 0x20000; 93 | let MAP_HUGETLB = 0x40000; 94 | let MAP_FILE = 0; 95 | 96 | let PROT_NONE = 0; 97 | let PROT_READ = 1; 98 | let PROT_WRITE = 2; 99 | let PROT_EXEC = 4; 100 | let PROT_GROWSDOWN = 0x01000000; 101 | let PROT_GROWSUP = 0x02000000; 102 | 103 | let MS_ASYNC = 1; 104 | let MS_INVALIDATE = 2; 105 | let MS_SYNC = 4; 106 | 107 | let MCL_CURRENT = 1; 108 | let MCL_FUTURE = 2; 109 | let MCL_ONFAULT = 4; 110 | 111 | let POSIX_MADV_NORMAL = 0; 112 | let POSIX_MADV_RANDOM = 1; 113 | let POSIX_MADV_SEQUENTIAL = 2; 114 | let POSIX_MADV_WILLNEED = 3; 115 | let POSIX_MADV_DONTNEED = 4; 116 | 117 | let O_ACCMODE = 0x0003; 118 | let O_RDONLY = 0x0000; 119 | let O_WRONLY = 0x0001; 120 | let O_RDWR = 0x0002; 121 | let O_CREAT = 0x0040; 122 | let O_EXCL = 0x0080; 123 | let O_NOCTTY = 0x0100; 124 | let O_TRUNC = 0x0200; 125 | let O_APPEND = 0x0400; 126 | let O_NONBLOCK = 0x0800; 127 | let O_NDELAY = O_NONBLOCK; 128 | let O_SYNC = 0x101000; 129 | let O_FSYNC = O_SYNC; 130 | let O_ASYNC = 0x2000; 131 | let O_LARGEFILE = 0x8000; 132 | 133 | let AT_FDCWD = -100; 134 | 135 | 136 | } -------------------------------------------------------------------------------- /publish/current/samples/math.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | // http://openlibm.org/ 3 | mod Math 4 | { 5 | let pi: f64 = 3.1415926535897932384626433832795028841971693993751058209749445923078164062; 6 | let half_pi = pi / 2.0; 7 | let pi_32 = pi@f32; 8 | let half_pi_32 = half_pi@f32; 9 | let tau = 2.0 * pi; 10 | let tau_32 = 2.0 * pi_32; 11 | 12 | ["READNONE"] 13 | let sin = extern("llvm.sin.f32") fun (x: f32) => f32; 14 | ["READNONE"] 15 | let cos = extern("llvm.cos.f32") fun (x: f32) => f32; 16 | ["READNONE"] 17 | let tan = extern("tanf") fun (x: f32) => f32; 18 | ["READNONE"] 19 | let asin = extern("asinf") fun (x: f32) => f32; 20 | ["READNONE"] 21 | let acos = extern("acosf") fun (x: f32) => f32; 22 | ["READNONE"] 23 | let atan = extern("atanf") fun (x: f32) => f32; 24 | ["READNONE"] 25 | let atan2 = extern("atan2f") fun (x: f32) => f32; 26 | ["READNONE"] 27 | let sqrt = extern("llvm.sqrt.f32") fun (x: f32) => f32; 28 | ["READNONE"] 29 | let pow = extern("llvm.pow.f32") fun (x: f32; p: f32) => f32; 30 | ["READNONE"] 31 | let abs = extern("llvm.fabs.f32") fun (x: f32) => f32; 32 | ["READNONE"] 33 | let floor = extern("llvm.floor.f32") fun (x: f32) => f32; 34 | ["READNONE"] 35 | let trunc = extern("llvm.trunc.f32") fun (x: f32) => f32; 36 | ["READNONE"] 37 | let ceil = extern("llvm.ceil.f32") fun (x: f32) => f32; 38 | ["READNONE"] 39 | let round = extern("llvm.round.f32") fun (x: f32) => f32; 40 | ["READNONE"] 41 | let exp = extern("llvm.exp.f32") fun (x: f32) => f32; 42 | ["READNONE"] 43 | let exp2 = extern("llvm.exp2.f32") fun (x: f32) => f32; 44 | ["READNONE"] 45 | let log = extern("llvm.log.f32") fun (x: f32) => f32; 46 | ["READNONE"] 47 | let log2 = extern("llvm.log2.f32") fun (x: f32) => f32; 48 | ["READNONE"] 49 | let log10 = extern("llvm.log10.f32") fun (x: f32) => f32; 50 | 51 | ["READNONE"] 52 | let exp = extern("llvm.exp.f32") fun (x: f32_4x) => f32_4x; 53 | ["READNONE"] 54 | let log = extern("llvm.log.f32") fun (x: f32_4x) => f32_4x; 55 | 56 | 57 | // ["READNONE"] 58 | // let min = extern("llvm.minnum.f32") fun (a: f32; b: f32) => f32; 59 | // ["READNONE"] 60 | // let max = extern("llvm.maxnum.f32") fun (a: f32; b: f32) => f32; 61 | 62 | ["READNONE"] 63 | let min = fun(a: f32; b: f32) => f32 { 64 | if (a < b) { 65 | return a; 66 | } else { 67 | return b; 68 | } 69 | } 70 | 71 | ["READNONE"] 72 | let max = fun(a: f32; b: f32) => f32 { 73 | if (a > b) { 74 | return a; 75 | } else { 76 | return b; 77 | } 78 | } 79 | 80 | ["READNONE"] 81 | let max = fun(a: i32; b: i32) => i32 { 82 | if (a > b) { 83 | return a; 84 | } else { 85 | return b; 86 | } 87 | } 88 | 89 | ["READNONE"] 90 | let min = fun(a: i32; b: i32) => i32 { 91 | if (a < b) { 92 | return a; 93 | } else { 94 | return b; 95 | } 96 | } 97 | 98 | let swap = fun (a: f32*; b: f32*) => void { 99 | var temp = *a; 100 | *a = *b; 101 | *b = temp; 102 | } 103 | 104 | ["READNONE"] 105 | let round_to_i32 = fun (x: f32) => i32 { 106 | return round(x)@i32; 107 | } 108 | ["READNONE"] 109 | let remainder = fun(x: f32; y: f32) => f32 110 | { 111 | return x - floor(x / y) * y; 112 | } 113 | ["READNONE"] 114 | let lerp = fun(a: f32; b: f32; t: f32) => f32 115 | { 116 | return a + (b-a)*t; 117 | } 118 | ["READNONE"] 119 | let abs = fun (value: i32) => i32 120 | { 121 | if (value >= 0) { 122 | return value; 123 | } else { 124 | return -value; 125 | } 126 | } 127 | 128 | ["READNONE"] 129 | let sign = fun (value: f32) => f32 { 130 | if (value > 0) { 131 | return 1.0; 132 | } elif (value < 0) { 133 | return -1.0; 134 | } else { 135 | return 0.0; 136 | } 137 | } 138 | 139 | ["READNONE"] 140 | let clamp = fun 141 | ( 142 | value: i32; 143 | min: i32; 144 | max: i32 145 | ) => i32 146 | { 147 | assert(min <= max); 148 | var result = value; 149 | if (result < min) { 150 | result = min; 151 | } elif (result > max) { 152 | result = max; 153 | } 154 | return result; 155 | } 156 | 157 | ["READNONE"] 158 | let clamp = fun (value: f32; min: f32; max: f32) => f32 159 | { 160 | assert(min <= max); 161 | var result = value; 162 | if (result < min) { 163 | result = min; 164 | } elif (result > max) { 165 | result = max; 166 | } 167 | return result; 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /publish/current/samples/memory.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | 3 | let memory_arena = struct( 4 | size: mm; 5 | base: ptr; 6 | used: mm; 7 | ); 8 | 9 | let align_4 = fun(value: mm) => mm{ 10 | return (value + 3) & (~3); 11 | } 12 | let align_8 = fun(value: mm) => mm { 13 | return (value + 7) & (~7); 14 | } 15 | let align_16 = fun(value: mm) => mm { 16 | return (value + 15) & (~15); 17 | } 18 | 19 | let push = fun(@arena: memory_arena*; push_size: mm) => ptr { 20 | var result = base + used; 21 | // result = align_16(result@mm)@ptr; 22 | 23 | used = result@mm - base@mm + push_size@mm; 24 | 25 | if (used > size) { 26 | assert(false); 27 | return nullptr; 28 | } 29 | return result; 30 | } 31 | 32 | let start_temp = fun(@arena: memory_arena*;) => mm { 33 | return used; 34 | } 35 | 36 | let stop_temp = fun(@arena: memory_arena*; temp_used: mm) => void { 37 | used = temp_used; 38 | } 39 | mod _INTERNAL { 40 | // TODO(pragma): this stuff should be thread local? 41 | var temp_memory_stack_pos: i32; 42 | var temp_memory_stack: mm[32]; 43 | } 44 | 45 | 46 | // TODO(pragma): make this threadsafe 47 | let push_temp = fun(@arena: memory_arena* = &temp_memory_arena) => void { 48 | _INTERNAL::temp_memory_stack[_INTERNAL::temp_memory_stack_pos++] = start_temp(arena); 49 | if (_INTERNAL::temp_memory_stack_pos@mm >= len(_INTERNAL::temp_memory_stack)) { 50 | assert(false, "Exceeded max temp memory stack size!"); 51 | } 52 | } 53 | 54 | // TODO(pragma): make this threadsafe 55 | let pop_temp = fun(@arena: memory_arena* = &temp_memory_arena) => void { 56 | _INTERNAL::temp_memory_stack_pos--; 57 | if (_INTERNAL::temp_memory_stack_pos < 0) { 58 | assert(false, "Inbalanced push_temp pop_temp operations. Stack pos below 0!"); 59 | } 60 | stop_temp(arena, _INTERNAL::temp_memory_stack[_INTERNAL::temp_memory_stack_pos]); 61 | } 62 | 63 | let create_arena = fun(size: mm) => memory_arena { 64 | var data = allocate(size); 65 | var result: memory_arena; 66 | if (data != nullptr) { 67 | result.size = size; 68 | result.base = data; 69 | result.used = 0; 70 | } else { 71 | result.size = 0; 72 | result.base = nullptr; 73 | result.used = 0; 74 | } 75 | return result; 76 | } 77 | 78 | let get_slice = fun(@arena: memory_arena*) => i8[] { 79 | var result = base[:used@i32]; 80 | return result; 81 | } 82 | -------------------------------------------------------------------------------- /publish/current/samples/nn/nn.prag: -------------------------------------------------------------------------------- 1 | import "../preamble.prag" 2 | import "../random.prag" 3 | import "../math.prag" 4 | 5 | let f = fun(x: f32; y: f32) => f32 { 6 | var result = x * y + Math::sin(x); 7 | return result; 8 | } 9 | 10 | let fdx = fun(x: f32; y: f32) => f32 { 11 | var result = y + Math::cos(x); 12 | return result; 13 | } 14 | 15 | let fdy = fun(x: f32; y: f32) => f32 { 16 | var result = x; 17 | return result; 18 | } 19 | 20 | let ft = fun(x: f32;y: f32) => f32; 21 | 22 | let delta = 0.000001; 23 | let dx_at = fun(x: f32; y: f32) => f32 { 24 | var result = (f(x + delta, y) - f(x - delta, y)) / (2.0 * delta); 25 | return result; 26 | } 27 | let dy_at = fun(x: f32; y: f32) => f32 { 28 | var result = (f(x, y + delta) - f(x, y - delta)) / (2.0 * delta); 29 | return result; 30 | } 31 | 32 | 33 | [ 34 | "compile.output": "nn.exe", 35 | "compile.entry" : "true", 36 | "compile.opt" : "0", 37 | "compile.debuginfo": "true", 38 | "compile.ll" : "false", 39 | "compile.asm" : "false", 40 | "compile.cpu" : "native", // "sandybridge", 41 | "compile.run" : "true", 42 | "compile.libs" : "kernel32.lib, user32.lib, gdi32.lib, shcore.lib, libopenlibm.a, opengl32.lib" 43 | ] 44 | let main = fun () => void { 45 | let x = 1.2; 46 | let y = -0.3; 47 | debug_print("x", x); 48 | debug_print("y", y); 49 | debug_print("f", f(x, y)); 50 | debug_print("dx_at", dx_at(x, y)); 51 | debug_print("dy_at", dy_at(x, y)); 52 | debug_print("fdx", fdx(x, y)); 53 | debug_print("fdy", fdy(x, y)); 54 | } 55 | -------------------------------------------------------------------------------- /publish/current/samples/opengl/fs.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 7 | } -------------------------------------------------------------------------------- /publish/current/samples/opengl/vs.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | void main() 5 | { 6 | gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); 7 | } -------------------------------------------------------------------------------- /publish/current/samples/random.prag: -------------------------------------------------------------------------------- 1 | 2 | mod Random 3 | { 4 | let seed0 = 12345; 5 | let seed1 = 33333; 6 | let seed2 = 982845; 7 | let seed3 = 11293929; 8 | 9 | let state = struct 10 | ( 11 | z1: i32_4x; 12 | z2: i32_4x; 13 | z3: i32_4x; 14 | z4: i32_4x; 15 | ); 16 | 17 | // var state: state = state{seed0, seed0, seed0, seed0}; 18 | var state: state = state { 19 | i32_4x {seed0, seed1, seed2, seed3}, 20 | i32_4x {seed0, seed1, seed2, seed3}, 21 | i32_4x {seed0, seed1, seed2, seed3}, 22 | i32_4x {seed0, seed1, seed2, seed3} 23 | }; 24 | 25 | 26 | let init_seed = fun (seed: i32_4x; state: state*) => void { 27 | state.z1 = seed; 28 | state.z2 = seed; 29 | state.z3 = seed; 30 | state.z4 = seed; 31 | } 32 | 33 | let rand_i32_4x = fun (@state: state*) => i32_4x { 34 | let vi_2 = i32_4x { 2, 2, 2, 2 }; 35 | let vi_3 = i32_4x { 3, 3, 3, 3 }; 36 | let vi_6 = i32_4x { 6, 6, 6, 6 }; 37 | let vi_7 = i32_4x { 7, 7, 7, 7 }; 38 | let vi_12 = i32_4x { 12, 12, 12, 12 }; 39 | let vi_13 = i32_4x { 13, 13, 13, 13}; 40 | let vi_18 = i32_4x { 18, 18, 18, 18}; 41 | let vi_21 = i32_4x { 21, 21, 21, 21}; 42 | let vi_27 = i32_4x { 27, 27, 27, 27}; 43 | let vi_m0 = i32_4x { 4294967294, 4294967294, 4294967294, 4294967294 }; 44 | let vi_m1 = i32_4x { 4294967288, 4294967288, 4294967288, 4294967288 }; 45 | let vi_m2 = i32_4x { 4294967280, 4294967280, 4294967280, 4294967280 }; 46 | let vi_m3 = i32_4x { 4294967168, 4294967168, 4294967168, 4294967168 }; 47 | 48 | var b: i32_4x; 49 | b = ((z1 << vi_6) ^ z1) >>\ vi_13; 50 | z1 = ((z1 & vi_m0) << vi_18) ^ b; 51 | b = ((z2 << vi_2) ^ z2) >>\ vi_27; 52 | z2 = ((z2 & vi_m1) << vi_2) ^ b; 53 | b = ((z3 << vi_13) ^ z3) >>\ vi_21; 54 | z3 = ((z3 & vi_m2) << vi_7) ^ b; 55 | b = ((z4 << vi_3) ^ z4) >>\ vi_12; 56 | z4 = ((z4 & vi_m3) << vi_13) ^ b; 57 | return (z1 ^ z2 ^ z3 ^ z4); 58 | } 59 | 60 | let rand_f32_4x = fun(min: f32_4x = f32_4x { 0.0, 0.0, 0.0, 0.0 }; max: f32_4x = f32_4x { 1.0, 1.0, 1.0, 1.0 }; state: state* = &state) => f32_4x { 61 | let div = f32_4x { 4294967295.0, 4294967295.0, 4294967295.0, 4294967295.0 }; 62 | var x = rand_i32_4x(state); 63 | var result = @\f32_4x x / div; 64 | result = min + result * (max - min); 65 | return result; 66 | } 67 | 68 | let rand_i32 = fun(state: state* = &state) => i32 { 69 | var result = rand_i32_4x(state); 70 | return result[0]; 71 | } 72 | 73 | let rand_f32 = fun (min: f32 = 0.0; max: f32 = 1.0; state: state* = &state;) => f32 { 74 | var x = rand_i32(state); 75 | var result = @\f32 x / 4294967295.0; 76 | result = min + result * (max - min); 77 | return result; 78 | } 79 | let rand_xkcd = fun () => i32 { 80 | return 4; // chosen by fair dice roll. 81 | // guaranteed to be random. 82 | } 83 | } -------------------------------------------------------------------------------- /publish/current/samples/simd.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | mod SIMD 3 | { 4 | // declare <4 x float> @llvm.x86.sse.max.ps(<4 x float>, <4 x float>) 5 | 6 | let max_ps = extern("llvm.x86.sse.max.ps") fun (a: f32_4x; b: f32_4x) => f32_4x; 7 | let min_ps = extern("llvm.x86.sse.min.ps") fun (a: f32_4x; b: f32_4x) => f32_4x; 8 | 9 | 10 | let set1_ps = fun(v: f32) => f32_4x { 11 | return f32_4x { v, v, v, v }; 12 | } 13 | let set1_epi32 = fun(v: i32) => i32_4x { 14 | return i32_4x {v, v, v, v}; 15 | } 16 | let cvtepi32_ps = fun(v: i32_4x) => f32_4x { 17 | return v@f32_4x; 18 | } 19 | 20 | let rcp_ps = extern("llvm.x86.sse.rcp.ps") fun(v: f32_4x) => f32_4x; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /publish/current/samples/test/array.prag: -------------------------------------------------------------------------------- 1 | import "../preamble.prag" 2 | 3 | // let print_array = fun (x: i32*; length: i32) => void { 4 | // for (var idx = 0; idx < length; ++idx) { 5 | // print_i32(*(x+idx)); 6 | // } 7 | // } 8 | 9 | // let matrix = struct( 10 | // e: i32[4, 4]; 11 | // ); 12 | 13 | // let print_matrix = fun (m: matrix*) => void { 14 | // for (var j = 0; j < (i32\)len(m.e, 0); ++j) { 15 | // for (var i = 0; i < (i32\)len(m.e, 1); ++i) { 16 | // print_i32(m.e[j, i]); 17 | // if (i != 3) { 18 | // print_string(", "); 19 | // } 20 | // } 21 | // print_string("\n"); 22 | // } 23 | // } 24 | 25 | 26 | // let print_int_slice = fun(x: i32[]) => void { 27 | // for (var i = 0; i < x.length; ++i) { 28 | // print_i32(x[i]); 29 | // if (i != x.length - 1) { 30 | // print_string(", "); 31 | // } 32 | // } 33 | // } 34 | 35 | let print_array_unsafe = fun(arr: i32*; count: i32) => void { 36 | for (var idx = 0; idx < count; ++idx) { 37 | print_i32(*(arr + idx)); 38 | print_string("\n"); 39 | } 40 | } 41 | 42 | 43 | [ 44 | "compile.output": "array.exe", 45 | "compile.entry" : "true", 46 | "compile.opt" : "0", 47 | "compile.ll" : "true", 48 | "compile.asm" : "false", 49 | "compile.run" : "true", 50 | "compile.libs" : "kernel32.lib" 51 | ] 52 | let main = fun () => void { 53 | var arr = [1,2,3,4]; 54 | 55 | var elptr = &arr; 56 | print_array_unsafe(elptr, (i32\)len(arr)); 57 | 58 | debug_print_i32("size_of(foo)", (i32\)(size_of(foo))); 59 | 60 | // debug_print_i32("arr: ", (i32\)len(arr)); 61 | 62 | // for (var i = 0; i < (i32\)len(arr); ++i) { 63 | // print_i32(arr[i]); 64 | // if (i != (i32\)len(arr) - 1) { 65 | // print_string(", "); 66 | // } 67 | // } 68 | // print_string("\n"); 69 | 70 | // var arr2d = [[1, 2, 3], 71 | // [4, 5, 6], 72 | // [7, 8, 9]]; 73 | // for (var j = 0; j < (i32\)len(arr2d, 0); ++j) { 74 | // for (var i = 0; i < (i32\)len(arr2d, 1); ++i) { 75 | // print_i32(arr2d[j, i]); 76 | // if (i != 3) { 77 | // print_string(", "); 78 | // } 79 | // } 80 | // print_string("\n"); 81 | // } 82 | 83 | // var x: i32[5]; 84 | // for (var idx = 0; idx < (i32\)len(x); ++idx) { 85 | // x[idx] = idx + 1; 86 | // } 87 | // print_array(&x[0], (i32\)len(x)); 88 | // print_string("\n"); 89 | 90 | // var xs = i32[]{ (i32\)len(x), &x[0] }; 91 | // print_int_slice(xs); 92 | 93 | // // TODO(pragma): fix this 94 | // // print_int_slice(i32[]{ (i32\)len(x), &x[0] }); 95 | // print_string("\n"); 96 | 97 | // var y: i32[3, 7]; 98 | // debug_print_i32("ly0: ", (i32\)len(y, 0)); 99 | // debug_print_i32("ly0: ", (i32\)len(y, 1)); 100 | // for (var idx = 0; idx < (i32\)len(y); ++idx) { 101 | // y[idx] = idx; 102 | // } 103 | 104 | // debug_print_i32("len_y: ", (i32\)len(y)); 105 | // print_i32(y[2, 6]); 106 | // print_string("\n"); 107 | 108 | // var m = matrix {}; 109 | // var mp = &m.e[0]; 110 | // var idx = 0; 111 | // while (mp <\ &m.e[0] + (i32\)len(m.e)) { 112 | // *(mp++) = idx++; 113 | // } 114 | 115 | // print_matrix(&m); 116 | // print_string("\nhello world\n"); 117 | } 118 | 119 | -------------------------------------------------------------------------------- /publish/current/samples/vec_simd.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | import "math.prag" 3 | import "simd.prag" 4 | 5 | let v3_4x = struct 6 | ( 7 | x: f32_4x; 8 | y: f32_4x; 9 | z: f32_4x; 10 | ); 11 | 12 | let v3 = fun (x: f32_4x; y: f32_4x; z: f32_4x) => v3_4x { 13 | var result = v3_4x { x, y, z}; 14 | return result; 15 | } 16 | 17 | var vz_4 = v3_4x { f32_4x { 0.0, 0.0, 0.0, 0.0 } , f32_4x { 0.0, 0.0, 0.0, 0.0 }, f32_4x { 0.0, 0.0, 0.0, 0.0 }}; 18 | let add = fun (a: v3_4x*; b: v3_4x*) => v3_4x { 19 | var result = v3_4x { a.x + b.x, a.y + b.y, a.z + b.z}; 20 | return result; 21 | } 22 | let add = fun (a: v3_4x; b: v3_4x) => v3_4x { 23 | var result = v3_4x { a.x + b.x, a.y + b.y, a.z + b.z}; 24 | return result; 25 | } 26 | let sub = fun (a: v3_4x*; b: v3_4x*) => v3_4x { 27 | var result = v3_4x { a.x - b.x, a.y - b.y, a.z - b.z}; 28 | return result; 29 | } 30 | let sub = fun (a: v3_4x; b: v3_4x) => v3_4x { 31 | var result = v3_4x { a.x - b.x, a.y - b.y, a.z - b.z}; 32 | return result; 33 | } 34 | let scaled = fun (a: v3_4x*; s: f32_4x) => v3_4x { 35 | var result = v3_4x { a.x * s, a.y * s, a.z * s}; 36 | return result; 37 | } 38 | let scaled = fun (a: v3_4x; s: f32_4x) => v3_4x { 39 | var result = v3_4x { a.x * s, a.y * s, a.z * s}; 40 | return result; 41 | } 42 | let hadamard = fun (a: v3_4x*; b: v3_4x*) => v3_4x { 43 | var result = v3_4x { a.x * b.x, a.y * b.y, a.z * b.z}; 44 | return result; 45 | } 46 | let hadamard = fun (a: v3_4x; b: v3_4x) => v3_4x { 47 | var result = v3_4x { a.x * b.x, a.y * b.y, a.z * b.z}; 48 | return result; 49 | } 50 | let normalize = fun (@a: v3_4x*) => void { 51 | var sqrs = x*x + y*y + z*z; 52 | var scl = f32_4x { 53 | 1.0 / Math::sqrt(sqrs[0]), 54 | 1.0 / Math::sqrt(sqrs[1]), 55 | 1.0 / Math::sqrt(sqrs[2]), 56 | 1.0 / Math::sqrt(sqrs[3]) 57 | }; 58 | x *= scl; 59 | y *= scl; 60 | z *= scl; 61 | } 62 | let normalized = fun (v: v3_4x*) => v3_4x { 63 | var result = *v; 64 | normalize(&result); 65 | return result; 66 | } 67 | let normalized = fun (v: v3_4x) => v3_4x { 68 | var result = v; 69 | normalize(&result); 70 | return result; 71 | } 72 | let length = fun(@a: v3_4x*) => f32_4x { 73 | var sqrs = x*x + y*y + z*z; 74 | var result = f32_4x { 75 | Math::sqrt(sqrs[0]), 76 | Math::sqrt(sqrs[1]), 77 | Math::sqrt(sqrs[2]), 78 | Math::sqrt(sqrs[3]) 79 | }; 80 | return result; 81 | } 82 | let length = fun(@a: v3_4x) => f32_4x { 83 | var sqrs = x*x + y*y + z*z; 84 | var result = f32_4x { 85 | Math::sqrt(sqrs[0]), 86 | Math::sqrt(sqrs[1]), 87 | Math::sqrt(sqrs[2]), 88 | Math::sqrt(sqrs[3]) 89 | }; 90 | return result; 91 | } 92 | let sqr_length = fun(@a: v3_4x*) => f32_4x { 93 | var result = x*x + y*y + z*z; 94 | return result; 95 | } 96 | let sqr_length = fun(@a: v3_4x) => f32_4x { 97 | var result = x*x + y*y + z*z; 98 | return result; 99 | } 100 | let dot = fun (a: v3_4x*; b: v3_4x*) => f32_4x { 101 | var result = a.x*b.x + a.y*b.y + a.z*b.z; 102 | return result; 103 | } 104 | let dot = fun (a: v3_4x; b: v3_4x) => f32_4x { 105 | var result = a.x*b.x + a.y*b.y + a.z*b.z; 106 | return result; 107 | } 108 | let cross = fun (a: v3_4x*; b: v3_4x*) => v3_4x { 109 | var result = v3_4x 110 | { 111 | a.y * b.z - a.z * b.y, 112 | a.z * b.x - a.x * b.z, 113 | a.x * b.y - a.y * b.x 114 | }; 115 | return result; 116 | } 117 | let cross = fun (a: v3_4x; b: v3_4x) => v3_4x { 118 | var result = v3_4x 119 | { 120 | a.y * b.z - a.z * b.y, 121 | a.z * b.x - a.x * b.z, 122 | a.x * b.y - a.y * b.x 123 | }; 124 | return result; 125 | } 126 | let get_orthogonal = fun (v: v3_4x*) => v3_4x { 127 | var c0 = v3_4x { 128 | SIMD::set1_ps(1.0), 129 | SIMD::set1_ps(0.0), 130 | SIMD::set1_ps(0.0) 131 | }; 132 | var c1 = v3_4x { 133 | SIMD::set1_ps(0.0), 134 | SIMD::set1_ps(1.0), 135 | SIMD::set1_ps(0.0) 136 | }; 137 | var result = cross(v, &c0); 138 | // if (sqr_length(&result) < 0.0001) { 139 | // result = cross(v, &c1); 140 | // } 141 | return result; 142 | } 143 | let get_orthogonal = fun (v: v3_4x) => v3_4x { 144 | var c0 = v3_4x { 145 | SIMD::set1_ps(1.0), 146 | SIMD::set1_ps(0.0), 147 | SIMD::set1_ps(0.0) 148 | }; 149 | var c1 = v3_4x { 150 | SIMD::set1_ps(0.0), 151 | SIMD::set1_ps(1.0), 152 | SIMD::set1_ps(0.0) 153 | }; 154 | 155 | var result0 = cross(v, c0); 156 | var result1 = cross(v, c1); 157 | var l0 = sqr_length(&result0); 158 | 159 | // if (sqr_length(&result) < 0.0001) { 160 | // result = cross(v, c1); 161 | // } 162 | // return result; 163 | return result0; 164 | } 165 | let reflect = fun (v: v3_4x*; n: v3_4x*) => v3_4x { 166 | 167 | var len_b = SIMD::set1_ps(2.0) * dot(v, n); 168 | var b = scaled(n, len_b); 169 | return sub(v, &b); 170 | } 171 | let reflect = fun (v: v3_4x; n: v3_4x) => v3_4x { 172 | var len_b = SIMD::set1_ps(2.0) * dot(v, n); 173 | return sub(v, scaled(n, len_b)); 174 | } 175 | let lerp = fun(a: v3_4x*; b: v3_4x*; t: f32_4x) => v3_4x { 176 | var delta = sub(b, a); 177 | var scaled_delta = scaled(&delta, t); 178 | var result = add(a, &scaled_delta); 179 | return result; 180 | } 181 | let lerp = fun(a: v3_4x; b: v3_4x; t: f32_4x) => v3_4x { 182 | var result = add(a, scaled(sub(b, a), t)); 183 | return result; 184 | } 185 | let swap = fun (a: v3_4x*; b: v3_4x*) => void { 186 | var temp = *a; 187 | *a = *b; 188 | *b = temp; 189 | } 190 | let ray_4 = struct 191 | ( 192 | origin: v3_4x; 193 | direction: v3_4x; 194 | ); 195 | let at = fun(@ray: ray_4*; t: f32_4x) => v3_4x { 196 | var delta = scaled(&direction, t); 197 | return add(&origin, &delta); 198 | } 199 | let debug_print = fun(name: string; value: v3_4x) => void { 200 | print(name); 201 | print(": ("); 202 | print(value.x); 203 | print(", "); 204 | print(value.y); 205 | print(", "); 206 | print(value.z); 207 | print(")\n"); 208 | } -------------------------------------------------------------------------------- /publish/current/samples/vulkan/vulkan.prag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/publish/current/samples/vulkan/vulkan.prag -------------------------------------------------------------------------------- /publish/current/samples/vulkan/vulkan_test.prag: -------------------------------------------------------------------------------- 1 | import "../preamble.prag" 2 | import "../windows.prag" 3 | 4 | let window_state = struct 5 | ( 6 | handle: mm; 7 | dc: mm; 8 | client_width: i32; 9 | client_height: i32; 10 | wants_to_quit: bool; 11 | ); 12 | var window: window_state; 13 | let get_perf_counter = fun() => i64 { 14 | var result: i64; 15 | Windows::QueryPerformanceCounter(&result); 16 | return result; 17 | } 18 | var perf_count_freq: i64; 19 | let get_seconds_elapsed = fun(t0: i64; t1: i64) => f64 { 20 | return (t1 - t0)@f64 / perf_count_freq@f64; 21 | } 22 | let get_ms_elapsed = fun(t0: i64; t1: i64) => f64 { 23 | return get_seconds_elapsed(t0, t1) * 1000; 24 | } 25 | 26 | let PROCESS_SYSTEM_DPI_AWARE = 1; 27 | let SetProcessDpiAwareness = extern fun( 28 | value: i32; 29 | ) => i32; 30 | 31 | let main_window_callback = fun 32 | ( 33 | window_handle: mm; 34 | message: i32; 35 | w_param: mm; 36 | l_param: mm; 37 | ) => mm { 38 | var result = null; 39 | if (message == Windows::WM_SIZE || message == Windows::WM_SIZING) { 40 | } 41 | elif (message == Windows::WM_CLOSE) { 42 | window.wants_to_quit = true; 43 | } 44 | elif (message == Windows::WM_DESTROY) { 45 | window.wants_to_quit = true; 46 | } 47 | elif (message == Windows::WM_PAINT) { 48 | var paint: Windows::PAINTSTRUCT; 49 | var context = Windows::BeginPaint(window_handle, &paint); 50 | // blit_to_screen(window.dc, &window.backbuffer); 51 | Windows::EndPaint(window_handle, &paint); 52 | } 53 | else { 54 | result = Windows::DefWindowProcA(window_handle, message, w_param, l_param); 55 | } 56 | return result; 57 | } 58 | 59 | let process_pending_messages = fun() => void { 60 | var msg: Windows::MSG; 61 | while (Windows::PeekMessageA(&msg, null, 0, 0, Windows::PM_REMOVE|Windows::PM_NOYIELD) != 0) { 62 | var message = msg.message; 63 | if (message == Windows::WM_QUIT) { 64 | window.wants_to_quit = true; 65 | } 66 | elif (message == Windows::WM_SYSKEYDOWN 67 | || message == Windows::WM_SYSKEYUP 68 | || message == Windows::WM_KEYDOWN 69 | || message == Windows::WM_KEYUP) { 70 | 71 | var w_param = @i32 (msg.wParam >> 32@mm); 72 | var l_param = @i32 (msg.lParam >> 32@mm); 73 | var vk_code = w_param; 74 | 75 | var was_down = (l_param & (1 << 30)) != 0; 76 | var is_down = (l_param & (1 << 31)) == 0; 77 | var key_up = was_down && !is_down; 78 | var key_down = !was_down && is_down; 79 | 80 | if(vk_code == Windows::VK_ESCAPE) { 81 | window.wants_to_quit = true; 82 | } 83 | } else { 84 | Windows::TranslateMessage(&msg); 85 | Windows::DispatchMessageA(&msg); 86 | } 87 | } 88 | } 89 | 90 | 91 | let render = fun(window: window_state*; time: f32) => void { 92 | 93 | } 94 | 95 | 96 | [ 97 | "compile.entry", 98 | "compile.output": "vulkan_test.exe", 99 | "compile.debuginfo": "true", 100 | "compile.ll" : "false", 101 | "compile.asm" : "false", 102 | "compile.opt" : "0", 103 | "compile.cpu" : "native", 104 | "compile.run" : "true", 105 | "compile.libs" : "kernel32.lib, libopenlibm.a, user32.lib, shcore.lib" 106 | ] 107 | let main = fun () => void { 108 | print("Hello, Vulkan!"); 109 | 110 | Windows::QueryPerformanceFrequency(&perf_count_freq); 111 | SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE); 112 | 113 | let buffer_width = 1280; 114 | let buffer_height = 720; 115 | 116 | var client_rect = Windows::RECT { 0, 0, buffer_width, buffer_height }; 117 | Windows::AdjustWindowRectEx(&client_rect, dw_style, 0, dw_ex_style); 118 | 119 | var window_width = client_rect.right - client_rect.left; 120 | assert(window_width > 0); 121 | var window_height = client_rect.bottom - client_rect.top; 122 | assert(window_height > 0); 123 | window.client_width = buffer_width; 124 | window.client_height = buffer_height; 125 | 126 | var class_name = cstr("vulkan_test_window_class\0"); 127 | var window_name = cstr("vulkan test\0"); 128 | var module_handle = Windows::GetModuleHandleA(null); 129 | var window_class = Windows::WNDCLASSEX {}; 130 | window_class.cbSize = size_of(Windows::WNDCLASSEX)@i32; 131 | window_class.style = Windows::CS_HREDRAW|Windows::CS_VREDRAW; 132 | window_class.lpfnWndProc = @ptr main_window_callback; 133 | window_class.hInstance = module_handle; 134 | window_class.lpszClassName = class_name; 135 | window_class.hCursor = Windows::LoadCursorA(null, Windows::IDC_ARROW); 136 | Windows::RegisterClassExA(&window_class); 137 | 138 | 139 | let dw_style = Windows::WS_OVERLAPPED | Windows::WS_CAPTION | Windows::WS_SYSMENU | Windows::WS_MINIMIZEBOX | Windows::WS_VISIBLE; 140 | let dw_ex_style = 0 & Windows::WS_EX_TOPMOST; 141 | 142 | window.handle = Windows::CreateWindowExA( 143 | dw_ex_style, 144 | class_name, 145 | window_name, 146 | dw_style, 147 | Windows::CW_USEDEFAULT, 148 | Windows::CW_USEDEFAULT, 149 | window_width, 150 | window_height, 151 | null, 152 | null, 153 | module_handle, 154 | null 155 | ); 156 | window.dc = Windows::GetDC(window.handle); 157 | 158 | var start_time = get_perf_counter(); 159 | var frames = 0; 160 | while (!window.wants_to_quit) { 161 | process_pending_messages(); 162 | var t0 = get_perf_counter(); 163 | var time = get_seconds_elapsed(start_time, t0); 164 | render(&window, @f32 time); 165 | var t1 = get_perf_counter(); 166 | } 167 | Windows::ExitProcess(0); 168 | } 169 | -------------------------------------------------------------------------------- /publish/current/samples/work_queue.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | import "windows.prag" 3 | import "random.prag" 4 | import "math.prag" 5 | 6 | let work_queue_callback = fun(queue: work_queue*; data: ptr) => void; 7 | 8 | let work_queue_entry = struct( 9 | callback: work_queue_callback; 10 | data: ptr; 11 | ); 12 | 13 | let work_queue = struct( 14 | ["VOLATILE"] 15 | completion_goal: i32; 16 | ["VOLATILE"] 17 | completion_count: i32; 18 | ["VOLATILE"] 19 | next_entry_to_write: i32; 20 | ["VOLATILE"] 21 | next_entry_to_read: i32; 22 | semaphore_handle: mm; 23 | entries: work_queue_entry[1024]; 24 | ); 25 | 26 | 27 | let add_entry = fun(@queue: work_queue*; data: ptr; callback: work_queue_callback) => void { 28 | var entry = create_work_entry(data, callback); 29 | add_entry(queue, entry); 30 | } 31 | 32 | let add_entry = fun (@queue: work_queue*; entry: work_queue_entry) => void { 33 | var temp_queue = queue; 34 | var target_next_entry_to_write = next_entry_to_write + 1; 35 | if (target_next_entry_to_write >= len(entries)@i32) { 36 | assert(target_next_entry_to_write == len(entries)@i32); 37 | target_next_entry_to_write = 0; 38 | } 39 | assert(target_next_entry_to_write != next_entry_to_read); 40 | entries[next_entry_to_write] = entry; 41 | queue.completion_goal += 1; 42 | 43 | _WriteBarrier(); 44 | 45 | queue.next_entry_to_write = target_next_entry_to_write; 46 | Windows::ReleaseSemaphore(semaphore_handle, 1, 0@i32*); 47 | } 48 | 49 | let next_entry = fun(@queue: work_queue*) => bool 50 | { 51 | var temp_queue = queue; 52 | var should_sleep = false; 53 | var original_next_entry_to_read = queue.next_entry_to_read; 54 | var target_next_entry_to_read = original_next_entry_to_read + 1; 55 | if (target_next_entry_to_read >= len(entries)@i32) { 56 | assert(target_next_entry_to_read == len(entries)@i32); 57 | target_next_entry_to_read = 0; 58 | } 59 | if (original_next_entry_to_read != next_entry_to_write) { 60 | var idx = atomic_compare_and_swap( 61 | &next_entry_to_read, 62 | target_next_entry_to_read, 63 | original_next_entry_to_read 64 | ); 65 | if (idx == original_next_entry_to_read) { 66 | var entry = entries[idx]; 67 | entry.callback(queue, entry.data); 68 | atomic_inc(&queue.completion_count); 69 | } 70 | } else { 71 | should_sleep = true; 72 | } 73 | return should_sleep; 74 | } 75 | 76 | let wait_for_completion = fun(queue: work_queue*) => void { 77 | var temp_queue = queue; 78 | while (queue.completion_goal != queue.completion_count) { 79 | Windows::Sleep(10); 80 | // if (!next_entry(queue)) { 81 | // debug_print("percent", Math::round_to_i32(100.0 * queue.completion_count@f32 / queue.completion_goal@f32)); 82 | // } 83 | } 84 | debug_print("percent", Math::round_to_i32(100.0 * queue.completion_count@f32 / queue.completion_goal@f32)); 85 | } 86 | 87 | let work_queue_thread_proc = fun(data: ptr) => void { 88 | var queue = data@work_queue*; 89 | while (true) { 90 | if (next_entry(queue)) { 91 | Windows::WaitForSingleObject(queue.semaphore_handle, Windows::INFINITE); 92 | } 93 | } 94 | } 95 | 96 | let init_work_queue = fun(queue: work_queue*; worker_count: i32) => void { 97 | var temp_queue = queue; 98 | queue.completion_goal = 0; 99 | queue.completion_count = 0; 100 | queue.next_entry_to_write = 0; 101 | queue.next_entry_to_read = 0; 102 | var initial_count = 0; 103 | queue.semaphore_handle = Windows::CreateSemaphoreA(nullptr, initial_count, worker_count + 1, nullptr); 104 | for (var worker_idx = 0; worker_idx < worker_count; ++worker_idx) { 105 | var handle = Windows::CreateThread(nullptr, 0, work_queue_thread_proc@Windows::ThreadProc, queue@ptr, 0, 0@mm*); 106 | Windows::CloseHandle(handle); 107 | } 108 | } 109 | 110 | let create_work_entry = fun(data: ptr; callback: work_queue_callback) => work_queue_entry 111 | { 112 | var result = work_queue_entry {}; 113 | result.data = data; 114 | result.callback = callback; 115 | return result; 116 | } 117 | 118 | 119 | let test_sleep_rnd = fun(queue: work_queue*; data: ptr) => void { 120 | var temp_queue = queue; 121 | var state: Random::state; 122 | var seed = data@i32; 123 | debug_print("seed", seed); 124 | 125 | Random::init_seed(i32_4x{ seed, seed^3023141, seed^82318, seed^113 }, &state); 126 | var ms = Random::rand_i32(&state) % 5000; 127 | debug_print("sleeping for [ms]", ms); 128 | Windows::Sleep(ms); 129 | } 130 | 131 | 132 | #if false 133 | [ 134 | "compile.output": "test_work_queue.exe", 135 | "compile.debuginfo": "true", 136 | "compile.entry" : "true", 137 | "compile.ll" : "true", 138 | "compile.asm" : "false", 139 | "compile.opt" : "0", 140 | "compile.run" : "false", 141 | "compile.libs" : "kernel32.lib" 142 | ] 143 | let main = fun () => void { 144 | var queue = work_queue { }; 145 | init_work_queue(&queue, 8); 146 | 147 | for (var work_idx = 0; work_idx < 12; ++work_idx) { 148 | add_entry(&queue, (work_idx + 1)@ptr, test_sleep_rnd@work_queue_callback); 149 | } 150 | 151 | wait_for_completion(&queue); 152 | print("exit this thingy.\n"); 153 | Windows::ExitProcess(0); 154 | } 155 | #endif 156 | 157 | 158 | -------------------------------------------------------------------------------- /publish/current/template/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "(Windows) Launch", 6 | "type": "cppvsdbg", 7 | "request": "launch", 8 | "program": "${workspaceRoot}/bin/output.exe", 9 | "args": [], 10 | "stopAtEntry": false, 11 | "cwd": "${workspaceRoot}/bin/", 12 | "environment": [], 13 | "externalConsole": true 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /publish/current/template/main.prag: -------------------------------------------------------------------------------- 1 | import "system/preamble.prag" 2 | 3 | 4 | [ 5 | "compile.entry", 6 | "compile.run":"false", 7 | "compile.opt": "0", 8 | "compile.debuginfo": "true" 9 | ] 10 | let main = fun () => void { 11 | print("hello, world!\n"); 12 | } 13 | -------------------------------------------------------------------------------- /publish/current/template/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "debug.allowBreakpointsEverywhere": true, 4 | $$includeDir$$ 5 | } -------------------------------------------------------------------------------- /publish/current/template/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 | "label": "build", 8 | "type": "shell", 9 | "windows": { 10 | "command": "pragma" 11 | }, 12 | "linux": { 13 | "command": "pragma" 14 | }, 15 | "group": { 16 | "kind": "build", 17 | "isDefault": true 18 | }, 19 | "args": [ 20 | "build", 21 | "\"${file}\"", 22 | "-d" 23 | ], 24 | "problemMatcher": [ 25 | { 26 | "fileLocation": "absolute", 27 | "pattern": { 28 | "regexp": "error: (.*?) at \\(.*?file \"(.*?)\".*?line (.*?),.*?pos (.*?),", 29 | "message": 1, 30 | "file": 2, 31 | "line": 3, 32 | "column": 4 33 | }, 34 | "severity": "error", 35 | "owner": "pragma", 36 | }, 37 | { 38 | "fileLocation": "absolute", 39 | "pattern": { 40 | "regexp": "(Assertion) failed at: \\(file \"(.*?)\".*?line (.*?),.*?pos (.*?)\\)", 41 | "message": 1, 42 | "file": 2, 43 | "line": 3, 44 | "column": 4 45 | }, 46 | "owner": "pragma", 47 | } 48 | ] 49 | }, 50 | { 51 | "label": "build release", 52 | "type": "shell", 53 | "command": "pragma", 54 | "group": "build", 55 | "args": [ 56 | "build", 57 | "${file}" 58 | ], 59 | "problemMatcher": [ 60 | { 61 | "fileLocation": "absolute", 62 | "pattern": { 63 | "regexp": "error: (.*?) at \\(.*?file \"(.*?)\".*?line (.*?),.*?pos (.*?),", 64 | "message": 1, 65 | "file": 2, 66 | "line": 3, 67 | "column": 4 68 | }, 69 | "applyTo": "allDocuments", 70 | "severity": "error", 71 | "owner": "pragma", 72 | }, 73 | { 74 | "fileLocation": "absolute", 75 | "pattern": { 76 | "regexp": "(Assertion) failed at: \\(file \"(.*?)\".*?line (.*?),.*?pos (.*?)\\)", 77 | "message": 1, 78 | "file": 2, 79 | "line": 3, 80 | "column": 4 81 | }, 82 | "applyTo": "allDocuments", 83 | "owner": "pragma", 84 | } 85 | ] 86 | } 87 | ], 88 | } -------------------------------------------------------------------------------- /src/.vs/PragmaCore/DesignTimeBuild/.dtbcache.v2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/src/.vs/PragmaCore/DesignTimeBuild/.dtbcache.v2 -------------------------------------------------------------------------------- /src/.vs/PragmaCore/project-colors.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "ProjectMap": { 4 | "5c9bbb01-5436-4dbb-bbaa-c6b86fca7b7c": { 5 | "ProjectGuid": "5c9bbb01-5436-4dbb-bbaa-c6b86fca7b7c", 6 | "DisplayName": "PragmaCore", 7 | "ColorIndex": 0 8 | }, 9 | "a2fe74e1-b743-11d0-ae1a-00a0c90fffc3": { 10 | "ProjectGuid": "a2fe74e1-b743-11d0-ae1a-00a0c90fffc3", 11 | "DisplayName": "Miscellaneous Files", 12 | "ColorIndex": -1 13 | }, 14 | "532ba1dd-e201-4ea1-b74f-4633f9fadcc3": { 15 | "ProjectGuid": "532ba1dd-e201-4ea1-b74f-4633f9fadcc3", 16 | "DisplayName": "PragmaCore", 17 | "ColorIndex": 1 18 | } 19 | }, 20 | "NextColorIndex": 2 21 | } -------------------------------------------------------------------------------- /src/.vs/PragmaCore/v17/.futdcache.v1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/src/.vs/PragmaCore/v17/.futdcache.v1 -------------------------------------------------------------------------------- /src/.vs/ProjectSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "CurrentProjectSetting": null 3 | } -------------------------------------------------------------------------------- /src/.vs/VSWorkspaceState.json: -------------------------------------------------------------------------------- 1 | { 2 | "ExpandedNodes": [ 3 | "" 4 | ], 5 | "PreviewInSolutionExplorer": false 6 | } -------------------------------------------------------------------------------- /src/.vs/slnx.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/src/.vs/slnx.sqlite -------------------------------------------------------------------------------- /src/.vs/src/FileContentIndex/2b503f25-0658-48c7-9de3-5564bc78b801.vsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/src/.vs/src/FileContentIndex/2b503f25-0658-48c7-9de3-5564bc78b801.vsidx -------------------------------------------------------------------------------- /src/.vs/src/FileContentIndex/8dd15cf9-c6cf-4b58-a061-bc287799e336.vsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/src/.vs/src/FileContentIndex/8dd15cf9-c6cf-4b58-a061-bc287799e336.vsidx -------------------------------------------------------------------------------- /src/.vs/src/FileContentIndex/e9a7709f-110d-41f2-94d3-46f14184cd56.vsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/src/.vs/src/FileContentIndex/e9a7709f-110d-41f2-94d3-46f14184cd56.vsidx -------------------------------------------------------------------------------- /src/.vs/src/FileContentIndex/f8e6a904-ea51-4967-92f7-57770534f802.vsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/src/.vs/src/FileContentIndex/f8e6a904-ea51-4967-92f7-57770534f802.vsidx -------------------------------------------------------------------------------- /src/.vs/src/FileContentIndex/read.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/src/.vs/src/FileContentIndex/read.lock -------------------------------------------------------------------------------- /src/.vs/src/project-colors.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "ProjectMap": { 4 | "a2fe74e1-b743-11d0-ae1a-00a0c90fffc3": { 5 | "ProjectGuid": "a2fe74e1-b743-11d0-ae1a-00a0c90fffc3", 6 | "DisplayName": "Miscellaneous Files", 7 | "ColorIndex": -1 8 | } 9 | }, 10 | "NextColorIndex": 0 11 | } -------------------------------------------------------------------------------- /src/.vs/src/v17/.wsuo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/src/.vs/src/v17/.wsuo -------------------------------------------------------------------------------- /src/.vs/src/v17/workspaceFileList.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/src/.vs/src/v17/workspaceFileList.bin -------------------------------------------------------------------------------- /src/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to find out which attributes exist for C# debugging 3 | // Use hover for the description of the existing attributes 4 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": ".NET Core Launch (console)", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceRoot}/../publish/current/bin/pragma.dll", 14 | "args": [ 15 | "build" 16 | ], 17 | "cwd": "${workspaceRoot}\\temp", 18 | "justMyCode": false, 19 | // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window 20 | "console": "internalConsole", 21 | "stopAtEntry": false, 22 | "internalConsoleOptions": "openOnSessionStart" 23 | }, 24 | { 25 | "name": ".NET Core Attach", 26 | "type": "coreclr", 27 | "request": "attach", 28 | "processId": "${command:pickProcess}" 29 | } 30 | ] 31 | } -------------------------------------------------------------------------------- /src/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | } -------------------------------------------------------------------------------- /src/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "group": "build", 7 | "command": "dotnet", 8 | "args": [ 9 | "build", 10 | "src.sln", 11 | "-c", 12 | "Debug" 13 | 14 | ], 15 | "problemMatcher": "$msCompile" 16 | }, 17 | { 18 | "command": "python", 19 | "label": "publish", 20 | "args": [ 21 | "publish.py" 22 | ] 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /src/Exceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PragmaScript 4 | { 5 | class InvalidCodePath : Exception 6 | { 7 | public InvalidCodePath() 8 | : base("Program should never get here!") 9 | { } 10 | } 11 | 12 | public class CompilerError : Exception 13 | { 14 | public string message; 15 | public Token token; 16 | public CompilerError(string message, Token t) 17 | : base(String.Format("error: {0} at {1}", message, t)) 18 | { 19 | this.message = message; 20 | this.token = t; 21 | } 22 | } 23 | 24 | public class LexerError : CompilerError 25 | { 26 | public LexerError(string message, Token t) 27 | : base(message, t) 28 | { 29 | } 30 | } 31 | 32 | public class ParserErrorExpected : CompilerError 33 | { 34 | public ParserErrorExpected(string expected, string got, Token t) 35 | : base(string.Format("expected \"{0}\", but got \"{1}\"", expected, got), t) 36 | { 37 | } 38 | } 39 | public class ParserExpectedType : CompilerError 40 | { 41 | public ParserExpectedType(FrontendType expected, FrontendType got, Token t) 42 | : base(string.Format("expected type \"{0}\", but got type \"{1}\"", expected.ToString(), got.ToString()), t) 43 | { 44 | } 45 | } 46 | 47 | public class ParserExpectedArgumentType : CompilerError 48 | { 49 | public ParserExpectedArgumentType(FrontendType expected, FrontendType got, int idx, Token t) 50 | : base(string.Format("function argument {2} has type \"{0}\", but got type \"{1}\"", expected.ToString(), got.ToString(), idx), t) 51 | { 52 | } 53 | } 54 | public class ParserTypeMismatch : CompilerError 55 | { 56 | public ParserTypeMismatch(FrontendType type1, FrontendType type2, Token t) 57 | : base(string.Format("Type mismatch: type {0} is not equal to {1}", type1.ToString(), type2.ToString()), t) 58 | { 59 | } 60 | } 61 | public class ParserVariableTypeMismatch : CompilerError 62 | { 63 | public ParserVariableTypeMismatch(FrontendType varType, FrontendType otherType, Token t) 64 | : base(string.Format("Type of expression does not match variable type: variable type \"{0}\" != expression type {1}", varType.ToString(), otherType.ToString()), t) 65 | { 66 | } 67 | } 68 | 69 | public class UndefinedVariable : CompilerError 70 | { 71 | public UndefinedVariable(string variableName, Token t) 72 | : base(string.Format("undefined variable \"{0}\"", variableName), t) 73 | { 74 | } 75 | } 76 | 77 | public class UndefinedType : CompilerError 78 | { 79 | public UndefinedType(string typeName, Token t) 80 | : base(string.Format("undefined type \"{0}\"", typeName), t) 81 | { 82 | } 83 | } 84 | 85 | public class RedefinedVariable : CompilerError 86 | { 87 | public RedefinedVariable(string variableName, Token t) 88 | : base(string.Format("variable \"{0}\" already defined", variableName), t) 89 | { 90 | } 91 | 92 | } 93 | public class RedefinedFunction : CompilerError 94 | { 95 | public RedefinedFunction(string functionName, Token t) 96 | : base(string.Format("function \"{0}\" already defined", functionName), t) 97 | { 98 | } 99 | 100 | } 101 | public class RedefinedType : CompilerError 102 | { 103 | public RedefinedType(string typeName, Token t) 104 | : base(string.Format("type \"{0}\" already defined", typeName), t) 105 | { 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/Extensions.cs: -------------------------------------------------------------------------------- 1 | namespace PragmaScript 2 | { 3 | public static class Extensions 4 | { 5 | public static char at(this string s, int idx) 6 | { 7 | if (idx >= 0 && idx < s.Length) 8 | { 9 | return s[idx]; 10 | } 11 | else 12 | { 13 | return '\0'; 14 | } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/ParseTreeTransformations.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | 4 | using static PragmaScript.AST; 5 | 6 | namespace PragmaScript 7 | { 8 | class ParseTreeTransformations 9 | { 10 | 11 | public static void Init(AST.ProgramRoot root) 12 | { 13 | fixupParents(null, root); 14 | } 15 | 16 | public static void Desugar(List<(AST.FieldAccess fa, Scope.Module ns)> namespaceAccesses, TypeChecker tc) 17 | { 18 | foreach (var na in namespaceAccesses) 19 | { 20 | Debug.Assert(na.fa.kind == FieldAccess.AccessKind.Namespace); 21 | var result = new VariableReference(na.fa.token, na.ns.scope); 22 | result.variableName = na.fa.fieldName; 23 | tc.ResolveNode(result, tc.GetNodeType(na.fa)); 24 | na.fa.parent.Replace(na.fa, result); 25 | } 26 | } 27 | 28 | public static void Desugar(List embeddings, TypeChecker tc) 29 | { 30 | foreach (var e in embeddings) 31 | { 32 | var ft = tc.GetNodeType(e.scope.function) as FrontendFunctionType; 33 | Debug.Assert(ft != null); 34 | 35 | var ov = e.scope.GetVar(e.variableName, e.token); 36 | Scope.VariableDefinition vd; 37 | if (!ov.IsOverloaded) 38 | { 39 | vd = ov.First; 40 | } 41 | else 42 | { 43 | // TODO(pragma): 44 | throw new System.NotImplementedException(); 45 | } 46 | 47 | var p = ft.parameters[vd.parameterIdx]; 48 | var pt = p.type; 49 | // var pt = tc.GetNodeType(p.typeString); 50 | 51 | var vr = new AST.VariableReference(e.token, e.scope); 52 | vr.variableName = p.name; 53 | tc.ResolveNode(vr, pt); 54 | 55 | var f = new AST.FieldAccess(e.token, e.scope); 56 | f.fieldName = e.variableName; 57 | f.fieldNameToken = e.token; 58 | f.left = vr; 59 | f.parent = e.parent; 60 | f.IsArrow = pt is FrontendPointerType; 61 | f.returnPointer = e.returnPointer; 62 | 63 | 64 | FrontendStructType st; 65 | if (pt is FrontendPointerType fpt) 66 | { 67 | st = fpt.elementType as FrontendStructType; 68 | } 69 | else 70 | { 71 | st = pt as FrontendStructType; 72 | } 73 | var typeRoot = (AST.StructDeclaration)tc.GetTypeRoot(st); 74 | f.IsVolatile = typeRoot.GetField(f.fieldName).isVolatile; 75 | 76 | Debug.Assert(st != null); 77 | tc.ResolveNode(f, st.fields[vd.embeddingIdx].type); 78 | vr.parent = f; 79 | 80 | 81 | e.parent.Replace(e, f); 82 | } 83 | } 84 | 85 | static void fixupParents(Node parent, Node node) 86 | { 87 | node.parent = parent; 88 | foreach (var c in node.GetChilds()) 89 | { 90 | fixupParents(node, c); 91 | } 92 | } 93 | 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/PragmaCore.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma 4 | Exe 5 | 0.1.0.$([System.DateTime]::UtcNow.ToString(mmff)) 6 | 0.0.0.1 7 | $(VersionSuffix) 8 | 0.0.1.0 9 | $(VersionSuffix) 10 | 11 | 12 | 14 | net8.0 15 | linux-x64 16 | win-x64 17 | DISPLAY_TIMINGS 18 | 19 | true 20 | true 21 | 22 | true 23 | true 24 | true 25 | true 26 | 27 | 28 | 29 | true 30 | false 31 | portable 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/Tools.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace PragmaScript 7 | { 8 | internal static class AsyncHelper 9 | { 10 | private static readonly TaskFactory _myTaskFactory = new 11 | TaskFactory(CancellationToken.None, 12 | TaskCreationOptions.None, 13 | TaskContinuationOptions.None, 14 | TaskScheduler.Default); 15 | 16 | public static TResult RunSync(Func> func) 17 | { 18 | return AsyncHelper._myTaskFactory 19 | .StartNew>(func) 20 | .Unwrap() 21 | .GetAwaiter() 22 | .GetResult(); 23 | } 24 | 25 | public static void RunSync(Func func) 26 | { 27 | AsyncHelper._myTaskFactory 28 | .StartNew(func) 29 | .Unwrap() 30 | .GetAwaiter() 31 | .GetResult(); 32 | } 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/postbuild.py: -------------------------------------------------------------------------------- 1 | from shutil import copy 2 | import os 3 | import sys 4 | import platform 5 | 6 | 7 | if sys.argv[1] == "-Release": 8 | prefixPath = "bin/Release" 9 | elif sys.argv[1] == "-Debug": 10 | prefixPath = "bin/Debug" 11 | else: 12 | assert False 13 | 14 | 15 | cwd = os.getcwd() 16 | 17 | def nj(*paths): 18 | return os.path.normpath(os.path.join(*paths)) 19 | 20 | if platform.system() == "Windows": 21 | binPath = nj(cwd, prefixPath, "net8.0/win-x64") 22 | elif platform.system() == "Linux": 23 | binPath = nj(cwd, prefixPath, "net8.0/linux-x64") 24 | 25 | publishPath = nj(cwd, "../publish/current/bin") 26 | 27 | for _, _, files in os.walk(binPath): 28 | for f in files: 29 | fp = nj(binPath, f) 30 | copy(fp, publishPath) 31 | break 32 | 33 | -------------------------------------------------------------------------------- /src/publish.py: -------------------------------------------------------------------------------- 1 | from shutil import copy, copytree, rmtree, make_archive, move 2 | from subprocess import call 3 | import os 4 | import time 5 | import sys 6 | 7 | 8 | 9 | cwd = os.getcwd() 10 | 11 | def nj(*paths): 12 | return os.path.normpath(os.path.join(*paths)) 13 | call("dotnet clean -c release") 14 | call("dotnet publish -c release -r win7-x64 /p:PublishSingleFile=true") 15 | binPath = nj(cwd, "bin/Release/netcoreapp3.0/win7-x64/publish") 16 | publishPath = nj(cwd, "../publish/pragma") 17 | 18 | copytree(binPath, nj(publishPath, "bin")) 19 | copytree(nj(cwd, "../publish/current/bin/external"), nj(publishPath, "bin/external")) 20 | 21 | def ignore(path, names): 22 | ignored = [] 23 | for x in names: 24 | xpath = nj(path, x) 25 | if (x == "bin" or x == "obj" or x == "cpp") and (os.path.isdir(xpath)): 26 | ignored.append(x) 27 | return ignored 28 | 29 | copytree(nj(cwd, "../publish/current/samples"), nj(publishPath, "samples"), ignore=ignore) 30 | archive_path = nj(cwd, "../publish", time.strftime("pragma_%Y_%m_%d")) 31 | make_archive(archive_path, "zip", nj(cwd, "../publish"), "pragma") 32 | move(archive_path+".zip", nj(cwd, "../publish/releases",)) 33 | rmtree(publishPath) 34 | -------------------------------------------------------------------------------- /src/src.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PragmaCore", "PragmaCore.csproj", "{D1AAFA2C-A39A-451D-A3DA-5227211D4DD2}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D1AAFA2C-A39A-451D-A3DA-5227211D4DD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {D1AAFA2C-A39A-451D-A3DA-5227211D4DD2}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {D1AAFA2C-A39A-451D-A3DA-5227211D4DD2}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {D1AAFA2C-A39A-451D-A3DA-5227211D4DD2}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {6D828DC4-9FF6-4F7A-B35E-B08D69F06D81} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/temp/main.prag: -------------------------------------------------------------------------------- 1 | import "system/preamble.prag" 2 | [ 3 | "compile.entry", 4 | "compile.run":"true", 5 | "compile.opt": "0", 6 | "compile.debuginfo": "true" 7 | ] 8 | let main = fun () => void { 9 | print("hello, world!\n"); 10 | } 11 | -------------------------------------------------------------------------------- /src/temp/system/linux.prag: -------------------------------------------------------------------------------- 1 | mod Linux 2 | { 3 | ["stub"] 4 | let __write = extern fun(fd: i32; buf: ptr; size: mm) => i64; 5 | 6 | ["stub"] 7 | let __read = extern fun(fd: i32; buf: ptr; size: mm) => i64; 8 | 9 | ["stub"] 10 | let __open = extern fun(filename: i8*; flags: i32; mode: i32) => i32; 11 | 12 | ["stub"] 13 | let __close = extern fun(fd: i32) => i32; 14 | 15 | ["stub"] 16 | let __openat = extern fun(dirfd: i32; filename: i8*; flags: i32; mode: i32) => i32; 17 | 18 | ["stub"] 19 | let __mmap = extern fun(addr: ptr; length: mm; prot: i32; flags: i32; fd: i32; offset: mm) => ptr; 20 | 21 | ["stub"] 22 | let __munmap = extern fun(addr: ptr; length: mm) => i32; 23 | 24 | 25 | // *** Dumping AST Record Layout 26 | // 0 | struct stat 27 | // 0 | __dev_t st_dev 28 | // 8 | __ino_t st_ino 29 | // 16 | __nlink_t st_nlink 30 | // 24 | __mode_t st_mode 31 | // 28 | __uid_t st_uid 32 | // 32 | __gid_t st_gid 33 | // 36 | int __pad0 34 | // 40 | __dev_t st_rdev 35 | // 48 | __off_t st_size 36 | // 56 | __blksize_t st_blksize 37 | // 64 | __blkcnt_t st_blocks 38 | // 72 | struct timespec st_atim 39 | // 72 | __time_t tv_sec 40 | // 80 | __syscall_slong_t tv_nsec 41 | // 88 | struct timespec st_mtim 42 | // 88 | __time_t tv_sec 43 | // 96 | __syscall_slong_t tv_nsec 44 | // 104 | struct timespec st_ctim 45 | // 104 | __time_t tv_sec 46 | // 112 | __syscall_slong_t tv_nsec 47 | // 120 | __syscall_slong_t [3] __glibc_reserved 48 | // | [sizeof=144, dsize=144, align=8, 49 | // | nvsize=144, nvalign=8] 50 | 51 | 52 | let timespec = struct( 53 | tv_sec: i64; 54 | tv_nsec: i64; 55 | ); 56 | 57 | ["packed"] 58 | let stat = struct( 59 | st_dev: i64; 60 | st_ino: i64; 61 | st_nlink: i64; 62 | st_mode: i32; 63 | st_uid: i32; 64 | st_gid: i32; 65 | __pad0: i32; 66 | st_rdev: i64; 67 | st_size: i64; 68 | st_blksize: i64; 69 | st_blocks: i64; 70 | st_atim: timespec; 71 | st_mtim: timespec; 72 | st_ctim: timespec; 73 | reserved: i64[3]; 74 | ); 75 | 76 | ["stub"] 77 | let __fstatat = extern fun(dfd: i32; filename: i8*; statbuf: i8*; flag: i32) => i32; 78 | 79 | let MAP_SHARED = 0x01; 80 | let MAP_PRIVATE = 0x02; 81 | let MAP_TYPE = 0x0F; 82 | let MAP_FIXED = 0x10; 83 | let MAP_ANON = 0x20; 84 | let MAP_ANONYMOUS = MAP_ANON; 85 | let MAP_NORESERVE = 0x4000; 86 | let MAP_GROWSDOWN = 0x0100; 87 | let MAP_DENYWRITE = 0x0800; 88 | let MAP_EXECUTABLE = 0x1000; 89 | let MAP_LOCKED = 0x2000; 90 | let MAP_POPULATE = 0x8000; 91 | let MAP_NONBLOCK = 0x10000; 92 | let MAP_STACK = 0x20000; 93 | let MAP_HUGETLB = 0x40000; 94 | let MAP_FILE = 0; 95 | 96 | let PROT_NONE = 0; 97 | let PROT_READ = 1; 98 | let PROT_WRITE = 2; 99 | let PROT_EXEC = 4; 100 | let PROT_GROWSDOWN = 0x01000000; 101 | let PROT_GROWSUP = 0x02000000; 102 | 103 | let MS_ASYNC = 1; 104 | let MS_INVALIDATE = 2; 105 | let MS_SYNC = 4; 106 | 107 | let MCL_CURRENT = 1; 108 | let MCL_FUTURE = 2; 109 | let MCL_ONFAULT = 4; 110 | 111 | let POSIX_MADV_NORMAL = 0; 112 | let POSIX_MADV_RANDOM = 1; 113 | let POSIX_MADV_SEQUENTIAL = 2; 114 | let POSIX_MADV_WILLNEED = 3; 115 | let POSIX_MADV_DONTNEED = 4; 116 | 117 | let O_ACCMODE = 0x0003; 118 | let O_RDONLY = 0x0000; 119 | let O_WRONLY = 0x0001; 120 | let O_RDWR = 0x0002; 121 | let O_CREAT = 0x0040; 122 | let O_EXCL = 0x0080; 123 | let O_NOCTTY = 0x0100; 124 | let O_TRUNC = 0x0200; 125 | let O_APPEND = 0x0400; 126 | let O_NONBLOCK = 0x0800; 127 | let O_NDELAY = O_NONBLOCK; 128 | let O_SYNC = 0x101000; 129 | let O_FSYNC = O_SYNC; 130 | let O_ASYNC = 0x2000; 131 | let O_LARGEFILE = 0x8000; 132 | 133 | let AT_FDCWD = -100; 134 | 135 | 136 | } -------------------------------------------------------------------------------- /src/temp/system/math.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | // http://openlibm.org/ 3 | mod Math 4 | { 5 | let pi: f64 = 3.1415926535897932384626433832795028841971693993751058209749445923078164062; 6 | let half_pi = pi / 2.0; 7 | let pi_32 = pi@f32; 8 | let half_pi_32 = half_pi@f32; 9 | let tau = 2.0 * pi; 10 | let tau_32 = 2.0 * pi_32; 11 | 12 | ["READNONE"] 13 | let sin = extern("llvm.sin.f32") fun (x: f32) => f32; 14 | ["READNONE"] 15 | let cos = extern("llvm.cos.f32") fun (x: f32) => f32; 16 | ["READNONE"] 17 | let tan = extern("tanf") fun (x: f32) => f32; 18 | ["READNONE"] 19 | let asin = extern("asinf") fun (x: f32) => f32; 20 | ["READNONE"] 21 | let acos = extern("acosf") fun (x: f32) => f32; 22 | ["READNONE"] 23 | let atan = extern("atanf") fun (x: f32) => f32; 24 | ["READNONE"] 25 | let atan2 = extern("atan2f") fun (x: f32) => f32; 26 | ["READNONE"] 27 | let sqrt = extern("llvm.sqrt.f32") fun (x: f32) => f32; 28 | ["READNONE"] 29 | let pow = extern("llvm.pow.f32") fun (x: f32; p: f32) => f32; 30 | ["READNONE"] 31 | let abs = extern("llvm.fabs.f32") fun (x: f32) => f32; 32 | ["READNONE"] 33 | let floor = extern("llvm.floor.f32") fun (x: f32) => f32; 34 | ["READNONE"] 35 | let trunc = extern("llvm.trunc.f32") fun (x: f32) => f32; 36 | ["READNONE"] 37 | let ceil = extern("llvm.ceil.f32") fun (x: f32) => f32; 38 | ["READNONE"] 39 | let round = extern("llvm.round.f32") fun (x: f32) => f32; 40 | ["READNONE"] 41 | let exp = extern("llvm.exp.f32") fun (x: f32) => f32; 42 | ["READNONE"] 43 | let exp2 = extern("llvm.exp2.f32") fun (x: f32) => f32; 44 | ["READNONE"] 45 | let log = extern("llvm.log.f32") fun (x: f32) => f32; 46 | ["READNONE"] 47 | let log2 = extern("llvm.log2.f32") fun (x: f32) => f32; 48 | ["READNONE"] 49 | let log10 = extern("llvm.log10.f32") fun (x: f32) => f32; 50 | 51 | ["READNONE"] 52 | let exp = extern("llvm.exp.f32") fun (x: f32_4x) => f32_4x; 53 | ["READNONE"] 54 | let log = extern("llvm.log.f32") fun (x: f32_4x) => f32_4x; 55 | 56 | 57 | // ["READNONE"] 58 | // let min = extern("llvm.minnum.f32") fun (a: f32; b: f32) => f32; 59 | // ["READNONE"] 60 | // let max = extern("llvm.maxnum.f32") fun (a: f32; b: f32) => f32; 61 | 62 | ["READNONE"] 63 | let min = fun(a: f32; b: f32) => f32 { 64 | if (a < b) { 65 | return a; 66 | } else { 67 | return b; 68 | } 69 | } 70 | 71 | ["READNONE"] 72 | let max = fun(a: f32; b: f32) => f32 { 73 | if (a > b) { 74 | return a; 75 | } else { 76 | return b; 77 | } 78 | } 79 | 80 | ["READNONE"] 81 | let max = fun(a: i32; b: i32) => i32 { 82 | if (a > b) { 83 | return a; 84 | } else { 85 | return b; 86 | } 87 | } 88 | 89 | ["READNONE"] 90 | let min = fun(a: i32; b: i32) => i32 { 91 | if (a < b) { 92 | return a; 93 | } else { 94 | return b; 95 | } 96 | } 97 | 98 | let swap = fun (a: f32*; b: f32*) => void { 99 | var temp = *a; 100 | *a = *b; 101 | *b = temp; 102 | } 103 | 104 | ["READNONE"] 105 | let round_to_i32 = fun (x: f32) => i32 { 106 | return round(x)@i32; 107 | } 108 | ["READNONE"] 109 | let remainder = fun(x: f32; y: f32) => f32 110 | { 111 | return x - floor(x / y) * y; 112 | } 113 | ["READNONE"] 114 | let lerp = fun(a: f32; b: f32; t: f32) => f32 115 | { 116 | return a + (b-a)*t; 117 | } 118 | ["READNONE"] 119 | let abs = fun (value: i32) => i32 120 | { 121 | if (value >= 0) { 122 | return value; 123 | } else { 124 | return -value; 125 | } 126 | } 127 | 128 | ["READNONE"] 129 | let sign = fun (value: f32) => f32 { 130 | if (value > 0) { 131 | return 1.0; 132 | } elif (value < 0) { 133 | return -1.0; 134 | } else { 135 | return 0.0; 136 | } 137 | } 138 | 139 | ["READNONE"] 140 | let clamp = fun 141 | ( 142 | value: i32; 143 | min: i32; 144 | max: i32 145 | ) => i32 146 | { 147 | assert(min <= max); 148 | var result = value; 149 | if (result < min) { 150 | result = min; 151 | } elif (result > max) { 152 | result = max; 153 | } 154 | return result; 155 | } 156 | 157 | ["READNONE"] 158 | let clamp = fun (value: f32; min: f32; max: f32) => f32 159 | { 160 | assert(min <= max); 161 | var result = value; 162 | if (result < min) { 163 | result = min; 164 | } elif (result > max) { 165 | result = max; 166 | } 167 | return result; 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/temp/system/memory.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | 3 | let memory_arena = struct( 4 | size: mm; 5 | base: ptr; 6 | used: mm; 7 | ); 8 | 9 | let align_4 = fun(value: mm) => mm{ 10 | return (value + 3) & (~3); 11 | } 12 | let align_8 = fun(value: mm) => mm { 13 | return (value + 7) & (~7); 14 | } 15 | let align_16 = fun(value: mm) => mm { 16 | return (value + 15) & (~15); 17 | } 18 | 19 | let push = fun(@arena: memory_arena*; push_size: mm) => ptr { 20 | var result = base + used; 21 | // result = align_16(result@mm)@ptr; 22 | 23 | used = result@mm - base@mm + push_size@mm; 24 | 25 | if (used > size) { 26 | assert(false); 27 | return nullptr; 28 | } 29 | return result; 30 | } 31 | 32 | let start_temp = fun(@arena: memory_arena*;) => mm { 33 | return used; 34 | } 35 | 36 | let stop_temp = fun(@arena: memory_arena*; temp_used: mm) => void { 37 | used = temp_used; 38 | } 39 | mod _INTERNAL { 40 | // TODO(pragma): this stuff should be thread local? 41 | var temp_memory_stack_pos: i32; 42 | var temp_memory_stack: mm[32]; 43 | } 44 | 45 | 46 | // TODO(pragma): make this threadsafe 47 | let push_temp = fun(@arena: memory_arena* = &temp_memory_arena) => void { 48 | _INTERNAL::temp_memory_stack[_INTERNAL::temp_memory_stack_pos++] = start_temp(arena); 49 | if (_INTERNAL::temp_memory_stack_pos@mm >= len(_INTERNAL::temp_memory_stack)) { 50 | assert(false, "Exceeded max temp memory stack size!"); 51 | } 52 | } 53 | 54 | // TODO(pragma): make this threadsafe 55 | let pop_temp = fun(@arena: memory_arena* = &temp_memory_arena) => void { 56 | _INTERNAL::temp_memory_stack_pos--; 57 | if (_INTERNAL::temp_memory_stack_pos < 0) { 58 | assert(false, "Inbalanced push_temp pop_temp operations. Stack pos below 0!"); 59 | } 60 | stop_temp(arena, _INTERNAL::temp_memory_stack[_INTERNAL::temp_memory_stack_pos]); 61 | } 62 | 63 | let create_arena = fun(size: mm) => memory_arena { 64 | var data = allocate(size); 65 | var result: memory_arena; 66 | if (data != nullptr) { 67 | result.size = size; 68 | result.base = data; 69 | result.used = 0; 70 | } else { 71 | result.size = 0; 72 | result.base = nullptr; 73 | result.used = 0; 74 | } 75 | return result; 76 | } 77 | 78 | let get_slice = fun(@arena: memory_arena*) => i8[] { 79 | var result = base[:used@i32]; 80 | return result; 81 | } 82 | -------------------------------------------------------------------------------- /src/temp/system/random.prag: -------------------------------------------------------------------------------- 1 | 2 | mod Random 3 | { 4 | let seed0 = 12345; 5 | let seed1 = 33333; 6 | let seed2 = 982845; 7 | let seed3 = 11293929; 8 | 9 | let state = struct 10 | ( 11 | z1: i32_4x; 12 | z2: i32_4x; 13 | z3: i32_4x; 14 | z4: i32_4x; 15 | ); 16 | 17 | // var state: state = state{seed0, seed0, seed0, seed0}; 18 | var state: state = state { 19 | i32_4x {seed0, seed1, seed2, seed3}, 20 | i32_4x {seed0, seed1, seed2, seed3}, 21 | i32_4x {seed0, seed1, seed2, seed3}, 22 | i32_4x {seed0, seed1, seed2, seed3} 23 | }; 24 | 25 | 26 | let init_seed = fun (seed: i32_4x; state: state*) => void { 27 | state.z1 = seed; 28 | state.z2 = seed; 29 | state.z3 = seed; 30 | state.z4 = seed; 31 | } 32 | 33 | let rand_i32_4x = fun (@state: state*) => i32_4x { 34 | let vi_2 = i32_4x { 2, 2, 2, 2 }; 35 | let vi_3 = i32_4x { 3, 3, 3, 3 }; 36 | let vi_6 = i32_4x { 6, 6, 6, 6 }; 37 | let vi_7 = i32_4x { 7, 7, 7, 7 }; 38 | let vi_12 = i32_4x { 12, 12, 12, 12 }; 39 | let vi_13 = i32_4x { 13, 13, 13, 13}; 40 | let vi_18 = i32_4x { 18, 18, 18, 18}; 41 | let vi_21 = i32_4x { 21, 21, 21, 21}; 42 | let vi_27 = i32_4x { 27, 27, 27, 27}; 43 | let vi_m0 = i32_4x { 4294967294, 4294967294, 4294967294, 4294967294 }; 44 | let vi_m1 = i32_4x { 4294967288, 4294967288, 4294967288, 4294967288 }; 45 | let vi_m2 = i32_4x { 4294967280, 4294967280, 4294967280, 4294967280 }; 46 | let vi_m3 = i32_4x { 4294967168, 4294967168, 4294967168, 4294967168 }; 47 | 48 | var b: i32_4x; 49 | b = ((z1 << vi_6) ^ z1) >>\ vi_13; 50 | z1 = ((z1 & vi_m0) << vi_18) ^ b; 51 | b = ((z2 << vi_2) ^ z2) >>\ vi_27; 52 | z2 = ((z2 & vi_m1) << vi_2) ^ b; 53 | b = ((z3 << vi_13) ^ z3) >>\ vi_21; 54 | z3 = ((z3 & vi_m2) << vi_7) ^ b; 55 | b = ((z4 << vi_3) ^ z4) >>\ vi_12; 56 | z4 = ((z4 & vi_m3) << vi_13) ^ b; 57 | return (z1 ^ z2 ^ z3 ^ z4); 58 | } 59 | 60 | let rand_f32_4x = fun(min: f32_4x = f32_4x { 0.0, 0.0, 0.0, 0.0 }; max: f32_4x = f32_4x { 1.0, 1.0, 1.0, 1.0 }; state: state* = &state) => f32_4x { 61 | let div = f32_4x { 4294967295.0, 4294967295.0, 4294967295.0, 4294967295.0 }; 62 | var x = rand_i32_4x(state); 63 | var result = @\f32_4x x / div; 64 | result = min + result * (max - min); 65 | return result; 66 | } 67 | 68 | let rand_i32 = fun(state: state* = &state) => i32 { 69 | var result = rand_i32_4x(state); 70 | return result[0]; 71 | } 72 | 73 | let rand_f32 = fun (min: f32 = 0.0; max: f32 = 1.0; state: state* = &state;) => f32 { 74 | var x = rand_i32(state); 75 | var result = @\f32 x / 4294967295.0; 76 | result = min + result * (max - min); 77 | return result; 78 | } 79 | let rand_xkcd = fun () => i32 { 80 | return 4; // chosen by fair dice roll. 81 | // guaranteed to be random. 82 | } 83 | } -------------------------------------------------------------------------------- /src/temp/system/simd.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | mod SIMD 3 | { 4 | // declare <4 x float> @llvm.x86.sse.max.ps(<4 x float>, <4 x float>) 5 | 6 | let max_ps = extern("llvm.x86.sse.max.ps") fun (a: f32_4x; b: f32_4x) => f32_4x; 7 | let min_ps = extern("llvm.x86.sse.min.ps") fun (a: f32_4x; b: f32_4x) => f32_4x; 8 | 9 | 10 | let set1_ps = fun(v: f32) => f32_4x { 11 | return f32_4x { v, v, v, v }; 12 | } 13 | let set1_epi32 = fun(v: i32) => i32_4x { 14 | return i32_4x {v, v, v, v}; 15 | } 16 | let cvtepi32_ps = fun(v: i32_4x) => f32_4x { 17 | return v@f32_4x; 18 | } 19 | 20 | let rcp_ps = extern("llvm.x86.sse.rcp.ps") fun(v: f32_4x) => f32_4x; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/temp/system/vec_simd.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | import "math.prag" 3 | import "simd.prag" 4 | 5 | let v3_4x = struct 6 | ( 7 | x: f32_4x; 8 | y: f32_4x; 9 | z: f32_4x; 10 | ); 11 | 12 | let v3 = fun (x: f32_4x; y: f32_4x; z: f32_4x) => v3_4x { 13 | var result = v3_4x { x, y, z}; 14 | return result; 15 | } 16 | 17 | var vz_4 = v3_4x { f32_4x { 0.0, 0.0, 0.0, 0.0 } , f32_4x { 0.0, 0.0, 0.0, 0.0 }, f32_4x { 0.0, 0.0, 0.0, 0.0 }}; 18 | let add = fun (a: v3_4x*; b: v3_4x*) => v3_4x { 19 | var result = v3_4x { a.x + b.x, a.y + b.y, a.z + b.z}; 20 | return result; 21 | } 22 | let add = fun (a: v3_4x; b: v3_4x) => v3_4x { 23 | var result = v3_4x { a.x + b.x, a.y + b.y, a.z + b.z}; 24 | return result; 25 | } 26 | let sub = fun (a: v3_4x*; b: v3_4x*) => v3_4x { 27 | var result = v3_4x { a.x - b.x, a.y - b.y, a.z - b.z}; 28 | return result; 29 | } 30 | let sub = fun (a: v3_4x; b: v3_4x) => v3_4x { 31 | var result = v3_4x { a.x - b.x, a.y - b.y, a.z - b.z}; 32 | return result; 33 | } 34 | let scaled = fun (a: v3_4x*; s: f32_4x) => v3_4x { 35 | var result = v3_4x { a.x * s, a.y * s, a.z * s}; 36 | return result; 37 | } 38 | let scaled = fun (a: v3_4x; s: f32_4x) => v3_4x { 39 | var result = v3_4x { a.x * s, a.y * s, a.z * s}; 40 | return result; 41 | } 42 | let hadamard = fun (a: v3_4x*; b: v3_4x*) => v3_4x { 43 | var result = v3_4x { a.x * b.x, a.y * b.y, a.z * b.z}; 44 | return result; 45 | } 46 | let hadamard = fun (a: v3_4x; b: v3_4x) => v3_4x { 47 | var result = v3_4x { a.x * b.x, a.y * b.y, a.z * b.z}; 48 | return result; 49 | } 50 | let normalize = fun (@a: v3_4x*) => void { 51 | var sqrs = x*x + y*y + z*z; 52 | var scl = f32_4x { 53 | 1.0 / Math::sqrt(sqrs[0]), 54 | 1.0 / Math::sqrt(sqrs[1]), 55 | 1.0 / Math::sqrt(sqrs[2]), 56 | 1.0 / Math::sqrt(sqrs[3]) 57 | }; 58 | x *= scl; 59 | y *= scl; 60 | z *= scl; 61 | } 62 | let normalized = fun (v: v3_4x*) => v3_4x { 63 | var result = *v; 64 | normalize(&result); 65 | return result; 66 | } 67 | let normalized = fun (v: v3_4x) => v3_4x { 68 | var result = v; 69 | normalize(&result); 70 | return result; 71 | } 72 | let length = fun(@a: v3_4x*) => f32_4x { 73 | var sqrs = x*x + y*y + z*z; 74 | var result = f32_4x { 75 | Math::sqrt(sqrs[0]), 76 | Math::sqrt(sqrs[1]), 77 | Math::sqrt(sqrs[2]), 78 | Math::sqrt(sqrs[3]) 79 | }; 80 | return result; 81 | } 82 | let length = fun(@a: v3_4x) => f32_4x { 83 | var sqrs = x*x + y*y + z*z; 84 | var result = f32_4x { 85 | Math::sqrt(sqrs[0]), 86 | Math::sqrt(sqrs[1]), 87 | Math::sqrt(sqrs[2]), 88 | Math::sqrt(sqrs[3]) 89 | }; 90 | return result; 91 | } 92 | let sqr_length = fun(@a: v3_4x*) => f32_4x { 93 | var result = x*x + y*y + z*z; 94 | return result; 95 | } 96 | let sqr_length = fun(@a: v3_4x) => f32_4x { 97 | var result = x*x + y*y + z*z; 98 | return result; 99 | } 100 | let dot = fun (a: v3_4x*; b: v3_4x*) => f32_4x { 101 | var result = a.x*b.x + a.y*b.y + a.z*b.z; 102 | return result; 103 | } 104 | let dot = fun (a: v3_4x; b: v3_4x) => f32_4x { 105 | var result = a.x*b.x + a.y*b.y + a.z*b.z; 106 | return result; 107 | } 108 | let cross = fun (a: v3_4x*; b: v3_4x*) => v3_4x { 109 | var result = v3_4x 110 | { 111 | a.y * b.z - a.z * b.y, 112 | a.z * b.x - a.x * b.z, 113 | a.x * b.y - a.y * b.x 114 | }; 115 | return result; 116 | } 117 | let cross = fun (a: v3_4x; b: v3_4x) => v3_4x { 118 | var result = v3_4x 119 | { 120 | a.y * b.z - a.z * b.y, 121 | a.z * b.x - a.x * b.z, 122 | a.x * b.y - a.y * b.x 123 | }; 124 | return result; 125 | } 126 | let get_orthogonal = fun (v: v3_4x*) => v3_4x { 127 | var c0 = v3_4x { 128 | SIMD::set1_ps(1.0), 129 | SIMD::set1_ps(0.0), 130 | SIMD::set1_ps(0.0) 131 | }; 132 | var c1 = v3_4x { 133 | SIMD::set1_ps(0.0), 134 | SIMD::set1_ps(1.0), 135 | SIMD::set1_ps(0.0) 136 | }; 137 | var result = cross(v, &c0); 138 | // if (sqr_length(&result) < 0.0001) { 139 | // result = cross(v, &c1); 140 | // } 141 | return result; 142 | } 143 | let get_orthogonal = fun (v: v3_4x) => v3_4x { 144 | var c0 = v3_4x { 145 | SIMD::set1_ps(1.0), 146 | SIMD::set1_ps(0.0), 147 | SIMD::set1_ps(0.0) 148 | }; 149 | var c1 = v3_4x { 150 | SIMD::set1_ps(0.0), 151 | SIMD::set1_ps(1.0), 152 | SIMD::set1_ps(0.0) 153 | }; 154 | 155 | var result0 = cross(v, c0); 156 | var result1 = cross(v, c1); 157 | var l0 = sqr_length(&result0); 158 | 159 | // if (sqr_length(&result) < 0.0001) { 160 | // result = cross(v, c1); 161 | // } 162 | // return result; 163 | return result0; 164 | } 165 | let reflect = fun (v: v3_4x*; n: v3_4x*) => v3_4x { 166 | 167 | var len_b = SIMD::set1_ps(2.0) * dot(v, n); 168 | var b = scaled(n, len_b); 169 | return sub(v, &b); 170 | } 171 | let reflect = fun (v: v3_4x; n: v3_4x) => v3_4x { 172 | var len_b = SIMD::set1_ps(2.0) * dot(v, n); 173 | return sub(v, scaled(n, len_b)); 174 | } 175 | let lerp = fun(a: v3_4x*; b: v3_4x*; t: f32_4x) => v3_4x { 176 | var delta = sub(b, a); 177 | var scaled_delta = scaled(&delta, t); 178 | var result = add(a, &scaled_delta); 179 | return result; 180 | } 181 | let lerp = fun(a: v3_4x; b: v3_4x; t: f32_4x) => v3_4x { 182 | var result = add(a, scaled(sub(b, a), t)); 183 | return result; 184 | } 185 | let swap = fun (a: v3_4x*; b: v3_4x*) => void { 186 | var temp = *a; 187 | *a = *b; 188 | *b = temp; 189 | } 190 | let ray_4 = struct 191 | ( 192 | origin: v3_4x; 193 | direction: v3_4x; 194 | ); 195 | let at = fun(@ray: ray_4*; t: f32_4x) => v3_4x { 196 | var delta = scaled(&direction, t); 197 | return add(&origin, &delta); 198 | } 199 | let debug_print = fun(name: string; value: v3_4x) => void { 200 | print(name); 201 | print(": ("); 202 | print(value.x); 203 | print(", "); 204 | print(value.y); 205 | print(", "); 206 | print(value.z); 207 | print(")\n"); 208 | } -------------------------------------------------------------------------------- /src/temp/system/work_queue.prag: -------------------------------------------------------------------------------- 1 | import "preamble.prag" 2 | import "windows.prag" 3 | import "random.prag" 4 | import "math.prag" 5 | 6 | let work_queue_callback = fun(queue: work_queue*; data: ptr) => void; 7 | 8 | let work_queue_entry = struct( 9 | callback: work_queue_callback; 10 | data: ptr; 11 | ); 12 | 13 | let work_queue = struct( 14 | ["VOLATILE"] 15 | completion_goal: i32; 16 | ["VOLATILE"] 17 | completion_count: i32; 18 | ["VOLATILE"] 19 | next_entry_to_write: i32; 20 | ["VOLATILE"] 21 | next_entry_to_read: i32; 22 | semaphore_handle: mm; 23 | entries: work_queue_entry[1024]; 24 | ); 25 | 26 | 27 | let add_entry = fun(@queue: work_queue*; data: ptr; callback: work_queue_callback) => void { 28 | var entry = create_work_entry(data, callback); 29 | add_entry(queue, entry); 30 | } 31 | 32 | let add_entry = fun (@queue: work_queue*; entry: work_queue_entry) => void { 33 | var temp_queue = queue; 34 | var target_next_entry_to_write = next_entry_to_write + 1; 35 | if (target_next_entry_to_write >= len(entries)@i32) { 36 | assert(target_next_entry_to_write == len(entries)@i32); 37 | target_next_entry_to_write = 0; 38 | } 39 | assert(target_next_entry_to_write != next_entry_to_read); 40 | entries[next_entry_to_write] = entry; 41 | queue.completion_goal += 1; 42 | 43 | _WriteBarrier(); 44 | 45 | queue.next_entry_to_write = target_next_entry_to_write; 46 | Windows::ReleaseSemaphore(semaphore_handle, 1, 0@i32*); 47 | } 48 | 49 | let next_entry = fun(@queue: work_queue*) => bool 50 | { 51 | var temp_queue = queue; 52 | var should_sleep = false; 53 | var original_next_entry_to_read = queue.next_entry_to_read; 54 | var target_next_entry_to_read = original_next_entry_to_read + 1; 55 | if (target_next_entry_to_read >= len(entries)@i32) { 56 | assert(target_next_entry_to_read == len(entries)@i32); 57 | target_next_entry_to_read = 0; 58 | } 59 | if (original_next_entry_to_read != next_entry_to_write) { 60 | var idx = atomic_compare_and_swap( 61 | &next_entry_to_read, 62 | target_next_entry_to_read, 63 | original_next_entry_to_read 64 | ); 65 | if (idx == original_next_entry_to_read) { 66 | var entry = entries[idx]; 67 | entry.callback(queue, entry.data); 68 | atomic_inc(&queue.completion_count); 69 | } 70 | } else { 71 | should_sleep = true; 72 | } 73 | return should_sleep; 74 | } 75 | 76 | let wait_for_completion = fun(queue: work_queue*) => void { 77 | var temp_queue = queue; 78 | while (queue.completion_goal != queue.completion_count) { 79 | Windows::Sleep(10); 80 | // if (!next_entry(queue)) { 81 | // debug_print("percent", Math::round_to_i32(100.0 * queue.completion_count@f32 / queue.completion_goal@f32)); 82 | // } 83 | } 84 | debug_print("percent", Math::round_to_i32(100.0 * queue.completion_count@f32 / queue.completion_goal@f32)); 85 | } 86 | 87 | let work_queue_thread_proc = fun(data: ptr) => void { 88 | var queue = data@work_queue*; 89 | while (true) { 90 | if (next_entry(queue)) { 91 | Windows::WaitForSingleObject(queue.semaphore_handle, Windows::INFINITE); 92 | } 93 | } 94 | } 95 | 96 | let init_work_queue = fun(queue: work_queue*; worker_count: i32) => void { 97 | var temp_queue = queue; 98 | queue.completion_goal = 0; 99 | queue.completion_count = 0; 100 | queue.next_entry_to_write = 0; 101 | queue.next_entry_to_read = 0; 102 | var initial_count = 0; 103 | queue.semaphore_handle = Windows::CreateSemaphoreA(nullptr, initial_count, worker_count + 1, nullptr); 104 | for (var worker_idx = 0; worker_idx < worker_count; ++worker_idx) { 105 | var handle = Windows::CreateThread(nullptr, 0, work_queue_thread_proc@Windows::ThreadProc, queue@ptr, 0, 0@mm*); 106 | Windows::CloseHandle(handle); 107 | } 108 | } 109 | 110 | let create_work_entry = fun(data: ptr; callback: work_queue_callback) => work_queue_entry 111 | { 112 | var result = work_queue_entry {}; 113 | result.data = data; 114 | result.callback = callback; 115 | return result; 116 | } 117 | 118 | 119 | let test_sleep_rnd = fun(queue: work_queue*; data: ptr) => void { 120 | var temp_queue = queue; 121 | var state: Random::state; 122 | var seed = data@i32; 123 | debug_print("seed", seed); 124 | 125 | Random::init_seed(i32_4x{ seed, seed^3023141, seed^82318, seed^113 }, &state); 126 | var ms = Random::rand_i32(&state) % 5000; 127 | debug_print("sleeping for [ms]", ms); 128 | Windows::Sleep(ms); 129 | } 130 | 131 | 132 | #if false 133 | [ 134 | "compile.output": "test_work_queue.exe", 135 | "compile.debuginfo": "true", 136 | "compile.entry" : "true", 137 | "compile.ll" : "true", 138 | "compile.asm" : "false", 139 | "compile.opt" : "0", 140 | "compile.run" : "false", 141 | "compile.libs" : "kernel32.lib" 142 | ] 143 | let main = fun () => void { 144 | var queue = work_queue { }; 145 | init_work_queue(&queue, 8); 146 | 147 | for (var work_idx = 0; work_idx < 12; ++work_idx) { 148 | add_entry(&queue, (work_idx + 1)@ptr, test_sleep_rnd@work_queue_callback); 149 | } 150 | 151 | wait_for_completion(&queue); 152 | print("exit this thingy.\n"); 153 | Windows::ExitProcess(0); 154 | } 155 | #endif 156 | 157 | 158 | -------------------------------------------------------------------------------- /src/todo.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | single threaded memory fence 4 | 5 | https://github.com/tari/rust/commit/0edbf2c9687b58f95783f7f0cde6370837d9fad3 6 | 7 | 8 | 9 | https://github.com/vsajip/llvm/blob/master/test/CodeGen/X86/sse-intrinsics-x86.ll 10 | 11 | 12 | https://msdn.microsoft.com/library/5c53b4f8-6ff5-47d7-beb2-2d6ee3c6ea89.aspx#atomic_thread_fence_function 13 | 14 | https://peeterjoot.wordpress.com/2009/12/04/intel-memory-ordering-fence-instructions-and-atomic-operations/ 15 | 16 | https://assets.bitbashing.io/papers/lockless.pdf 17 | 18 | https://poshtools.com/2017/11/22/the-future-of-languages-in-visual-studio/ 19 | 20 | http://casual-effects.com/markdeep/#api 21 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": [ 9 | "@typescript-eslint" 10 | ], 11 | "rules": { 12 | "@typescript-eslint/naming-convention": "warn", 13 | "@typescript-eslint/semi": "warn", 14 | "curly": "warn", 15 | "eqeqeq": "warn", 16 | "no-throw-literal": "warn", 17 | "semi": "off" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behavior to automatically normalize line endings. 2 | * text=auto 3 | 4 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vscode-test/ 4 | *.vsix 5 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 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 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "args": [ 13 | "--extensionDevelopmentPath=${workspaceFolder}" 14 | ], 15 | "outFiles": [ 16 | "${workspaceFolder}/out/**/*.js" 17 | ], 18 | "preLaunchTask": "${defaultBuildTask}" 19 | }, 20 | { 21 | "name": "Extension Tests", 22 | "type": "extensionHost", 23 | "request": "launch", 24 | "args": [ 25 | "--extensionDevelopmentPath=${workspaceFolder}", 26 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 27 | ], 28 | "outFiles": [ 29 | "${workspaceFolder}/out/test/**/*.js" 30 | ], 31 | "preLaunchTask": "${defaultBuildTask}" 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off" 11 | } -------------------------------------------------------------------------------- /tools/PragmaLangClient/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | src/** 5 | .gitignore 6 | .yarnrc 7 | vsc-extension-quickstart.md 8 | **/tsconfig.json 9 | **/.eslintrc.json 10 | **/*.map 11 | **/*.ts 12 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to the "pragmaclient" extension will be documented in this file. 4 | 5 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. 6 | 7 | ## [Unreleased] 8 | 9 | - Initial release -------------------------------------------------------------------------------- /tools/PragmaLangClient/README.md: -------------------------------------------------------------------------------- 1 | ## pragma-lang language client for VSCode 2 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/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 | // symbols that that can be used to surround a selection 23 | "surroundingPairs": [ 24 | ["{", "}"], 25 | ["[", "]"], 26 | ["(", ")"], 27 | ["\"", "\""], 28 | ["'", "'"] 29 | ] 30 | } -------------------------------------------------------------------------------- /tools/PragmaLangClient/package.bat: -------------------------------------------------------------------------------- 1 | mkdir server 2 | del server\*.* /Q 3 | copy ..\PragmaLangServer\bin\%1\net8.0\win-x64\publish\*.* server\ 4 | vsce package -------------------------------------------------------------------------------- /tools/PragmaLangClient/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pragmalangclient", 3 | "displayName": "PragmaLangClient", 4 | "description": "Client for pragma language server", 5 | "publisher": "pragmascript", 6 | "version": "0.0.1", 7 | "private": true, 8 | "repository": { 9 | "type": "git", 10 | "url": "git://github.com/pragmascript/PragmaScript.git" 11 | }, 12 | "engines": { 13 | "vscode": "^1.50.0" 14 | }, 15 | "categories": [ 16 | "Programming Languages" 17 | ], 18 | "activationEvents": [ 19 | "onCommand:pragmalangclient.helloWorld", 20 | "onLanguage:pragma" 21 | ], 22 | "main": "./out/extension.js", 23 | "contributes": { 24 | "languages": [{ 25 | "id": "pragma", 26 | "aliases": [ 27 | "pragma", 28 | "PragmaScript", 29 | "Pragma" 30 | ], 31 | "extensions": [ 32 | ".prag" 33 | ], 34 | "configuration": "./language-configuration.json" 35 | }], 36 | "grammars": [{ 37 | "language": "pragma", 38 | "scopeName": "source.pragma", 39 | "path": "./syntaxes/pragma.tmLanguage.json" 40 | }], 41 | "commands": [{ 42 | "command": "pragmalangclient.helloWorld", 43 | "title": "Hello World" 44 | }], 45 | "configuration": [{ 46 | "title": "pragma", 47 | "properties": { 48 | "pragma.includeDirectory": { 49 | "type": "string", 50 | "description": "directory pragma uses to search for include files. This is typically \"[pragma_install_dir]\\include\"" 51 | } 52 | } 53 | }] 54 | }, 55 | "scripts": { 56 | "vscode:prepublish": "npm run compile", 57 | "compile": "tsc -p ./", 58 | "lint": "eslint src --ext ts", 59 | "watch": "tsc -watch -p ./", 60 | "pretest": "npm run compile && npm run lint", 61 | "test": "node ./out/test/runTest.js" 62 | }, 63 | "devDependencies": { 64 | "@types/glob": "^7.1.3", 65 | "@types/mocha": "^8.0.0", 66 | "@types/node": "^12.11.7", 67 | "@types/vscode": "^1.50.0", 68 | "@typescript-eslint/eslint-plugin": "^4.1.1", 69 | "@typescript-eslint/parser": "^4.1.1", 70 | "eslint": "^7.9.0", 71 | "glob": "^7.1.6", 72 | "mocha": "^10.1.0", 73 | "typescript": "^4.0.2", 74 | "vscode-test": "^1.4.0" 75 | }, 76 | "dependencies": { 77 | "vscode-languageclient": "^8.1.0" 78 | } 79 | } -------------------------------------------------------------------------------- /tools/PragmaLangClient/server/PragmaLangServer.runtimeconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeOptions": { 3 | "tfm": "net8.0", 4 | "framework": { 5 | "name": "Microsoft.NETCore.App", 6 | "version": "8.0.0" 7 | }, 8 | "configProperties": { 9 | "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, 10 | "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /tools/PragmaLangClient/src/extension.ts: -------------------------------------------------------------------------------- 1 | // The module 'vscode' contains the VS Code extensibility API 2 | // Import the module and reference it with the alias vscode in your code below 3 | import * as path from 'path'; 4 | import * as vscode from 'vscode'; 5 | 6 | import { 7 | LanguageClient, 8 | LanguageClientOptions, 9 | ServerOptions 10 | } from 'vscode-languageclient'; 11 | 12 | let client: LanguageClient; 13 | 14 | // this method is called when your extension is activated 15 | // your extension is activated the very first time the command is executed 16 | export function activate(context: vscode.ExtensionContext) { 17 | let basePath = context.asAbsolutePath(""); 18 | console.log(`basepath: ${basePath}`) 19 | 20 | let serverPath = path.join(basePath, "server/PragmaLangServer") 21 | 22 | console.log(`serverPath: ${serverPath}`) 23 | 24 | let serverOptions: ServerOptions = { 25 | run: { command: serverPath }, 26 | debug: { command: serverPath } 27 | }; 28 | 29 | let clientOptions: LanguageClientOptions = { 30 | documentSelector: [ 31 | { 32 | pattern: "**/*.prag", 33 | } 34 | ], 35 | synchronize: { 36 | // Notify the server about file changes to '.prag files contained in the workspace 37 | fileEvents: vscode.workspace.createFileSystemWatcher('**/.prag') 38 | }, 39 | } 40 | 41 | client = new LanguageClient("PragmaLanguageClient", serverOptions, clientOptions); 42 | client.start(); 43 | 44 | // The command has been defined in the package.json file 45 | // Now provide the implementation of the command with registerCommand 46 | // The commandId parameter must match the command field in package.json 47 | let disposable = vscode.commands.registerCommand('pragmaclient.helloWorld', () => { 48 | // The code you place here will be executed every time your command is executed 49 | 50 | // Display a message box to the user 51 | vscode.window.showInformationMessage('Hello World from PragmaClient!'); 52 | }); 53 | 54 | context.subscriptions.push(disposable); 55 | } 56 | 57 | // this method is called when your extension is deactivated 58 | export function deactivate() { } 59 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/src/test/runTest.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | 3 | import { runTests } from 'vscode-test'; 4 | 5 | async function main() { 6 | try { 7 | // The folder containing the Extension Manifest package.json 8 | // Passed to `--extensionDevelopmentPath` 9 | const extensionDevelopmentPath = path.resolve(__dirname, '../../'); 10 | 11 | // The path to test runner 12 | // Passed to --extensionTestsPath 13 | const extensionTestsPath = path.resolve(__dirname, './suite/index'); 14 | 15 | // Download VS Code, unzip it and run the integration test 16 | await runTests({ extensionDevelopmentPath, extensionTestsPath }); 17 | } catch (err) { 18 | console.error('Failed to run tests'); 19 | process.exit(1); 20 | } 21 | } 22 | 23 | main(); 24 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/src/test/suite/extension.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | 3 | // You can import and use all API from the 'vscode' module 4 | // as well as import your extension to test it 5 | import * as vscode from 'vscode'; 6 | // import * as myExtension from '../../extension'; 7 | 8 | suite('Extension Test Suite', () => { 9 | vscode.window.showInformationMessage('Start all tests.'); 10 | 11 | test('Sample test', () => { 12 | assert.equal(-1, [1, 2, 3].indexOf(5)); 13 | assert.equal(-1, [1, 2, 3].indexOf(0)); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/src/test/suite/index.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import * as Mocha from 'mocha'; 3 | import * as glob from 'glob'; 4 | 5 | export function run(): Promise { 6 | // Create the mocha test 7 | const mocha = new Mocha({ 8 | ui: 'tdd', 9 | color: true 10 | }); 11 | 12 | const testsRoot = path.resolve(__dirname, '..'); 13 | 14 | return new Promise((c, e) => { 15 | glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { 16 | if (err) { 17 | return e(err); 18 | } 19 | 20 | // Add files to the test suite 21 | files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); 22 | 23 | try { 24 | // Run the mocha test 25 | mocha.run(failures => { 26 | if (failures > 0) { 27 | e(new Error(`${failures} tests failed.`)); 28 | } else { 29 | c(); 30 | } 31 | }); 32 | } catch (err) { 33 | console.error(err); 34 | e(err); 35 | } 36 | }); 37 | }); 38 | } 39 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/syntaxes/pragma.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", 3 | "name": "pragma", 4 | "patterns": [ 5 | { 6 | "include": "#keywords" 7 | }, 8 | { 9 | "include": "#strings" 10 | }, 11 | { 12 | "include": "#storage-modifier" 13 | }, 14 | { 15 | "include": "#comments" 16 | }, 17 | { 18 | "include": "#boolean-literal" 19 | }, 20 | { 21 | "include": "#invocation-expression" 22 | } 23 | ], 24 | "repository": { 25 | "keywords": { 26 | "patterns": [ 27 | { 28 | "name": "keyword.control.pragma", 29 | "match": "\\b(if|elif|else|for|while|break|continue)\\b" 30 | }, 31 | { 32 | "name": "keyword.other.pragma", 33 | "match": "\\b(let|var|enum|fun|return|size_of|import|mod|with)\\b" 34 | }, 35 | { 36 | "name": "keyword.other.struct.pragma", 37 | "match": "\\b(struct)\\b" 38 | } 39 | ] 40 | }, 41 | "strings": { 42 | "name": "string.quoted.double.pragma", 43 | "begin": "\"", 44 | "end": "\"", 45 | "patterns": [ 46 | { 47 | "name": "constant.character.escape.pragma", 48 | "match": "\\\\." 49 | } 50 | ] 51 | }, 52 | "comments": { 53 | "name": "comment.line.pragma", 54 | "match": "(//).*$\n?" 55 | }, 56 | "storage-modifier": { 57 | "name": "storage.modifier.pragma", 58 | "match": "\\b(extern)\\b" 59 | }, 60 | "boolean-literal": { 61 | "patterns": [ 62 | { 63 | "name": "constant.language.boolean.true.pragma", 64 | "match": "\\b(true)\\b" 65 | }, 66 | { 67 | "name": "constant.language.boolean.false.pragma", 68 | "match": "\\b(false)\\b" 69 | } 70 | ] 71 | } 72 | }, 73 | "scopeName": "source.pragma" 74 | } -------------------------------------------------------------------------------- /tools/PragmaLangClient/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "src", 11 | "strict": true /* enable all strict type-checking options */ 12 | /* Additional Checks */ 13 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 14 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 15 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 16 | }, 17 | "exclude": [ 18 | "node_modules", 19 | ".vscode-test" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tools/PragmaLangClient/vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your VS Code Extension 2 | 3 | ## What's in the folder 4 | 5 | * This folder contains all of the files necessary for your extension. 6 | * `package.json` - this is the manifest file in which you declare your extension and command. 7 | * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `src/extension.ts` - this is the main file where you will provide the implementation of your command. 9 | * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 10 | * We pass the function containing the implementation of the command as the second parameter to `registerCommand`. 11 | 12 | ## Get up and running straight away 13 | 14 | * Press `F5` to open a new window with your extension loaded. 15 | * Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. 16 | * Set breakpoints in your code inside `src/extension.ts` to debug your extension. 17 | * Find output from your extension in the debug console. 18 | 19 | ## Make changes 20 | 21 | * You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`. 22 | * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. 23 | 24 | 25 | ## Explore the API 26 | 27 | * You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`. 28 | 29 | ## Run tests 30 | 31 | * Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`. 32 | * Press `F5` to run the tests in a new window with your extension loaded. 33 | * See the output of the test result in the debug console. 34 | * Make changes to `src/test/suite/extension.test.ts` or create new test files inside the `test/suite` folder. 35 | * The provided test runner will only consider files matching the name pattern `**.test.ts`. 36 | * You can create folders inside the `test` folder to structure your tests any way you want. 37 | 38 | ## Go further 39 | 40 | * Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension). 41 | * [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace. 42 | * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration). 43 | -------------------------------------------------------------------------------- /tools/PragmaLangServer/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to find out which attributes exist for C# debugging 3 | // Use hover for the description of the existing attributes 4 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": ".NET Core Launch (console)", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceFolder}/bin/Debug/netcoreapp3.0/LangServer.dll", 14 | "args": [], 15 | "cwd": "${workspaceFolder}", 16 | // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console 17 | "console": "internalConsole", 18 | "stopAtEntry": false 19 | }, 20 | { 21 | "name": ".NET Core Attach", 22 | "type": "coreclr", 23 | "request": "attach", 24 | "processId": "${command:pickProcess}" 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /tools/PragmaLangServer/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug.node.autoAttach": "on" 3 | } -------------------------------------------------------------------------------- /tools/PragmaLangServer/.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 | "label": "build", 8 | "command": "dotnet", 9 | "type": "shell", 10 | "args": [ 11 | "build", 12 | // Ask dotnet build to generate full paths for file names. 13 | "/property:GenerateFullPaths=true", 14 | // Do not generate summary otherwise it leads to duplicate errors in Problems panel 15 | "/consoleloggerparameters:NoSummary" 16 | ], 17 | "group": "build", 18 | "presentation": { 19 | "reveal": "silent" 20 | }, 21 | "problemMatcher": "$msCompile" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /tools/PragmaLangServer/BufferManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | 3 | class BufferManager 4 | { 5 | private ConcurrentDictionary buffers = new ConcurrentDictionary(); 6 | private ConcurrentDictionary scopes = new ConcurrentDictionary(); 7 | 8 | public void UpdateBuffer(string documentPath, string text) 9 | { 10 | buffers.AddOrUpdate(documentPath, text, (k, v) => text); 11 | } 12 | 13 | public string GetBuffer(string documentPath) 14 | { 15 | if (buffers.TryGetValue(documentPath, out var result)) 16 | { 17 | return result; 18 | } 19 | else 20 | { 21 | return null; 22 | } 23 | } 24 | public void Annotate(string documentPath, PragmaScript.Scope rootScope, PragmaScript.TypeChecker tc) 25 | { 26 | scopes.AddOrUpdate(documentPath, (rootScope, tc), (k, v) => (rootScope, tc)); 27 | } 28 | public (PragmaScript.Scope, PragmaScript.TypeChecker tc) GetScope(string documentPath) 29 | { 30 | if (scopes.TryGetValue(documentPath, out var result)) 31 | { 32 | return result; 33 | } 34 | else 35 | { 36 | return (null, null); 37 | } 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /tools/PragmaLangServer/Debugger.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pragmascript/PragmaScript/8b9515bbe18b20770a1ea15eb5d2ecd558c1ede8/tools/PragmaLangServer/Debugger.cs -------------------------------------------------------------------------------- /tools/PragmaLangServer/LanguageHelper.cs: -------------------------------------------------------------------------------- 1 | using PragmaScript; 2 | 3 | public class LanguageHelper 4 | { 5 | public static bool InsideToken(Token token, int pos, int line) 6 | { 7 | // TODO(pragma): we have tokens that span multiple lines. implement. 8 | if (token.Line != line) 9 | { 10 | return false; 11 | } 12 | return pos >= token.Pos && pos < token.Pos + token.length; 13 | } 14 | 15 | public static AST.Node FindNode(Scope scope, int posZeroBased, int lineZeroBased, string filePath) 16 | { 17 | AST.Node FindNodeRec(AST.Node node, int pos, int line) 18 | { 19 | if (node.token.filename != filePath) 20 | { 21 | return null; 22 | } 23 | if (InsideToken(node.token, pos, line)) 24 | { 25 | return node; 26 | } 27 | else 28 | { 29 | if (node is AST.FieldAccess fa) 30 | { 31 | if (InsideToken(fa.fieldNameToken, pos, line)) 32 | { 33 | return node; 34 | } 35 | } 36 | foreach (var child in node.GetChilds()) 37 | { 38 | var result = FindNodeRec(child, pos, line); 39 | if (result != null) 40 | { 41 | return result; 42 | } 43 | } 44 | } 45 | return null; 46 | } 47 | AST.Node result = FindNodeRec(scope.owner, posZeroBased + 1, lineZeroBased + 1); 48 | return result; 49 | } 50 | 51 | public static Scope GetCurrentScope(Scope rootScope, int charIdxZeroBased, int lineIdxZeroBased, string filePath) 52 | { 53 | Scope GetCurrentScopeRec(Scope scope, int charIdx, int lineIdx) 54 | { 55 | var result = scope; 56 | foreach (var c in result.childs) 57 | { 58 | if (c.tokenRanges.Count == 0) 59 | { 60 | continue; 61 | } 62 | bool inside = false; 63 | foreach (var tr in c.tokenRanges) 64 | { 65 | if (tr.start.filename != filePath) 66 | { 67 | continue; 68 | } 69 | inside |= lineIdx > tr.start.Line && lineIdx < tr.end.Line; 70 | if (tr.start.Line == lineIdx) 71 | { 72 | if (tr.end.Line != tr.start.Line) 73 | { 74 | inside |= charIdx >= tr.start.Pos; 75 | } 76 | else 77 | { 78 | inside |= charIdx >= tr.start.Pos && charIdx <= tr.end.Pos; 79 | } 80 | } 81 | } 82 | if (inside) 83 | { 84 | result = GetCurrentScopeRec(c, charIdx, lineIdx); 85 | break; 86 | } 87 | } 88 | return result; 89 | } 90 | var result = GetCurrentScopeRec(rootScope, charIdxZeroBased + 1, lineIdxZeroBased + 1); 91 | return result; 92 | } 93 | } -------------------------------------------------------------------------------- /tools/PragmaLangServer/PragmaLangServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | linux-x64 7 | win-x64 8 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ../../src/bin/Debug/net8.0/linux-x64/pragma.dll 21 | 22 | 23 | ../../src/bin/Debug/net8.0/win-x64/pragma.dll 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tools/PragmaLangServer/PragmaLangServer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PragmaLangServer", "PragmaLangServer.csproj", "{B2A2C5CD-FD0C-4E8C-93EA-6B01C0A5EC5D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B2A2C5CD-FD0C-4E8C-93EA-6B01C0A5EC5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {B2A2C5CD-FD0C-4E8C-93EA-6B01C0A5EC5D}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {B2A2C5CD-FD0C-4E8C-93EA-6B01C0A5EC5D}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {B2A2C5CD-FD0C-4E8C-93EA-6B01C0A5EC5D}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {E0CA7AF3-2ACB-4693-AAFB-1ECBC45A5974} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /tools/PragmaLangServer/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Threading.Tasks; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Logging; 6 | using OmniSharp.Extensions.LanguageServer.Protocol.Models; 7 | using OmniSharp.Extensions.LanguageServer.Server; 8 | 9 | namespace LangServer 10 | { 11 | class Program 12 | { 13 | static async Task Main(string[] args) 14 | { 15 | var server = await LanguageServer.From(options => 16 | options 17 | .WithInput(Console.OpenStandardInput()) 18 | .WithOutput(Console.OpenStandardOutput()) 19 | .WithLoggerFactory(new LoggerFactory()) 20 | .AddDefaultLoggingProvider() 21 | .WithServices(ConfigureServices) 22 | .WithHandler() 23 | .WithHandler() 24 | .WithHandler() 25 | .WithHandler() 26 | .WithHandler() 27 | .OnStarted(async (languageServer, result, token) => { 28 | var configuration = await languageServer.Configuration.GetConfiguration( 29 | new ConfigurationItem { 30 | Section = "pragma" 31 | } 32 | ).ConfigureAwait(false); 33 | TextDocumentSyncHandler.includeDirectory = configuration["pragma:includeDirectory"]; 34 | }) 35 | 36 | ).ConfigureAwait(false); 37 | await server.WaitForExit; 38 | } 39 | 40 | private static void ConfigureServices(IServiceCollection services) 41 | { 42 | services.AddSingleton(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tools/PragmaLangServer/UriHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | #if false 5 | public static class UriHelper 6 | { 7 | /// 8 | /// Get the local file-system path for the specified document URI. 9 | /// 10 | /// 11 | /// The LSP document URI. 12 | /// 13 | /// 14 | /// The file-system path, or null if the URI does not represent a file-system path. 15 | /// 16 | public static string GetFileSystemPath(Uri documentUri) 17 | { 18 | if (documentUri == null) 19 | throw new ArgumentNullException(nameof(documentUri)); 20 | 21 | if (documentUri.Scheme != "file") 22 | return null; 23 | 24 | // The language server protocol represents "C:\Foo\Bar" as "file:///c:/foo/bar". 25 | string fileSystemPath = Uri.UnescapeDataString(documentUri.AbsolutePath); 26 | if (Path.DirectorySeparatorChar == '\\') 27 | { 28 | if (fileSystemPath.StartsWith("/")) 29 | fileSystemPath = fileSystemPath.Substring(1); 30 | 31 | fileSystemPath = fileSystemPath.Replace('/', '\\'); 32 | } 33 | 34 | var fullPath = Path.GetFullPath(fileSystemPath); 35 | if (fullPath.StartsWith("/")) 36 | { 37 | return fullPath.Substring(1); 38 | } 39 | else 40 | { 41 | return fullPath; 42 | } 43 | } 44 | 45 | /// 46 | /// Convert a file-system path to an LSP document URI. 47 | /// 48 | /// 49 | /// The file-system path. 50 | /// 51 | /// 52 | /// The LSP document URI. 53 | /// 54 | public static Uri FromFileSystemPath(string fileSystemPath) 55 | { 56 | if (string.IsNullOrWhiteSpace(fileSystemPath)) 57 | throw new ArgumentException("Argument cannot be null, empty, or entirely composed of whitespace: 'fileSystemPath'.", nameof(fileSystemPath)); 58 | 59 | if (!Path.IsPathRooted(fileSystemPath)) 60 | throw new ArgumentException($"Path '{fileSystemPath}' is not an absolute path.", nameof(fileSystemPath)); 61 | 62 | if (Path.DirectorySeparatorChar == '\\') 63 | fileSystemPath = fileSystemPath.Replace('\\', '/'); 64 | 65 | fileSystemPath = fileSystemPath.Replace(":", System.Uri.EscapeDataString(":")); 66 | return new Uri("file:///" + fileSystemPath); 67 | } 68 | } 69 | 70 | #endif --------------------------------------------------------------------------------