├── .gitattributes ├── .gitignore ├── .paket ├── paket.bootstrapper.exe └── paket.targets ├── .travis.yml ├── FSharp.Quotations.Compiler.sln ├── LICENSE.txt ├── README.md ├── RELEASE_NOTES.md ├── appveyor.yml ├── build.cmd ├── build.fsx ├── build.sh ├── docs ├── content │ ├── index.fsx │ ├── ja │ │ ├── index.fsx │ │ ├── limitations.fsx │ │ └── tutorial.fsx │ ├── limitations.fsx │ └── tutorial.fsx ├── files │ ├── content │ │ └── project.css │ └── img │ │ ├── en.png │ │ ├── ja.png │ │ ├── logo-template.pdn │ │ └── logo.png └── tools │ ├── generate.fsx │ └── templates │ ├── ja │ └── template.cshtml │ └── template.cshtml ├── lib └── README.md ├── paket.dependencies ├── paket.lock ├── src └── FSharp.Quotations.Compiler │ ├── AssemblyInfo.fs │ ├── CompileStack.fs │ ├── DebugUtil.fs │ ├── Expr.fs │ ├── ExprCompiler.fs │ ├── ExprUtil.fs │ ├── FSharp.Quotations.Compiler.fsproj │ ├── GeneratorProviders.fs │ ├── ILGeneratorWrapper.fs │ ├── ILOpCode.fs │ ├── LambdaEmitter.fs │ ├── MethodCallEmitter.fs │ ├── ModuleBuilderWrapper.fs │ ├── NullableOpTranslator.fs │ ├── Stringizer.fs │ ├── TupleEmitter.fs │ ├── TypeBuilderWrapper.fs │ ├── VariableEnv.fs │ ├── paket.references │ └── paket.template └── tests ├── FSharp.Quotations.Compiler.Tests.CSharp ├── CSharpClass.cs ├── FSharp.Quotations.Compiler.Tests.CSharp.csproj └── Properties │ └── AssemblyInfo.cs └── FSharp.Quotations.Compiler.Tests ├── ArithmeticOpTest.fs ├── ArrayFuncTest.fs ├── ArrayOpTest.fs ├── BitOpTest.fs ├── BoolOpTest.fs ├── CmpOpTest.fs ├── ControlFlowExprTest.fs ├── ConvertFuncTest.fs ├── CoreFuncTest.fs ├── CustomClassTest.fs ├── ExtraTopLevelOpTest.fs ├── FSharp.Quotations.Compiler.Tests.fsproj ├── FSharpTypeTest.fs ├── LetTest.fs ├── Limitations.fs ├── ListTest.fs ├── LiteralTest.fs ├── MathFuncTest.fs ├── NullableTest.fs ├── ObjTest.fs ├── Pitfall.fs ├── RangeOpTest.fs ├── SeqTest.fs ├── StringFuncTest.fs ├── StringOpTest.fs ├── TestUtil.fs ├── TypeOpTest.fs ├── app.config ├── packages.config └── paket.references /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp text=auto eol=lf 6 | *.fs diff=csharp text=auto eol=lf 7 | *.fsi diff=csharp text=auto eol=lf 8 | *.fsx diff=csharp text=auto eol=lf 9 | *.sln text eol=crlf merge=union 10 | *.csproj merge=union 11 | *.vbproj merge=union 12 | *.fsproj merge=union 13 | *.dbproj merge=union 14 | 15 | # Standard to msysgit 16 | *.doc diff=astextplain 17 | *.DOC diff=astextplain 18 | *.docx diff=astextplain 19 | *.DOCX diff=astextplain 20 | *.dot diff=astextplain 21 | *.DOT diff=astextplain 22 | *.pdf diff=astextplain 23 | *.PDF diff=astextplain 24 | *.rtf diff=astextplain 25 | *.RTF diff=astextplain 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Xamarin Studio / monodevelop user-specific 10 | *.userprefs 11 | 12 | # Build results 13 | 14 | [Dd]ebug/ 15 | [Rr]elease/ 16 | x64/ 17 | build/ 18 | [Bb]in/ 19 | [Oo]bj/ 20 | 21 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 22 | !packages/*/build/ 23 | 24 | # MSTest test Results 25 | [Tt]est[Rr]esult*/ 26 | [Bb]uild[Ll]og.* 27 | 28 | *_i.c 29 | *_p.c 30 | *.ilk 31 | *.meta 32 | *.obj 33 | *.pch 34 | *.pdb 35 | *.pgc 36 | *.pgd 37 | *.rsp 38 | *.sbr 39 | *.tlb 40 | *.tli 41 | *.tlh 42 | *.tmp 43 | *.tmp_proj 44 | *.log 45 | *.vspscc 46 | *.vssscc 47 | .builds 48 | *.pidb 49 | *.log 50 | *.scc 51 | 52 | # Visual C++ cache files 53 | ipch/ 54 | *.aps 55 | *.ncb 56 | *.opensdf 57 | *.sdf 58 | *.cachefile 59 | 60 | # Visual Studio profiler 61 | *.psess 62 | *.vsp 63 | *.vspx 64 | 65 | # Guidance Automation Toolkit 66 | *.gpState 67 | 68 | # ReSharper is a .NET coding add-in 69 | _ReSharper*/ 70 | *.[Rr]e[Ss]harper 71 | 72 | # TeamCity is a build add-in 73 | _TeamCity* 74 | 75 | # DotCover is a Code Coverage Tool 76 | *.dotCover 77 | 78 | # NCrunch 79 | *.ncrunch* 80 | .*crunch*.local.xml 81 | 82 | # Installshield output folder 83 | [Ee]xpress/ 84 | 85 | # DocProject is a documentation generator add-in 86 | DocProject/buildhelp/ 87 | DocProject/Help/*.HxT 88 | DocProject/Help/*.HxC 89 | DocProject/Help/*.hhc 90 | DocProject/Help/*.hhk 91 | DocProject/Help/*.hhp 92 | DocProject/Help/Html2 93 | DocProject/Help/html 94 | 95 | # Click-Once directory 96 | publish/ 97 | 98 | # Publish Web Output 99 | *.Publish.xml 100 | 101 | # Enable nuget.exe in the .nuget folder (though normally executables are not tracked) 102 | !.nuget/NuGet.exe 103 | 104 | # Windows Azure Build Output 105 | csx 106 | *.build.csdef 107 | 108 | # Windows Store app package directory 109 | AppPackages/ 110 | 111 | # Others 112 | sql/ 113 | *.Cache 114 | ClientBin/ 115 | [Ss]tyle[Cc]op.* 116 | ~$* 117 | *~ 118 | *.dbmdl 119 | *.[Pp]ublish.xml 120 | *.pfx 121 | *.publishsettings 122 | 123 | # RIA/Silverlight projects 124 | Generated_Code/ 125 | 126 | # Backup & report files from converting an old project file to a newer 127 | # Visual Studio version. Backup files are not needed, because we have git ;-) 128 | _UpgradeReport_Files/ 129 | Backup*/ 130 | UpgradeLog*.XML 131 | UpgradeLog*.htm 132 | 133 | # SQL Server files 134 | App_Data/*.mdf 135 | App_Data/*.ldf 136 | 137 | 138 | #LightSwitch generated files 139 | GeneratedArtifacts/ 140 | _Pvt_Extensions/ 141 | ModelManifest.xml 142 | 143 | # ========================= 144 | # Windows detritus 145 | # ========================= 146 | 147 | # Windows image file caches 148 | Thumbs.db 149 | ehthumbs.db 150 | 151 | # Folder config file 152 | Desktop.ini 153 | 154 | # Recycle Bin used on file shares 155 | $RECYCLE.BIN/ 156 | 157 | # Mac desktop service store files 158 | .DS_Store 159 | 160 | # =================================================== 161 | # Exclude F# project specific directories and files 162 | # =================================================== 163 | 164 | # NuGet Packages Directory 165 | packages/ 166 | 167 | # Generated documentation folder 168 | docs/output/ 169 | 170 | # Temp folder used for publishing docs 171 | temp/ 172 | 173 | # Test results produced by build 174 | TestResults.xml 175 | 176 | # Nuget outputs 177 | nuget/*.nupkg 178 | release.cmd 179 | release.sh 180 | localpackages/ 181 | paket-files 182 | *.orig 183 | .paket/paket.exe 184 | docs/content/license.md 185 | docs/content/release-notes.md 186 | -------------------------------------------------------------------------------- /.paket/paket.bootstrapper.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bleis-tift/FSharp.Quotations.Compiler/ec7be81498cc02fdb8ab68b86bf14eab090f4a5c/.paket/paket.bootstrapper.exe -------------------------------------------------------------------------------- /.paket/paket.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | 7 | true 8 | $(MSBuildThisFileDirectory) 9 | $(MSBuildThisFileDirectory)..\ 10 | 11 | 12 | 13 | $(PaketToolsPath)paket.exe 14 | $(PaketToolsPath)paket.bootstrapper.exe 15 | "$(PaketExePath)" 16 | mono --runtime=v4.0.30319 $(PaketExePath) 17 | "$(PaketBootStrapperExePath)" 18 | mono --runtime=v4.0.30319 $(PaketBootStrapperExePath) 19 | 20 | $(PaketCommand) restore 21 | $(PaketBootStrapperCommand) 22 | 23 | RestorePackages; $(BuildDependsOn); 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | 3 | sudo: false # use the new container-based Travis infrastructure 4 | 5 | mono: 6 | - 3.12.0 7 | - 3.10.0 8 | solution: FSharp.Quotations.Compiler.sln 9 | 10 | script: 11 | - ./build.sh All 12 | -------------------------------------------------------------------------------- /FSharp.Quotations.Compiler.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 2013 3 | VisualStudioVersion = 12.0.30723.0 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{63297B98-5CED-492C-A5B7-A5B4F73CF142}" 6 | ProjectSection(SolutionItems) = preProject 7 | paket.dependencies = paket.dependencies 8 | paket.lock = paket.lock 9 | EndProjectSection 10 | EndProject 11 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1}" 12 | EndProject 13 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Quotations.Compiler", "src\FSharp.Quotations.Compiler\FSharp.Quotations.Compiler.fsproj", "{5BEAA1FD-4B61-43A0-9DC6-351C4121D877}" 14 | EndProject 15 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "project", "project", "{BF60BC93-E09B-4E5F-9D85-95A519479D54}" 16 | ProjectSection(SolutionItems) = preProject 17 | build.fsx = build.fsx 18 | README.md = README.md 19 | RELEASE_NOTES.md = RELEASE_NOTES.md 20 | EndProjectSection 21 | EndProject 22 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{83F16175-43B1-4C90-A1EE-8E351C33435D}" 23 | ProjectSection(SolutionItems) = preProject 24 | docs\tools\generate.fsx = docs\tools\generate.fsx 25 | docs\tools\templates\template.cshtml = docs\tools\templates\template.cshtml 26 | EndProjectSection 27 | EndProject 28 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "content", "content", "{8E6D5255-776D-4B61-85F9-73C37AA1FB9A}" 29 | ProjectSection(SolutionItems) = preProject 30 | docs\content\index.fsx = docs\content\index.fsx 31 | docs\content\limitations.fsx = docs\content\limitations.fsx 32 | docs\content\tutorial.fsx = docs\content\tutorial.fsx 33 | EndProjectSection 34 | EndProject 35 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{ED8079DD-2B06-4030-9F0F-DC548F98E1C4}" 36 | EndProject 37 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Quotations.Compiler.Tests", "tests\FSharp.Quotations.Compiler.Tests\FSharp.Quotations.Compiler.Tests.fsproj", "{6B9E5F15-6DA0-4D39-AAB7-B28986D9447C}" 38 | EndProject 39 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSharp.Quotations.Compiler.Tests.CSharp", "tests\FSharp.Quotations.Compiler.Tests.CSharp\FSharp.Quotations.Compiler.Tests.CSharp.csproj", "{B69BD2F7-BD0B-4DEC-AF95-6069212101A8}" 40 | EndProject 41 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ja", "ja", "{E8FC761A-5863-4AAB-9313-7CF0B0C71FEB}" 42 | ProjectSection(SolutionItems) = preProject 43 | docs\content\ja\index.fsx = docs\content\ja\index.fsx 44 | docs\content\ja\limitations.fsx = docs\content\ja\limitations.fsx 45 | docs\content\ja\tutorial.fsx = docs\content\ja\tutorial.fsx 46 | EndProjectSection 47 | EndProject 48 | Global 49 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 50 | Debug|Any CPU = Debug|Any CPU 51 | Development|Any CPU = Development|Any CPU 52 | Release|Any CPU = Release|Any CPU 53 | EndGlobalSection 54 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 55 | {5BEAA1FD-4B61-43A0-9DC6-351C4121D877}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 56 | {5BEAA1FD-4B61-43A0-9DC6-351C4121D877}.Debug|Any CPU.Build.0 = Debug|Any CPU 57 | {5BEAA1FD-4B61-43A0-9DC6-351C4121D877}.Development|Any CPU.ActiveCfg = Development|Any CPU 58 | {5BEAA1FD-4B61-43A0-9DC6-351C4121D877}.Development|Any CPU.Build.0 = Development|Any CPU 59 | {5BEAA1FD-4B61-43A0-9DC6-351C4121D877}.Release|Any CPU.ActiveCfg = Release|Any CPU 60 | {5BEAA1FD-4B61-43A0-9DC6-351C4121D877}.Release|Any CPU.Build.0 = Release|Any CPU 61 | {6B9E5F15-6DA0-4D39-AAB7-B28986D9447C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 62 | {6B9E5F15-6DA0-4D39-AAB7-B28986D9447C}.Debug|Any CPU.Build.0 = Debug|Any CPU 63 | {6B9E5F15-6DA0-4D39-AAB7-B28986D9447C}.Development|Any CPU.ActiveCfg = Development|Any CPU 64 | {6B9E5F15-6DA0-4D39-AAB7-B28986D9447C}.Development|Any CPU.Build.0 = Development|Any CPU 65 | {6B9E5F15-6DA0-4D39-AAB7-B28986D9447C}.Release|Any CPU.ActiveCfg = Release|Any CPU 66 | {6B9E5F15-6DA0-4D39-AAB7-B28986D9447C}.Release|Any CPU.Build.0 = Release|Any CPU 67 | {B69BD2F7-BD0B-4DEC-AF95-6069212101A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 68 | {B69BD2F7-BD0B-4DEC-AF95-6069212101A8}.Debug|Any CPU.Build.0 = Debug|Any CPU 69 | {B69BD2F7-BD0B-4DEC-AF95-6069212101A8}.Development|Any CPU.ActiveCfg = Debug|Any CPU 70 | {B69BD2F7-BD0B-4DEC-AF95-6069212101A8}.Development|Any CPU.Build.0 = Debug|Any CPU 71 | {B69BD2F7-BD0B-4DEC-AF95-6069212101A8}.Release|Any CPU.ActiveCfg = Release|Any CPU 72 | {B69BD2F7-BD0B-4DEC-AF95-6069212101A8}.Release|Any CPU.Build.0 = Release|Any CPU 73 | EndGlobalSection 74 | GlobalSection(SolutionProperties) = preSolution 75 | HideSolutionNode = FALSE 76 | EndGlobalSection 77 | GlobalSection(NestedProjects) = preSolution 78 | {83F16175-43B1-4C90-A1EE-8E351C33435D} = {A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1} 79 | {8E6D5255-776D-4B61-85F9-73C37AA1FB9A} = {A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1} 80 | {6B9E5F15-6DA0-4D39-AAB7-B28986D9447C} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4} 81 | {B69BD2F7-BD0B-4DEC-AF95-6069212101A8} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4} 82 | {E8FC761A-5863-4AAB-9313-7CF0B0C71FEB} = {8E6D5255-776D-4B61-85F9-73C37AA1FB9A} 83 | EndGlobalSection 84 | EndGlobal 85 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Issue Stats](http://issuestats.com/github/bleis-tift/FSharp.Quotations.Compiler/badge/issue)](http://issuestats.com/github/bleis-tift/FSharp.Quotations.Compiler) 2 | [![Issue Stats](http://issuestats.com/github/bleis-tift/FSharp.Quotations.Compiler/badge/pr)](http://issuestats.com/github/bleis-tift/FSharp.Quotations.Compiler) 3 | 4 | # FSharp.Quotations.Compiler 5 | 6 | This library is a compiler for F# expression tree. 7 | This is based on System.Reflection.Emit technology. 8 | 9 | Read the [Getting started tutorial](http://bleis-tift.github.io/FSharp.Quotations.Compiler/index.html#Getting-started) to learn more. 10 | 11 | Documentation: http://bleis-tift.github.io/FSharp.Quotations.Compiler 12 | 13 | ## Goals 14 | * Never happen StackOverflowException 15 | * Compile time is fast enough 16 | * Evaluate time is fast enough 17 | * Contains tests enough and runs fast enough 18 | 19 | Of course, For Fun. 20 | 21 | ## Limitations 22 | The following exprs are not supported yet. 23 | 24 | * `AddressOf` 25 | * `AddressSet` 26 | * `ForIntegerRangeLoop` 27 | * `LetRecursive` 28 | * `NewDelegate` 29 | * `Quote` 30 | * `WhileLoop` 31 | 32 | And `Value` is supported only the following types and `null`. 33 | 34 | * `unit` 35 | * `bool` 36 | * `int` 37 | * `byte` 38 | * `sbyte` 39 | * `int16` 40 | * `uint16` 41 | * `uint32` 42 | * `int64` 43 | * `uint64` 44 | * `float32` 45 | * `float` 46 | * `char` 47 | * `string` 48 | 49 | ## Maintainer(s) 50 | 51 | - [@bleis-tift](https://github.com/bleis-tift) 52 | -------------------------------------------------------------------------------- /RELEASE_NOTES.md: -------------------------------------------------------------------------------- 1 | ### 0.4 - September 9 2015 2 | * bug fix 3 | 4 | ### 0.3 - June 19 2015 5 | * bug fix 6 | 7 | ### 0.2 - April 19 2015 8 | * Initial public release 9 | 10 | ### 0.1 - Unreleased 11 | * internal release version 12 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | init: 2 | - git config --global core.autocrlf input 3 | build_script: 4 | - cmd: build.cmd 5 | test: off 6 | version: 0.0.1.{build} 7 | artifacts: 8 | - path: bin 9 | name: bin 10 | -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | cls 3 | 4 | .paket\paket.bootstrapper.exe 5 | if errorlevel 1 ( 6 | exit /b %errorlevel% 7 | ) 8 | 9 | .paket\paket.exe restore 10 | if errorlevel 1 ( 11 | exit /b %errorlevel% 12 | ) 13 | 14 | IF NOT EXIST build.fsx ( 15 | .paket\paket.exe update 16 | packages\FAKE\tools\FAKE.exe init.fsx 17 | ) 18 | packages\FAKE\tools\FAKE.exe build.fsx %* 19 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if test "$OS" = "Windows_NT" 3 | then 4 | # use .Net 5 | 6 | .paket/paket.bootstrapper.exe 7 | exit_code=$? 8 | if [ $exit_code -ne 0 ]; then 9 | exit $exit_code 10 | fi 11 | 12 | .paket/paket.exe restore 13 | exit_code=$? 14 | if [ $exit_code -ne 0 ]; then 15 | exit $exit_code 16 | fi 17 | 18 | [ ! -e build.fsx ] && .paket/paket.exe update 19 | [ ! -e build.fsx ] && packages/FAKE/tools/FAKE.exe init.fsx 20 | packages/FAKE/tools/FAKE.exe $@ --fsiargs -d:MONO build.fsx 21 | else 22 | # use mono 23 | mono .paket/paket.bootstrapper.exe 24 | exit_code=$? 25 | if [ $exit_code -ne 0 ]; then 26 | exit $exit_code 27 | fi 28 | 29 | mono .paket/paket.exe restore 30 | exit_code=$? 31 | if [ $exit_code -ne 0 ]; then 32 | exit $exit_code 33 | fi 34 | 35 | [ ! -e build.fsx ] && mono .paket/paket.exe update 36 | [ ! -e build.fsx ] && mono packages/FAKE/tools/FAKE.exe init.fsx 37 | mono packages/FAKE/tools/FAKE.exe $@ --fsiargs -d:MONO build.fsx 38 | fi 39 | -------------------------------------------------------------------------------- /docs/content/index.fsx: -------------------------------------------------------------------------------- 1 | (*** hide ***) 2 | // This block of code is omitted in the generated HTML documentation. Use 3 | // it to define helpers that you do not want to show in the documentation. 4 | #I "../../bin" 5 | #I "../../bin/FSharp.Quotations.Compiler" 6 | 7 | (** 8 | FSharp.Quotations.Compiler 9 | ====================== 10 | 11 |
12 |
13 |
14 |
15 | The FSharp.Quotations.Compiler library can be installed from NuGet: 16 |
PM> Install-Package FSharp.Quotations.Compiler
17 |
18 |
19 |
20 |
21 | 22 | Summary 23 | ------- 24 | FSharp.Quotations.Compiler is a library for compiling F# expression tree to IL. 25 | 26 | There are similar libraries: 27 | 28 | * [FSharp.Quotations.Evaluator](http://fsprojects.github.io/FSharp.Quotations.Evaluator/) 29 | * [QuotationCompiler](https://github.com/eiriktsarpalis/QuotationCompiler) 30 | * [Unquote](https://code.google.com/p/unquote/) 31 | 32 | The biggest difference between FSharp.Quotations.Compiler and these is analysis policy of expression tree. 33 | FSharp.Quotations.Compiler uses while loop rather than recursive function. 34 | So we can use this library without thinking about stack overflow. 35 | 36 | Example 37 | ------- 38 | 39 | *) 40 | #r "FSharp.Quotations.Compiler.dll" 41 | open FSharp.Quotations.Compiler 42 | 43 | (*** define-output: result ***) 44 | let expr = <@ 10 + 20 @> 45 | let res = expr.Compile() 46 | printfn "%d" (res.ExecuteCompiledCode()) 47 | 48 | (** The output is: *) 49 | (*** include-output: result ***) 50 | 51 | (** 52 | 53 | Samples & documentation 54 | ----------------------- 55 | * [Tutorial](tutorial.html) contains a further explanation of this library. 56 | * [Limitations](limitations.html) contains an explanation of limitations of this library. 57 | * [API Reference](reference/index.html) contains automatically generated documentation for all types, modules 58 | and functions in the library. 59 | 60 | Contributing and copyright 61 | -------------------------- 62 | 63 | The project is hosted on [GitHub][gh] where you can [report issues][issues], fork 64 | the project and submit pull requests. 65 | 66 | The library is available under Public Domain license, which allows modification and 67 | redistribution for both commercial and non-commercial purposes. For more information see the 68 | [License file][license] in the GitHub repository. 69 | 70 | [content]: https://github.com/bleis-tift/FSharp.Quotations.Compiler/tree/master/docs/content 71 | [gh]: https://github.com/bleis-tift/FSharp.Quotations.Compiler 72 | [issues]: https://github.com/bleis-tift/FSharp.Quotations.Compiler/issues 73 | [license]: https://github.com/bleis-tift/FSharp.Quotations.Compiler/blob/master/LICENSE.txt 74 | *) 75 | -------------------------------------------------------------------------------- /docs/content/ja/index.fsx: -------------------------------------------------------------------------------- 1 | (*** hide ***) 2 | // This block of code is omitted in the generated HTML documentation. Use 3 | // it to define helpers that you do not want to show in the documentation. 4 | #I "../../../bin" 5 | #I "../../../bin/FSharp.Quotations.Compiler" 6 | 7 | (** 8 | FSharp.Quotations.Compiler 9 | ========================== 10 | 11 |
12 |
13 |
14 |
15 | FSharp.Quotations.CompilerはNuGetからインストールできます: 16 |
PM> Install-Package FSharp.Quotations.Compiler
17 |
18 |
19 |
20 |
21 | 22 | 概要 23 | ---- 24 | FSharp.Quotations.Compilerは、F#の式木をILにコンパイルして実行するためのライブラリです。 25 | 26 | 同じようなライブラリには、以下のようなものがあります。 27 | 28 | * [FSharp.Quotations.Evaluator](http://fsprojects.github.io/FSharp.Quotations.Evaluator/) 29 | * [QuotationCompiler](https://github.com/eiriktsarpalis/QuotationCompiler) 30 | * [Unquote](https://code.google.com/p/unquote/) 31 | 32 | これらのライブラリとFSharp.Quotations.Compilerの大きな違いは、 33 | 式木の解析に(再帰ではなく)ループを使っていることです。 34 | そのため、このライブラリはスタックオーバーフローを気にすることなく使えます。 35 | 36 | 簡単な例 37 | -------- 38 | 39 | *) 40 | #r "FSharp.Quotations.Compiler.dll" 41 | open FSharp.Quotations.Compiler 42 | 43 | (*** define-output: result ***) 44 | let expr = <@ 10 + 20 @> 45 | let res = expr.Compile() 46 | printfn "%d" (res.ExecuteCompiledCode()) 47 | 48 | (** 49 | このコードを実行すると以下のように出力されます: 50 | *) 51 | (*** include-output: result ***) 52 | 53 | (** 54 | 55 | サンプルとドキュメント 56 | ---------------------- 57 | * [チュートリアル](tutorial.html)には、ライブラリのサンプルがあります。 58 | * [制限事項](limitations.html)には、このライブラリの制限事項についての説明があります。 59 | * [APIリファレンス](../reference/index.html)には、このライブラリのすべての型、モジュール、関数についての自動生成されたドキュメントがあります。 60 | 61 | コントリビュート 62 | ---------------- 63 | このプロジェクトは[Github][gh]でホストされています。 64 | [イシューを報告][issues]でき、フォークしてプルリクエストを送ることもできます。 65 | 66 | 67 | このライブラリは、CC0で公開されており、商用、非商用問わず、変更や再頒布可能です。 68 | より詳しい情報は、Githubリポジトリの[ライセンスファイル][license]をご覧ください。 69 | 70 | [content]: https://github.com/bleis-tift/FSharp.Quotations.Compiler/tree/master/docs/content 71 | [gh]: https://github.com/bleis-tift/FSharp.Quotations.Compiler 72 | [issues]: https://github.com/bleis-tift/FSharp.Quotations.Compiler/issues 73 | [license]: https://github.com/bleis-tift/FSharp.Quotations.Compiler/blob/master/LICENSE.txt 74 | *) 75 | -------------------------------------------------------------------------------- /docs/content/ja/limitations.fsx: -------------------------------------------------------------------------------- 1 | (*** hide ***) 2 | // This block of code is omitted in the generated HTML documentation. Use 3 | // it to define helpers that you do not want to show in the documentation. 4 | #I "../../../bin" 5 | #I "../../../bin/FSharp.Quotations.Compiler" 6 | 7 | #r "FSharp.Quotations.Compiler.dll" 8 | 9 | open Microsoft.FSharp.Quotations 10 | open FSharp.Quotations.Compiler 11 | 12 | (** 13 | 制限事項 14 | ======== 15 | このライブラリにはいくつかの制限事項があります。 16 | 17 | 未実装機能 18 | ---------- 19 | * `ForIntegerRangeLoop` 20 | * `LetRecursive` 21 | * `NewDelegate` 22 | * `WhileLoop` 23 | 24 | 未サポート機能 25 | -------------- 26 | * `AddressOf` 27 | * `AddressSet` 28 | * `Quote` 29 | 30 | 技術的な問題 31 | ------------ 32 | ### インライン関数 33 | `NoDynamicInvocationAttribute`付きの他のインライン関数を含むインライン関数は起動できません。 34 | 例えば、次のコードは`System.NotSupportedException`を投げます。 35 | *) 36 | 37 | // (-)はNoDynamicInvocationAttribute付き 38 | let inline f1 x y = x - y 39 | try 40 | let expr = <@ f1 20 10 @> 41 | expr.Execute() |> ignore 42 | with 43 | :? System.NotSupportedException -> printfn "raised exception." 44 | 45 | (** 46 | もちろん、`NoDynamicInvocationAttribute`付きの関数もこのライブラリでは実行できません。 47 | *) 48 | 49 | [] 50 | let inline f2 x = x 51 | try 52 | let expr = <@ f2 10 @> 53 | expr.Execute() |> ignore 54 | with 55 | :? System.NotSupportedException -> printfn "raised exception." 56 | 57 | (** 58 | もし`NoDynamicInvocationAttribute`付きの関数を実行したい場合、 59 | `inline`を取るか、手動でインライン化する必要があります。 60 | *) 61 | 62 | let expr = <@ 20 - 10 @> 63 | printfn "20 - 10 = %d" (expr.Execute()) 64 | 65 | (** 66 | 他にも、メンバー制約起動式を含むインライン関数をこのライブラリで実行することはできません。 67 | これに関する回避策はありません。 68 | 69 | ### mutableとtry-with/try-finally 70 | `try-with`と`try-finally`は値を持つ式なので、このライブラリではこれらをラムダ式にラップします。 71 | *) 72 | 73 | let tryWithExpr = 74 | <@ let x = 10 75 | let res = 76 | try x with _ -> 20 77 | res * 2 @> 78 | let compiledTryWithExpr = tryWithExpr.Compile() 79 | 80 | (** 81 | これは以下のようにコンパイルされます。 82 | *) 83 | 84 | type lambda0(x) = 85 | inherit FSharpFunc() 86 | 87 | override __.Invoke(_) = 88 | try x with _ -> 20 89 | 90 | let x = 10 91 | let res = lambda0(x).Invoke() 92 | res * 2 93 | 94 | (** 95 | `x`はラムダを表すクラスのフィールドとしてコンパイルされます。 96 | そのため、ラムダ式の本体で`x`を書き換えても、ラムダ式の外側には影響を与えることが出来ません。 97 | *) 98 | 99 | let letMutableAndTryWithExpr = 100 | <@ let mutable y = 0 101 | let res2 = 102 | try y <- 10; y with _ -> 20 103 | (y, res2) @> 104 | let compiledLetMutableAndTryWithExpr = letMutableAndTryWithExpr.Compile() 105 | 106 | (** 107 | これは、以下のようにコンパイルされます。 108 | *) 109 | 110 | type lambda1(y) = 111 | inherit FSharpFunc() 112 | 113 | member val y = y with get, set 114 | override this.Invoke(_) = 115 | try this.y <- 10; y with _ -> 20 116 | 117 | let mutable y = 0 118 | let tmp = lambda1(y) 119 | let res2 = tmp.Invoke() 120 | // ラムダ式の起動後に代入すべきだが、現在の実装ではそうなっていない。 121 | // y <- tmp.y 122 | (y, res2) 123 | 124 | (** 125 | ### Expr.Value 126 | リテラルを持たない型の`Expr.Value`はサポートされていません。 127 | *) 128 | 129 | let valueExpr: Expr = 130 | Expr.Value(System.DateTime.UtcNow) 131 | |> Expr.Cast 132 | 133 | (*** define-output: result1 ***) 134 | try 135 | valueExpr.Execute() |> ignore 136 | with 137 | e -> printfn "%s" e.Message 138 | 139 | (*** include-output: result1 ***) 140 | 141 | (** 142 | `Expr.Value`の代わりに、引用式を使ってください。 143 | *) 144 | 145 | let codeQuote = <@ System.DateTime.UtcNow @> 146 | (*** define-output: result2 ***) 147 | printfn "%A" (codeQuote.Execute()) 148 | 149 | (** 150 | 上の引用式は`Expr.Value`にならず、`Expr.PropertyGet`になるため、正しく実行できます。 151 | *) 152 | (*** include-output: result2 ***) 153 | -------------------------------------------------------------------------------- /docs/content/ja/tutorial.fsx: -------------------------------------------------------------------------------- 1 | (*** hide ***) 2 | // This block of code is omitted in the generated HTML documentation. Use 3 | // it to define helpers that you do not want to show in the documentation. 4 | #I "../../../bin" 5 | #I "../../../bin/FSharp.Quotations.Compiler" 6 | 7 | #r "FSharp.Quotations.Compiler.dll" 8 | 9 | (** 10 | チュートリアル 11 | ============== 12 | このライブラリは簡単に使えます。 13 | 14 | このライブラリを使うためには、`FSharp.Quotations.Compiler`名前空間をオープンしておくといいでしょう。 15 | *) 16 | open FSharp.Quotations.Compiler 17 | 18 | (** 19 | 型付きの式木 20 | ------------ 21 | 次のような式木を実行したい場合を考えてみます。 22 | *) 23 | 24 | let x = 10 25 | let y = 20 26 | let expr = <@ x + y @> 27 | 28 | (** 29 | `Execute`メソッドを使うだけでできます。 30 | *) 31 | 32 | (*** define-output: result1 ***) 33 | printfn "%d + %d = %d" x y (expr.Execute()) 34 | 35 | (** 36 | このコードを実行すると以下のように出力されます: 37 | *) 38 | (*** include-output: result1 ***) 39 | 40 | (** 41 | もし式木をコンパイルして、あとで実行したい場合は、`Compile`メソッドを使います。 42 | *) 43 | 44 | let result = expr.Compile() 45 | 46 | (** 47 | `Compile`メソッドを使うのと同じ意味で`ExprCompiler.compile`関数も使えます。 48 | *) 49 | 50 | let result2 = expr |> ExprCompiler.compile 51 | 52 | (** 53 | `result`を実行するためには、`ExecuteCompiledCode`メソッドを使います。 54 | *) 55 | 56 | printfn "%d + %d = %d" x y (result.ExecuteCompiledCode()) 57 | 58 | (** 59 | 型なしの式木 60 | ------------ 61 | このライブラリは、型なしの式木を直接はサポートしていません。 62 | もし型なしの式木を実行したい場合は、`Expr.Cast`メソッドを使います。 63 | このメソッドはF#の標準ライブラリのメソッドです。 64 | *) 65 | 66 | open Microsoft.FSharp.Quotations 67 | 68 | // キャストのためのヘルパ関数 69 | let cast<'T> (expr: Expr) : Expr<'T> = expr |> Expr.Cast 70 | 71 | let untypedExpr = <@@ x + y @@> 72 | let casted = untypedExpr |> cast 73 | printfn "%d + %d = %d" x y (casted.Execute()) 74 | -------------------------------------------------------------------------------- /docs/content/limitations.fsx: -------------------------------------------------------------------------------- 1 | (*** hide ***) 2 | // This block of code is omitted in the generated HTML documentation. Use 3 | // it to define helpers that you do not want to show in the documentation. 4 | #I "../../bin" 5 | #I "../../bin/FSharp.Quotations.Compiler" 6 | 7 | #r "FSharp.Quotations.Compiler.dll" 8 | 9 | open Microsoft.FSharp.Quotations 10 | open FSharp.Quotations.Compiler 11 | 12 | (** 13 | Limitations 14 | =========== 15 | This library has some limitations. 16 | 17 | Not Implemented Yet 18 | ------------------- 19 | * `ForIntegerRangeLoop` 20 | * `LetRecursive` 21 | * `NewDelegate` 22 | * `WhileLoop` 23 | 24 | Unupported 25 | ---------- 26 | * `AddressOf` 27 | * `AddressSet` 28 | * `Quote` 29 | 30 | Technical Problem 31 | ----------------- 32 | ### inline function 33 | The inline functions that contains other inline function with `NoDynamicInvocationAttribute` can not invoke. 34 | For example, the following code throws `System.NotSupportedException`. 35 | *) 36 | 37 | // (-) has NoDynamicInvocationAttribute. 38 | let inline f1 x y = x - y 39 | try 40 | let expr = <@ f1 20 10 @> 41 | expr.Execute() |> ignore 42 | with 43 | :? System.NotSupportedException -> printfn "raised exception." 44 | 45 | (** 46 | Of course, the inline function with `NoDynamicInvocationAttribute` can not execute using this library. 47 | *) 48 | 49 | [] 50 | let inline f2 x = x 51 | try 52 | let expr = <@ f2 10 @> 53 | expr.Execute() |> ignore 54 | with 55 | :? System.NotSupportedException -> printfn "raised exception." 56 | 57 | (** 58 | If you want to execute the function that contains other inline function with `NoDynamicInvocationAttribute`, 59 | you need to remove `inline` or to inline by hand. 60 | *) 61 | 62 | let expr = <@ 20 - 10 @> 63 | printfn "20 - 10 = %d" (expr.Execute()) 64 | 65 | (** 66 | In other case, the inline functions that contains member constraint invocation expressions can not also execute by this library. 67 | There is no workarround. 68 | 69 | ### mutable and try-with/try-finally 70 | This library wraps `try-with` and `try-finally` in the lambda expression because they are expression that has the value. 71 | *) 72 | 73 | let tryWithExpr = 74 | <@ let x = 10 75 | let res = 76 | try x with _ -> 20 77 | res * 2 @> 78 | let compiledTryWithExpr = tryWithExpr.Compile() 79 | 80 | (** 81 | It is compiled as following. 82 | *) 83 | 84 | type lambda0(x) = 85 | inherit FSharpFunc() 86 | 87 | override __.Invoke(_) = 88 | try x with _ -> 20 89 | 90 | let x = 10 91 | let res = lambda0(x).Invoke() 92 | res * 2 93 | 94 | (** 95 | The `x` is compiled to the field of the lambda class. 96 | So rewrite the `x` in the body of the lambda expression, it does not affect the outside of the lambda expression. 97 | *) 98 | 99 | let letMutableAndTryWithExpr = 100 | <@ let mutable y = 0 101 | let res2 = 102 | try y <- 10; y with _ -> 20 103 | (y, res2) @> 104 | let compiledLetMutableAndTryWithExpr = letMutableAndTryWithExpr.Compile() 105 | 106 | (** 107 | It is compiled as following. 108 | *) 109 | 110 | type lambda1(y) = 111 | inherit FSharpFunc() 112 | 113 | member val y = y with get, set 114 | override this.Invoke(_) = 115 | try this.y <- 10; y with _ -> 20 116 | 117 | let mutable y = 0 118 | let tmp = lambda1(y) 119 | let res2 = tmp.Invoke() 120 | // should assign after invocation of the lambda expression. 121 | // But now implementation does not assign. 122 | // y <- tmp.y 123 | (y, res2) 124 | 125 | (** 126 | ### Expr.Value 127 | The `Expr.Value` is not supported the type that does not have the literal. 128 | *) 129 | 130 | let valueExpr: Expr = 131 | Expr.Value(System.DateTime.UtcNow) 132 | |> Expr.Cast 133 | 134 | (*** define-output: result1 ***) 135 | try 136 | valueExpr.Execute() |> ignore 137 | with 138 | e -> printfn "%A" e.Message 139 | 140 | (*** include-output: result1 ***) 141 | 142 | (** 143 | You should use the quoted expression instead of using the `Expr.Value`. 144 | *) 145 | 146 | let codeQuote = <@ System.DateTime.UtcNow @> 147 | (*** define-output: result2 ***) 148 | printfn "%A" (codeQuote.Execute()) 149 | 150 | (** 151 | The above quoted expression can execute as expected 152 | because it is evaluated as `Expr.PropertyGet` 153 | rather than `Expr.Value`. 154 | *) 155 | (*** include-output: result2 ***) 156 | -------------------------------------------------------------------------------- /docs/content/tutorial.fsx: -------------------------------------------------------------------------------- 1 | (*** hide ***) 2 | // This block of code is omitted in the generated HTML documentation. Use 3 | // it to define helpers that you do not want to show in the documentation. 4 | #I "../../bin" 5 | #I "../../bin/FSharp.Quotations.Compiler" 6 | 7 | #r "FSharp.Quotations.Compiler.dll" 8 | 9 | (** 10 | Tutorial 11 | ======== 12 | This library use easily. 13 | 14 | In order to use this library, open `FSharp.Quotations.Compiler` namespace. 15 | *) 16 | open FSharp.Quotations.Compiler 17 | 18 | (** 19 | Typed Expression Tree 20 | --------------------- 21 | Suppose that you want to execute the following expression tree. 22 | *) 23 | 24 | let x = 10 25 | let y = 20 26 | let expr = <@ x + y @> 27 | 28 | (** 29 | You just use `Execute` method. 30 | *) 31 | 32 | (*** define-output: result1 ***) 33 | printfn "%d + %d = %d" x y (expr.Execute()) 34 | 35 | (** 36 | This code results as follows: 37 | *) 38 | (*** include-output: result1 ***) 39 | 40 | (** 41 | If you want to compile the expression tree and execute it later, 42 | you use `Compile` method. 43 | *) 44 | 45 | let result = expr.Compile() 46 | 47 | (** 48 | Or you can use `ExprCompiler.compile` function as same as using `Compile` method. 49 | *) 50 | 51 | let result2 = expr |> ExprCompiler.compile 52 | 53 | (** 54 | In order to execute `result`, you use `ExecuteCompiledCode` method. 55 | *) 56 | 57 | printfn "%d + %d = %d" x y (result.ExecuteCompiledCode()) 58 | 59 | (** 60 | Untyped Expression Tree 61 | ----------------------- 62 | This library does not support the untyped expression tree directly. 63 | If you want to execute untyped expression tree then use `Expr.Cast` method. 64 | It is the method of the F# standard library. 65 | *) 66 | 67 | open Microsoft.FSharp.Quotations 68 | 69 | // helper function for casting 70 | let cast<'T> (expr: Expr) : Expr<'T> = expr |> Expr.Cast 71 | 72 | let untypedExpr = <@@ x + y @@> 73 | let casted = untypedExpr |> cast 74 | printfn "%d + %d = %d" x y (casted.Execute()) 75 | -------------------------------------------------------------------------------- /docs/files/content/project.css: -------------------------------------------------------------------------------- 1 | .nav-list > li > a.nflag { 2 | float:right; 3 | padding: 0px; 4 | } 5 | 6 | .nav-list > li > a.nflag2 { 7 | margin-right: 18px; 8 | } 9 | -------------------------------------------------------------------------------- /docs/files/img/en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bleis-tift/FSharp.Quotations.Compiler/ec7be81498cc02fdb8ab68b86bf14eab090f4a5c/docs/files/img/en.png -------------------------------------------------------------------------------- /docs/files/img/ja.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bleis-tift/FSharp.Quotations.Compiler/ec7be81498cc02fdb8ab68b86bf14eab090f4a5c/docs/files/img/ja.png -------------------------------------------------------------------------------- /docs/files/img/logo-template.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bleis-tift/FSharp.Quotations.Compiler/ec7be81498cc02fdb8ab68b86bf14eab090f4a5c/docs/files/img/logo-template.pdn -------------------------------------------------------------------------------- /docs/files/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bleis-tift/FSharp.Quotations.Compiler/ec7be81498cc02fdb8ab68b86bf14eab090f4a5c/docs/files/img/logo.png -------------------------------------------------------------------------------- /docs/tools/generate.fsx: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------- 2 | // Builds the documentation from `.fsx` and `.md` files in the 'docs/content' directory 3 | // (the generated documentation is stored in the 'docs/output' directory) 4 | // -------------------------------------------------------------------------------------- 5 | 6 | // Web site location for the generated documentation 7 | let website = "/FSharp.Quotations.Compiler" 8 | 9 | let githubLink = "http://github.com/bleis-tift/FSharp.Quotations.Compiler" 10 | 11 | // Specify more information about your project 12 | let info = 13 | [ "project-name", "FSharp.Quotations.Compiler" 14 | "project-author", "bleis-tift" 15 | "project-summary", "A compiler for F# expression tree" 16 | "project-github", githubLink 17 | "project-nuget", "http://nuget.org/packages/FSharp.Quotations.Compiler" ] 18 | 19 | // -------------------------------------------------------------------------------------- 20 | // For typical project, no changes are needed below 21 | // -------------------------------------------------------------------------------------- 22 | 23 | #I "../../packages/FAKE/tools/" 24 | #load "../../packages/FSharp.Formatting/FSharp.Formatting.fsx" 25 | #r "NuGet.Core.dll" 26 | #r "FakeLib.dll" 27 | open Fake 28 | open System.IO 29 | open Fake.FileHelper 30 | open FSharp.Literate 31 | open FSharp.MetadataFormat 32 | 33 | // When called from 'build.fsx', use the public project URL as 34 | // otherwise, use the current 'output' directory. 35 | #if RELEASE 36 | let root = website 37 | #else 38 | let root = "file://" + (__SOURCE_DIRECTORY__ @@ "../output") 39 | #endif 40 | 41 | // Paths with template/source/output locations 42 | let bin = __SOURCE_DIRECTORY__ @@ "../../bin" 43 | let content = __SOURCE_DIRECTORY__ @@ "../content" 44 | let output = __SOURCE_DIRECTORY__ @@ "../output" 45 | let files = __SOURCE_DIRECTORY__ @@ "../files" 46 | let templates = __SOURCE_DIRECTORY__ @@ "templates" 47 | let formatting = __SOURCE_DIRECTORY__ @@ "../../packages/FSharp.Formatting/" 48 | let docTemplate = formatting @@ "templates/docpage.cshtml" 49 | 50 | // Where to look for *.csproj templates (in this order) 51 | let layoutRootsAll = new System.Collections.Generic.Dictionary() 52 | layoutRootsAll.Add("en",[ templates; formatting @@ "templates" 53 | formatting @@ "templates/reference" ]) 54 | subDirectories (directoryInfo templates) 55 | |> Seq.iter (fun d -> 56 | let name = d.Name 57 | if name.Length = 2 || name.Length = 3 then 58 | layoutRootsAll.Add( 59 | name, [templates @@ name 60 | formatting @@ "templates" 61 | formatting @@ "templates/reference" ])) 62 | 63 | // Copy static files and CSS + JS from F# Formatting 64 | let copyFiles () = 65 | CopyRecursive files output true |> Log "Copying file: " 66 | ensureDirectory (output @@ "content") 67 | CopyRecursive (formatting @@ "styles") (output @@ "content") true 68 | |> Log "Copying styles and scripts: " 69 | 70 | let references = 71 | if isMono then 72 | // Workaround compiler errors in Razor-ViewEngine 73 | let d = RazorEngine.Compilation.ReferenceResolver.UseCurrentAssembliesReferenceResolver() 74 | let loadedList = d.GetReferences () |> Seq.map (fun r -> r.GetFile()) |> Seq.cache 75 | // We replace the list and add required items manually as mcs doesn't like duplicates... 76 | let getItem name = loadedList |> Seq.find (fun l -> l.Contains name) 77 | [ (getItem "FSharp.Core").Replace("4.3.0.0", "4.3.1.0") 78 | Path.GetFullPath "./../../packages/FSharp.Compiler.Service/lib/net40/FSharp.Compiler.Service.dll" 79 | Path.GetFullPath "./../../packages/FSharp.Formatting/lib/net40/System.Web.Razor.dll" 80 | Path.GetFullPath "./../../packages/FSharp.Formatting/lib/net40/RazorEngine.dll" 81 | Path.GetFullPath "./../../packages/FSharp.Formatting/lib/net40/FSharp.Literate.dll" 82 | Path.GetFullPath "./../../packages/FSharp.Formatting/lib/net40/FSharp.CodeFormat.dll" 83 | Path.GetFullPath "./../../packages/FSharp.Formatting/lib/net40/FSharp.MetadataFormat.dll" ] 84 | |> Some 85 | else None 86 | 87 | let binaries = 88 | directoryInfo bin 89 | |> subDirectories 90 | |> Array.map (fun d -> d.FullName @@ (sprintf "%s.dll" d.Name)) 91 | |> List.ofArray 92 | 93 | let libDirs = 94 | directoryInfo bin 95 | |> subDirectories 96 | |> Array.map (fun d -> d.FullName) 97 | |> List.ofArray 98 | 99 | // Build API reference from XML comments 100 | let buildReference () = 101 | CleanDir (output @@ "reference") 102 | MetadataFormat.Generate 103 | ( binaries, output @@ "reference", layoutRootsAll.["en"], 104 | parameters = ("root", root)::info, 105 | sourceRepo = githubLink @@ "tree/master", 106 | sourceFolder = __SOURCE_DIRECTORY__ @@ ".." @@ "..", 107 | ?assemblyReferences = references, 108 | publicOnly = true,libDirs = libDirs ) 109 | 110 | // Build documentation from `fsx` and `md` files in `docs/content` 111 | let buildDocumentation () = 112 | let fsi = FsiEvaluator() 113 | Literate.ProcessDirectory 114 | ( content, docTemplate, output, replacements = ("root", root)::info, 115 | layoutRoots = layoutRootsAll.["en"], 116 | ?assemblyReferences = references, 117 | generateAnchors = true, 118 | processRecursive = false, 119 | fsiEvaluator = fsi ) 120 | 121 | let subdirs = Directory.EnumerateDirectories(content, "*", SearchOption.TopDirectoryOnly) 122 | for dir in subdirs do 123 | let dirname = (new DirectoryInfo(dir)).Name 124 | let layoutRoots = 125 | let key = layoutRootsAll.Keys |> Seq.tryFind (fun i -> i = dirname) 126 | match key with 127 | | Some lang -> layoutRootsAll.[lang] 128 | | None -> layoutRootsAll.["en"] // "en" is the default language 129 | Literate.ProcessDirectory 130 | ( dir, docTemplate, output @@ dirname, replacements = ("root", root)::info, 131 | layoutRoots = layoutRoots, 132 | ?assemblyReferences = references, 133 | generateAnchors = true, 134 | fsiEvaluator = fsi ) 135 | 136 | // Generate 137 | copyFiles() 138 | #if HELP 139 | buildDocumentation() 140 | #endif 141 | #if REFERENCE 142 | buildReference() 143 | #endif 144 | -------------------------------------------------------------------------------- /docs/tools/templates/ja/template.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | @Title 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 |
25 |
26 | 30 |

@Properties["project-name"]

31 |
32 |
33 |
34 |
35 | @RenderBody() 36 |
37 |
38 | F# Project 39 | 58 |
59 |
60 |
61 | Fork me on GitHub 62 | 63 | 64 | -------------------------------------------------------------------------------- /docs/tools/templates/template.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | @Title 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 |
25 |
26 | 30 |

@Properties["project-name"]

31 |
32 |
33 |
34 |
35 | @RenderBody() 36 |
37 |
38 | F# Project 39 | 58 |
59 |
60 |
61 | Fork me on GitHub 62 | 63 | 64 | -------------------------------------------------------------------------------- /lib/README.md: -------------------------------------------------------------------------------- 1 | This file is in the `lib` directory. 2 | 3 | Any **libraries** on which your project depends and which are **NOT managed via NuGet** should be kept **in this directory**. 4 | This typically includes custom builds of third-party software, private (i.e. to a company) codebases, and native libraries. 5 | 6 | --- 7 | NOTE: 8 | 9 | This file is a placeholder, used to preserve directory structure in Git. 10 | 11 | This file does not need to be edited. 12 | -------------------------------------------------------------------------------- /paket.dependencies: -------------------------------------------------------------------------------- 1 | source https://nuget.org/api/v2 2 | 3 | nuget FSharp.Formatting 4 | nuget FAKE 5 | nuget FsUnit 6 | nuget NUnit 2.6.3 7 | nuget NUnit.Runners 2.6.3 8 | nuget SourceLink.Fake 9 | 10 | github fsharp/FAKE modules/Octokit/Octokit.fsx -------------------------------------------------------------------------------- /paket.lock: -------------------------------------------------------------------------------- 1 | NUGET 2 | remote: https://nuget.org/api/v2 3 | specs: 4 | FAKE (3.23.0) 5 | FSharp.Compiler.Service (0.0.86) 6 | FSharp.Formatting (2.7.5) 7 | FSharp.Compiler.Service (>= 0.0.82) 8 | FSharpVSPowerTools.Core (>= 1.7.0) 9 | FSharpVSPowerTools.Core (1.7.0) 10 | FSharp.Compiler.Service (>= 0.0.81) 11 | FsUnit (1.3.0.1) 12 | NUnit (>= 2.6.3) 13 | Microsoft.Bcl (1.1.10) 14 | Microsoft.Bcl.Build (>= 1.0.14) 15 | Microsoft.Bcl.Build (1.0.21) 16 | Microsoft.Net.Http (2.2.29) 17 | Microsoft.Bcl (>= 1.1.10) 18 | Microsoft.Bcl.Build (>= 1.0.14) 19 | NUnit (2.6.3) 20 | NUnit.Runners (2.6.3) 21 | Octokit (0.8.0) 22 | Microsoft.Net.Http 23 | SourceLink.Fake (0.4.2) 24 | GITHUB 25 | remote: fsharp/FAKE 26 | specs: 27 | modules/Octokit/Octokit.fsx (4284c6a7d4e9f366b9b3cd8f9a0c3fbb8c921d43) 28 | Octokit -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/AssemblyInfo.fs: -------------------------------------------------------------------------------- 1 | namespace System 2 | open System.Reflection 3 | 4 | [] 5 | [] 6 | [] 7 | [] 8 | [] 9 | do () 10 | 11 | module internal AssemblyVersionInformation = 12 | let [] Version = "0.4" 13 | -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/CompileStack.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open Microsoft.FSharp.Quotations 16 | open System.Collections.Generic 17 | 18 | type internal Assumption = 19 | | IfSequential 20 | | IfRet 21 | | IfLoop 22 | | False 23 | 24 | type internal CompileStackInfo = 25 | | CompileTarget of Expr 26 | | Assumed of (Assumption * ILGeneratorWrapper -> unit) 27 | | Assumption of Assumption 28 | | Compiling of (ILGeneratorWrapper -> unit) 29 | | RestoreGen of ILGeneratorWrapper 30 | 31 | type internal CompileStack = Stack -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/DebugUtil.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open System.Reflection.Emit 16 | 17 | module internal DebugUtil = 18 | 19 | let assemblyBuilderAccess = 20 | #if DEBUG 21 | AssemblyBuilderAccess.RunAndSave 22 | #else 23 | AssemblyBuilderAccess.Run 24 | #endif 25 | 26 | let assemblyFilePath = 27 | #if DEBUG 28 | Some "output.dll" 29 | #else 30 | None 31 | #endif 32 | 33 | let label (_gen: ILGenerator) = 34 | #if DEBUG 35 | "IL_" + _gen.ILOffset.ToString("X").PadLeft(4, '0') + ": " 36 | #else 37 | "" 38 | #endif 39 | 40 | let save (asm: AssemblyBuilder) = 41 | match assemblyFilePath with 42 | | Some path -> asm.Save(path) 43 | | None -> () -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/Expr.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open Microsoft.FSharp.Quotations 16 | 17 | /// Contains the type extension for . 18 | [] 19 | module Extension = 20 | 21 | /// The type extension for the typed expression tree. 22 | type Expr<'T> with 23 | /// 24 | /// Compile the typed expression tree. 25 | /// 26 | /// 27 | /// The compilation result. 28 | /// 29 | member this.Compile() = ExprCompiler.compile this 30 | 31 | /// 32 | /// Compie and execute the typed expression tree. 33 | /// 34 | /// 35 | /// The execution result. 36 | /// 37 | member this.Execute() = this.Compile().ExecuteCompiledCode() -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/ExprUtil.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open Microsoft.FSharp.Quotations.Patterns 16 | 17 | module internal Expr = 18 | let rec getMethodInfo = function 19 | | Call (_, mi, _) -> mi 20 | | Let (_, _, body) -> getMethodInfo body 21 | | Lambda (_, body) -> getMethodInfo body 22 | | expr -> failwithf "expr is not Method call: %A" expr 23 | 24 | let getPropertyInfo = function 25 | | Let (_, _, PropertyGet (_, pi, _)) 26 | | PropertyGet (_, pi, _) -> pi 27 | | expr -> failwithf "expr is not property get: %A" expr 28 | 29 | let rec getGenericMethodInfo = function 30 | | Call (_, mi, _) -> mi.GetGenericMethodDefinition() 31 | | TryWith (_, _, _, _, Sequential (_, Call (_, mi, _))) -> mi.GetGenericMethodDefinition() 32 | | Lambda (_, body) -> getGenericMethodInfo body 33 | | expr -> failwithf "expr is not Method call: %A" expr 34 | -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/FSharp.Quotations.Compiler.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Development 6 | AnyCPU 7 | 2.0 8 | 5beaa1fd-4b61-43a0-9dc6-351c4121d877 9 | Library 10 | FSharp.Quotations.Compiler 11 | FSharp.Quotations.Compiler 12 | v4.5 13 | 4.3.0.0 14 | FSharp.Quotations.Compiler 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | false 22 | .\bin\Debug 23 | TRACE;DEBUG;DEVELOPMENT 24 | 3 25 | .\bin\Debug\FSharp.Quotations.Compiler.xml 26 | 27 | 28 | pdbonly 29 | true 30 | true 31 | .\bin\Release 32 | TRACE 33 | 3 34 | .\bin\Release\FSharp.Quotations.Compiler.xml 35 | 36 | 37 | 11 38 | 39 | 40 | true 41 | full 42 | false 43 | false 44 | TRACE;DEVELOPMENT 45 | 3 46 | .\bin\Debug\FSharp.Quotations.Compiler.xml 47 | bin\Debug\ 48 | 49 | 50 | 51 | 52 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets 53 | 54 | 55 | 56 | 57 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets 58 | 59 | 60 | 61 | 62 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | False 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/GeneratorProviders.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open System 16 | open System.Reflection 17 | open System.Reflection.Emit 18 | 19 | type internal IGeneratorProvider = 20 | abstract GetGenerator: unit -> ILGenerator 21 | 22 | type internal MethodBuilderWrapper private (moduleBuilder: ModuleBuilderWrapper, typeBuilder: TypeBuilderWrapper, builder: MethodBuilder, name: string) = 23 | static member Create(moduleBuilder, typeBuilder, builder, name) = 24 | MethodBuilderWrapper(moduleBuilder, typeBuilder, builder, name) 25 | 26 | member __.ModuleBuilder = moduleBuilder 27 | member __.RawBuilder = builder 28 | member __.Name = name 29 | member __.FullName = moduleBuilder.Name + "." + typeBuilder.Name + "." + name 30 | member __.GetGenerator() = builder.GetILGenerator() 31 | 32 | interface IGeneratorProvider with 33 | member this.GetGenerator() = this.GetGenerator() 34 | 35 | type internal CtorBuilderWrapper private (moduleBuilder: ModuleBuilderWrapper, typeBuilder: TypeBuilderWrapper, builder: ConstructorBuilder) = 36 | static member Create(moduleBuilder, typeBuilder, builder) = 37 | CtorBuilderWrapper(moduleBuilder, typeBuilder, builder) 38 | 39 | member __.ModuleBuilder = moduleBuilder 40 | member __.RawBuilder = builder 41 | member __.FullName = moduleBuilder.Name + "." + typeBuilder.Name + ".ctor" 42 | member __.GetGenerator() = builder.GetILGenerator() 43 | 44 | interface IGeneratorProvider with 45 | member this.GetGenerator() = this.GetGenerator() 46 | 47 | [] 48 | module internal TypeBuilderWrapperExtension = 49 | open Microsoft.FSharp.Quotations 50 | 51 | type TypeBuilderWrapper with 52 | member this.DefineMethod(name, attrs, retType, args: Var list) = 53 | let argsTypes = args |> List.map (fun arg -> arg.Type) 54 | let m = 55 | MethodBuilderWrapper.Create(this.Parent, this, this.RawBuilder.DefineMethod(name, attrs, retType, Array.ofList argsTypes), name) 56 | #if DEVELOPMENT 57 | m.RawBuilder.DefineParameter(0, ParameterAttributes.Out, "") |> ignore 58 | for arg, i in List.zip args [1..args.Length] do 59 | m.RawBuilder.DefineParameter(i, ParameterAttributes.In, arg.Name) |> ignore 60 | #endif 61 | m 62 | 63 | member this.DefineOverrideMethod(baseType: Type, name, attrs, retType, args: Var list) = 64 | let argsTypes = args |> List.map (fun arg -> arg.Type) 65 | let m = this.DefineMethod(name, attrs ||| MethodAttributes.Virtual, retType, args) 66 | this.RawBuilder.DefineMethodOverride(m.RawBuilder, baseType.GetMethod(name, Array.ofList argsTypes)) 67 | m 68 | 69 | member this.DefineConstructor(attrs, argNameAndTypes) = 70 | let argsTypes = argNameAndTypes |> List.map snd 71 | let c = 72 | CtorBuilderWrapper.Create(this.Parent, this, this.RawBuilder.DefineConstructor(attrs, CallingConventions.Standard, Array.ofList argsTypes)) 73 | #if DEVELOPMENT 74 | for name, i in List.zip (argNameAndTypes |> List.map fst) [1..argNameAndTypes.Length] do 75 | c.RawBuilder.DefineParameter(i, ParameterAttributes.In, name) |> ignore 76 | #endif 77 | c 78 | 79 | member this.DefineField(name, typ, attrs) = 80 | this.RawBuilder.DefineField(name, typ, attrs) -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/ILGeneratorWrapper.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open System 16 | open System.Reflection.Emit 17 | open System.Diagnostics.SymbolStore 18 | open System.IO 19 | 20 | type internal ILGeneratorWrapper private (builder: IGeneratorProvider, signature: string, gen: ILGenerator, name: string, doc: ISymbolDocumentWriter option) = 21 | let mutable lineNumber = 2 22 | let mutable indentCount = 0 23 | let mutable localVariableNumber = 0 24 | let writer = doc |> Option.map (fun _ -> let w = File.CreateText(name + ".il") in w.WriteLine("// " + signature); w) 25 | 26 | let pushIndent () = indentCount <- indentCount + 2 27 | let popIndent () = indentCount <- indentCount - 2 28 | let withIndent(str) = 29 | (String.replicate indentCount " ") + str 30 | 31 | let emittedOpCodes = ResizeArray<_>() 32 | 33 | static member Create(builder, signature, gen, name, doc) = 34 | ILGeneratorWrapper(builder, signature, gen, name, doc) 35 | 36 | member __.WriteLine(line: string) = 37 | writer |> Option.iter (fun w -> 38 | w.WriteLine(withIndent line) 39 | lineNumber <- lineNumber + 1 40 | ) 41 | member this.WriteLines(lines: string list) = lines |> List.iter (this.WriteLine) 42 | member __.WriteLineAndMark(line: string) = 43 | writer |> Option.iter (fun w -> 44 | let label = DebugUtil.label gen 45 | w.WriteLine(withIndent (label + line)) 46 | gen.MarkSequencePoint(doc.Value, lineNumber, indentCount + 1, lineNumber, indentCount + line.Length + 1) 47 | lineNumber <- lineNumber + 1 48 | ) 49 | member __.Close() = 50 | writer |> Option.iter (fun w -> w.Close()) 51 | #if DEVELOPMENT 52 | if emittedOpCodes.Count >= 3 then 53 | match emittedOpCodes |> Seq.toList |> List.rev with 54 | | last::preLast::prePreLast::_ -> 55 | assert (last = Ret) 56 | match preLast with 57 | | Call _ | Callvirt _ -> () 58 | // 本当なら有効化しておきたいが、ここで取得できるMethodInfoは値型かそうでないかの判定ができないのでコメントアウト 59 | //if prePreLast <> Tailcall then 60 | //failwith "detect tail call but did not emitted tailcall." 61 | | _ -> () 62 | | _ -> invalidOp "" 63 | #endif 64 | 65 | member this.DeclareLocal(_name: string, typ: Type) = 66 | let loc = gen.DeclareLocal(typ) 67 | #if DEVELOPMENT 68 | loc.SetLocalSymInfo(_name) 69 | this.WriteLine("// declare local: { val " + _name + ": " + typ.ToReadableText() + " }") 70 | #endif 71 | loc 72 | 73 | member this.DeclareTemp(typ: Type) = 74 | let loc = this.DeclareLocal(sprintf "$tmp_%d" localVariableNumber, typ) 75 | localVariableNumber <- localVariableNumber + 1 76 | loc 77 | 78 | member this.BeginExceptionBlock() = 79 | this.WriteLines([".try"; "{"]) 80 | pushIndent () 81 | gen.BeginExceptionBlock() 82 | member this.BeginCatchBlock(typ: Type) = 83 | popIndent () 84 | this.WriteLines(["}"; "catch " + typ.ToReadableText(); "{"]) 85 | pushIndent () 86 | gen.BeginCatchBlock(typ) 87 | member this.BeginFinallyBlock() = 88 | popIndent () 89 | this.WriteLines(["}"; "finally"; "{"]) 90 | pushIndent () 91 | gen.BeginFinallyBlock() 92 | member this.EndExceptionBlock() = 93 | popIndent () 94 | this.WriteLine("}") 95 | gen.EndExceptionBlock() 96 | member this.BeginWhileBlock() = 97 | this.WriteLine("// while start") 98 | pushIndent () 99 | let loopStart = gen.DefineLabel() 100 | let loopEnd = gen.DefineLabel() 101 | this.MarkLabel(loopStart) 102 | (loopStart, loopEnd) 103 | member this.EndWhileBlock(loopStart, loopEnd) = 104 | this.Emit(Br loopStart) 105 | popIndent () 106 | this.WriteLine("// while end") 107 | this.MarkLabel(loopEnd) 108 | member this.BeginForBlock() = 109 | this.WriteLine("// for start") 110 | pushIndent () 111 | let loopStart = gen.DefineLabel() 112 | let loopEnd = gen.DefineLabel() 113 | this.MarkLabel(loopStart) 114 | (loopStart, loopEnd) 115 | member this.EndForBlock(loopStart, loopEnd) = 116 | this.Emit(Br loopStart) 117 | popIndent () 118 | this.WriteLine("// for end") 119 | this.MarkLabel(loopEnd) 120 | 121 | member __.DefineLabel() = gen.DefineLabel() 122 | member this.MarkLabel(label) = 123 | this.WriteLine(string (label.GetHashCode()) + ": ") 124 | gen.MarkLabel(label) 125 | 126 | member __.EmittedOpCodes = emittedOpCodes.AsReadOnly() 127 | 128 | member this.Emit(opcode) = 129 | emittedOpCodes.Add(opcode) 130 | let raw = ILOpCode.toRawOpCode opcode 131 | match opcode with 132 | | Bgt label | Brfalse label | Br label -> 133 | this.WriteLineAndMark(raw.Name + " " + string (label.GetHashCode())) 134 | gen.Emit(raw, label) 135 | | Leave label -> 136 | this.WriteLineAndMark(raw.Name) 137 | gen.Emit(raw, label) 138 | | Stloc (local, nameOpt) | Ldloc (local, nameOpt) | Ldloca (local, nameOpt) -> 139 | let hint = match nameOpt with Some name -> " // " + name | None -> "" 140 | this.WriteLineAndMark(raw.Name + " " + string local.LocalIndex + hint) 141 | gen.Emit(raw, local) 142 | | Stsfld fld | Ldsfld fld | Stfld fld | Ldfld fld | Ldflda fld -> 143 | this.WriteLineAndMark(raw.Name + " " + (fld.ToReadableText())) 144 | gen.Emit(raw, fld) 145 | | Ldstr str -> 146 | this.WriteLineAndMark(raw.Name + " \"" + str + "\"") 147 | gen.Emit(raw, str) 148 | | Ldc_I4_S i | Ldc_I4 i | Ldarg i | Ldarga i | Starg i -> 149 | this.WriteLineAndMark(raw.Name + " " + string i) 150 | gen.Emit(raw, i) 151 | | Ldc_I8 i -> 152 | this.WriteLineAndMark(raw.Name + " " + string i) 153 | gen.Emit(raw, i) 154 | | Ldc_R4 x -> 155 | this.WriteLineAndMark(raw.Name + " " + x.ToStringWithRichInfo()) 156 | gen.Emit(raw, x) 157 | | Ldc_R8 x -> 158 | this.WriteLineAndMark(raw.Name + " " + x.ToStringWithRichInfo()) 159 | gen.Emit(raw, x) 160 | | Ldtoken tok -> 161 | match tok with 162 | | TokType t -> 163 | this.WriteLineAndMark(raw.Name + " " + t.ToReadableText()) 164 | gen.Emit(raw, t) 165 | | TokMethod m -> 166 | this.WriteLineAndMark(raw.Name + " " + m.ToReadableText()) 167 | gen.Emit(raw, m) 168 | | TokField f -> 169 | this.WriteLineAndMark(raw.Name + " " + f.ToReadableText()) 170 | gen.Emit(raw, f) 171 | | Call target | Callvirt target -> 172 | match target with 173 | | Method mi -> 174 | this.WriteLineAndMark(raw.Name + " " + mi.ToReadableText()) 175 | gen.Emit(raw, mi) 176 | | Ctor ci -> 177 | this.WriteLineAndMark(raw.Name + " " + ci.ToReadableText()) 178 | gen.Emit(raw, ci) 179 | | PropGet pi -> 180 | this.WriteLineAndMark(raw.Name + " " + pi.ToReadableText()) 181 | gen.Emit(raw, pi.GetMethod) 182 | | Newarr typ | Stelem typ | Initobj typ | Box typ | Unbox_Any typ | Isinst typ | Constrainted typ -> 183 | this.WriteLineAndMark(raw.Name + " " + typ.ToReadableText()) 184 | gen.Emit(raw, typ) 185 | | Newobj ci -> 186 | this.WriteLineAndMark(raw.Name + " " + ci.ToReadableText()) 187 | gen.Emit(raw, ci) 188 | | And | Or | Xor | Not | Shl | Shr | Shr_Un | Div | Div_Un | Mul | Mul_Ovf | Mul_Ovf_Un | Neg | Rem | Rem_Un | Add | Sub | Sub_Ovf | Sub_Ovf_Un 189 | | Conv_I | Conv_I1 | Conv_I2 | Conv_I4 | Conv_I8 190 | | Conv_U | Conv_U1 | Conv_U2 | Conv_U4 | Conv_U8 191 | | Conv_R_Un | Conv_R4 | Conv_R8 192 | | Conv_Ovf_I | Conv_Ovf_I1 | Conv_Ovf_I2 | Conv_Ovf_I4 | Conv_Ovf_I8 193 | | Conv_Ovf_U | Conv_Ovf_U1 | Conv_Ovf_U2 | Conv_Ovf_U4 | Conv_Ovf_U8 194 | | Conv_Ovf_I_Un | Conv_Ovf_I1_Un | Conv_Ovf_I2_Un | Conv_Ovf_I4_Un | Conv_Ovf_I8_Un 195 | | Conv_Ovf_U_Un | Conv_Ovf_U1_Un | Conv_Ovf_U2_Un | Conv_Ovf_U4_Un | Conv_Ovf_U8_Un 196 | | Ldarg_0 | Ldarg_1 | Ldarg_2 | Ldarg_3 197 | | Ldnull | Ldc_I4_M1 | Ldc_I4_0 | Ldc_I4_1 | Ldc_I4_2 | Ldc_I4_3 | Ldc_I4_4 | Ldc_I4_5 | Ldc_I4_6 | Ldc_I4_7 | Ldc_I4_8 198 | | Tailcall | Dup | Pop | Rethrow | Ret | Endfinally -> 199 | this.WriteLineAndMark(raw.Name) 200 | gen.Emit(raw) 201 | 202 | [] 203 | module internal GeneratorProvidersExtension = 204 | open Microsoft.FSharp.Quotations 205 | 206 | let private defineDoc (_name: string) (_builder: ModuleBuilderWrapper) = 207 | #if DEVELOPMENT 208 | Some (_builder.RawBuilder.DefineDocument(_name + ".il", SymDocumentType.Text, SymLanguageType.ILAssembly, SymLanguageVendor.Microsoft)) 209 | #else 210 | None 211 | #endif 212 | 213 | let methodSig name (args: Var list) (retType: Type) = 214 | let argsStr = args |> List.map (fun v -> v.Name + ":" + v.Type.ToReadableText()) |> String.concat " -> " 215 | name + " : " + (if argsStr = "" then "unit" else argsStr) + " -> " + retType.ToReadableText() 216 | 217 | type MethodBuilderWrapper with 218 | member this.GetILGenerator(retType: Type) = 219 | let gen = this.GetGenerator() 220 | let doc = defineDoc this.FullName this.ModuleBuilder 221 | ILGeneratorWrapper.Create(this, methodSig this.Name [] retType, gen, this.FullName, doc) 222 | member this.GetILGenerator(arg: Var, retType: Type) = 223 | let gen = this.GetGenerator() 224 | let doc = defineDoc this.FullName this.ModuleBuilder 225 | ILGeneratorWrapper.Create(this, methodSig this.Name [arg] retType, gen, this.FullName, doc) 226 | 227 | let ctorSig (varNamesAndTypes: (string * Type) list) = 228 | let str = varNamesAndTypes |> List.map (fun (n, t) -> n + ":" + t.ToReadableText()) |> String.concat " -> " 229 | "new : " + str + " -> this" 230 | 231 | type CtorBuilderWrapper with 232 | member this.GetILGenerator(varNamesAndTypes: (string * Type) list) = 233 | let gen = this.GetGenerator() 234 | let doc = defineDoc this.FullName this.ModuleBuilder 235 | ILGeneratorWrapper.Create(this, ctorSig varNamesAndTypes, gen, this.FullName, doc) 236 | -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/ILOpCode.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open System 16 | open System.Reflection 17 | open System.Reflection.Emit 18 | 19 | type internal CallTarget = 20 | | Method of MethodInfo 21 | | Ctor of ConstructorInfo 22 | | PropGet of PropertyInfo 23 | 24 | type internal Token = 25 | | TokType of Type 26 | | TokMethod of MethodInfo 27 | | TokField of FieldInfo 28 | 29 | type internal ILOpCode = 30 | | And 31 | | Or 32 | | Xor 33 | | Not 34 | | Shl 35 | | Shr 36 | | Shr_Un 37 | | Div 38 | | Div_Un 39 | | Mul 40 | | Mul_Ovf 41 | | Mul_Ovf_Un 42 | | Neg 43 | | Rem 44 | | Rem_Un 45 | | Add 46 | | Sub 47 | | Sub_Ovf 48 | | Sub_Ovf_Un 49 | | Bgt of Label 50 | | Brfalse of Label 51 | | Br of Label 52 | | Leave of Label 53 | | Endfinally 54 | | Isinst of Type 55 | | Conv_I 56 | | Conv_I1 57 | | Conv_I2 58 | | Conv_I4 59 | | Conv_I8 60 | | Conv_R_Un 61 | | Conv_R4 62 | | Conv_R8 63 | | Conv_U 64 | | Conv_U1 65 | | Conv_U2 66 | | Conv_U4 67 | | Conv_U8 68 | | Conv_Ovf_I 69 | | Conv_Ovf_I1 70 | | Conv_Ovf_I2 71 | | Conv_Ovf_I4 72 | | Conv_Ovf_I8 73 | | Conv_Ovf_U 74 | | Conv_Ovf_U1 75 | | Conv_Ovf_U2 76 | | Conv_Ovf_U4 77 | | Conv_Ovf_U8 78 | | Conv_Ovf_I_Un 79 | | Conv_Ovf_I1_Un 80 | | Conv_Ovf_I2_Un 81 | | Conv_Ovf_I4_Un 82 | | Conv_Ovf_I8_Un 83 | | Conv_Ovf_U_Un 84 | | Conv_Ovf_U1_Un 85 | | Conv_Ovf_U2_Un 86 | | Conv_Ovf_U4_Un 87 | | Conv_Ovf_U8_Un 88 | | Box of Type 89 | | Unbox_Any of Type 90 | | Stloc of LocalBuilder * string option 91 | | Ldloc of LocalBuilder * string option 92 | | Ldloca of LocalBuilder * string option 93 | | Starg of int 94 | | Ldarg_0 95 | | Ldarg_1 96 | | Ldarg_2 97 | | Ldarg_3 98 | | Ldarg of int 99 | | Ldarga of int 100 | | Stsfld of FieldInfo 101 | | Ldsfld of FieldInfo 102 | | Stfld of FieldInfo 103 | | Ldfld of FieldInfo 104 | | Ldflda of FieldInfo 105 | | Ldnull 106 | | Ldstr of string 107 | | Ldc_I4_M1 108 | | Ldc_I4_0 109 | | Ldc_I4_1 110 | | Ldc_I4_2 111 | | Ldc_I4_3 112 | | Ldc_I4_4 113 | | Ldc_I4_5 114 | | Ldc_I4_6 115 | | Ldc_I4_7 116 | | Ldc_I4_8 117 | | Ldc_I4_S of int 118 | | Ldc_I4 of int 119 | | Ldc_I8 of int64 120 | | Ldc_R4 of float32 121 | | Ldc_R8 of float 122 | | Stelem of Type 123 | | Ldtoken of Token 124 | | Tailcall 125 | | Constrainted of Type 126 | | Call of CallTarget 127 | | Callvirt of CallTarget 128 | | Newarr of Type 129 | | Newobj of ConstructorInfo 130 | | Initobj of Type 131 | | Dup 132 | | Pop 133 | | Rethrow 134 | | Ret 135 | 136 | [] 137 | module internal ILOpCode = 138 | let stloc local _nameOpt = 139 | #if DEVELOPMENT 140 | Stloc (local, Some _nameOpt) 141 | #else 142 | Stloc (local, None) 143 | #endif 144 | 145 | let ldloc local _nameOpt = 146 | #if DEVELOPMENT 147 | Ldloc (local, Some _nameOpt) 148 | #else 149 | Ldloc (local, None) 150 | #endif 151 | 152 | let ldloca local _nameOpt = 153 | #if DEVELOPMENT 154 | Ldloca (local, Some _nameOpt) 155 | #else 156 | Ldloca (local, None) 157 | #endif 158 | 159 | let toRawOpCode = function 160 | | And -> OpCodes.And 161 | | Or -> OpCodes.Or 162 | | Xor -> OpCodes.Xor 163 | | Not -> OpCodes.Not 164 | | Shl -> OpCodes.Shl 165 | | Shr -> OpCodes.Shr 166 | | Shr_Un -> OpCodes.Shr_Un 167 | | Div -> OpCodes.Div 168 | | Div_Un -> OpCodes.Div_Un 169 | | Mul -> OpCodes.Mul 170 | | Mul_Ovf -> OpCodes.Mul_Ovf 171 | | Mul_Ovf_Un -> OpCodes.Mul_Ovf_Un 172 | | Neg -> OpCodes.Neg 173 | | Rem -> OpCodes.Rem 174 | | Rem_Un -> OpCodes.Rem_Un 175 | | Add -> OpCodes.Add 176 | | Sub -> OpCodes.Sub 177 | | Sub_Ovf -> OpCodes.Sub_Ovf 178 | | Sub_Ovf_Un -> OpCodes.Sub_Ovf_Un 179 | | Bgt _ -> OpCodes.Bgt 180 | | Brfalse _ -> OpCodes.Brfalse 181 | | Br _ -> OpCodes.Br 182 | | Leave _ -> OpCodes.Leave 183 | | Endfinally -> OpCodes.Endfinally 184 | | Isinst _ -> OpCodes.Isinst 185 | | Conv_I -> OpCodes.Conv_I 186 | | Conv_I1 -> OpCodes.Conv_I1 187 | | Conv_I2 -> OpCodes.Conv_I2 188 | | Conv_I4 -> OpCodes.Conv_I4 189 | | Conv_I8 -> OpCodes.Conv_I8 190 | | Conv_U -> OpCodes.Conv_U 191 | | Conv_U1 -> OpCodes.Conv_U1 192 | | Conv_U2 -> OpCodes.Conv_U2 193 | | Conv_U4 -> OpCodes.Conv_U4 194 | | Conv_U8 -> OpCodes.Conv_U8 195 | | Conv_R_Un -> OpCodes.Conv_R_Un 196 | | Conv_R4 -> OpCodes.Conv_R4 197 | | Conv_R8 -> OpCodes.Conv_R8 198 | | Conv_Ovf_I -> OpCodes.Conv_Ovf_I 199 | | Conv_Ovf_I1 -> OpCodes.Conv_Ovf_I1 200 | | Conv_Ovf_I2 -> OpCodes.Conv_Ovf_I2 201 | | Conv_Ovf_I4 -> OpCodes.Conv_Ovf_I4 202 | | Conv_Ovf_I8 -> OpCodes.Conv_Ovf_I8 203 | | Conv_Ovf_U -> OpCodes.Conv_Ovf_U 204 | | Conv_Ovf_U1 -> OpCodes.Conv_Ovf_U1 205 | | Conv_Ovf_U2 -> OpCodes.Conv_Ovf_U2 206 | | Conv_Ovf_U4 -> OpCodes.Conv_Ovf_U4 207 | | Conv_Ovf_U8 -> OpCodes.Conv_Ovf_U8 208 | | Conv_Ovf_I_Un -> OpCodes.Conv_Ovf_I_Un 209 | | Conv_Ovf_I1_Un -> OpCodes.Conv_Ovf_I1_Un 210 | | Conv_Ovf_I2_Un -> OpCodes.Conv_Ovf_I2_Un 211 | | Conv_Ovf_I4_Un -> OpCodes.Conv_Ovf_I4_Un 212 | | Conv_Ovf_I8_Un -> OpCodes.Conv_Ovf_I8_Un 213 | | Conv_Ovf_U_Un -> OpCodes.Conv_Ovf_U_Un 214 | | Conv_Ovf_U1_Un -> OpCodes.Conv_Ovf_U1_Un 215 | | Conv_Ovf_U2_Un -> OpCodes.Conv_Ovf_U2_Un 216 | | Conv_Ovf_U4_Un -> OpCodes.Conv_Ovf_U4_Un 217 | | Conv_Ovf_U8_Un -> OpCodes.Conv_Ovf_U8_Un 218 | | Box _ -> OpCodes.Box 219 | | Unbox_Any _ -> OpCodes.Unbox_Any 220 | | Stloc _ -> OpCodes.Stloc 221 | | Ldloc _ -> OpCodes.Ldloc 222 | | Ldloca _ -> OpCodes.Ldloca 223 | | Starg _ -> OpCodes.Starg 224 | | Ldarg_0 -> OpCodes.Ldarg_0 225 | | Ldarg_1 -> OpCodes.Ldarg_1 226 | | Ldarg_2 -> OpCodes.Ldarg_2 227 | | Ldarg_3 -> OpCodes.Ldarg_3 228 | | Ldarg _ -> OpCodes.Ldarg 229 | | Ldarga _ -> OpCodes.Ldarga 230 | | Stsfld _ -> OpCodes.Stsfld 231 | | Ldsfld _ -> OpCodes.Ldsfld 232 | | Stfld _ -> OpCodes.Stfld 233 | | Ldfld _ -> OpCodes.Ldfld 234 | | Ldflda _ -> OpCodes.Ldflda 235 | | Ldnull -> OpCodes.Ldnull 236 | | Ldstr _ -> OpCodes.Ldstr 237 | | Ldc_I4_M1 -> OpCodes.Ldc_I4_M1 238 | | Ldc_I4_0 -> OpCodes.Ldc_I4_0 239 | | Ldc_I4_1 -> OpCodes.Ldc_I4_1 240 | | Ldc_I4_2 -> OpCodes.Ldc_I4_2 241 | | Ldc_I4_3 -> OpCodes.Ldc_I4_3 242 | | Ldc_I4_4 -> OpCodes.Ldc_I4_4 243 | | Ldc_I4_5 -> OpCodes.Ldc_I4_5 244 | | Ldc_I4_6 -> OpCodes.Ldc_I4_6 245 | | Ldc_I4_7 -> OpCodes.Ldc_I4_7 246 | | Ldc_I4_8 -> OpCodes.Ldc_I4_8 247 | | Ldc_I4_S _ -> OpCodes.Ldc_I4_S 248 | | Ldc_I4 _ -> OpCodes.Ldc_I4 249 | | Ldc_I8 _ -> OpCodes.Ldc_I8 250 | | Ldc_R4 _ -> OpCodes.Ldc_R4 251 | | Ldc_R8 _ -> OpCodes.Ldc_R8 252 | | Stelem _ -> OpCodes.Stelem 253 | | Ldtoken _ -> OpCodes.Ldtoken 254 | | Tailcall -> OpCodes.Tailcall 255 | | Constrainted _ -> OpCodes.Constrained 256 | | Call _ -> OpCodes.Call 257 | | Callvirt _ -> OpCodes.Callvirt 258 | | Newarr _ -> OpCodes.Newarr 259 | | Newobj _ -> OpCodes.Newobj 260 | | Initobj _ -> OpCodes.Initobj 261 | | Dup -> OpCodes.Dup 262 | | Pop -> OpCodes.Pop 263 | | Rethrow -> OpCodes.Rethrow 264 | | Ret -> OpCodes.Ret -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/LambdaEmitter.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open System 16 | open System.Reflection 17 | open System.Reflection.Emit 18 | open Microsoft.FSharp.Quotations 19 | 20 | module internal LambdaEmitter = 21 | let private emitCtor (baseType: Type) (lambda: TypeBuilderWrapper) (fields: FieldBuilder list) (varEnv: VariableEnv) = 22 | let varNamesAndTypes = varEnv |> List.map (fun (v, _) -> (v.Name, v.Type)) 23 | let baseCtor = baseType.GetConstructor(BindingFlags.NonPublic ||| BindingFlags.Instance, null, [||], null) 24 | let ctor = lambda.DefineConstructor(MethodAttributes.Public, varNamesAndTypes) 25 | let ctorGen = ctor.GetILGenerator(varNamesAndTypes) 26 | try 27 | // emit: call base ctor 28 | ctorGen.Emit(Ldarg_0) 29 | if varNamesAndTypes = [] then 30 | ctorGen.Emit(Tailcall) 31 | ctorGen.Emit(Call (Ctor baseCtor)) 32 | 33 | for i, field in List.zip [1..fields.Length] fields do 34 | // emit: this.field <- arg_i 35 | ctorGen.Emit(Ldarg_0) 36 | ctorGen.Emit(Ldarg i) 37 | ctorGen.Emit(Stfld field) 38 | ctorGen.Emit(Ret) 39 | ctor.RawBuilder :> ConstructorInfo 40 | finally 41 | ctorGen.Close() 42 | 43 | let private emitInvoke (baseType: Type) (lambda: TypeBuilderWrapper, fields, ctor) (gen, varEnvRef: VariableEnv ref, needVarInfos: VariableEnv, argVar: Var, bodyType: Type) bodyCompileInfo (stack: CompileStack) = 44 | let varEnv = !varEnvRef 45 | 46 | let invoke = lambda.DefineOverrideMethod(baseType, "Invoke", MethodAttributes.Public, bodyType, [ argVar ]) 47 | let invokeGen = invoke.GetILGenerator(argVar, bodyType) 48 | stack.Push(Compiling (fun _ -> 49 | varEnvRef := varEnv 50 | )) 51 | stack.Push(Compiling (fun gen -> 52 | for _, info in needVarInfos do 53 | match info with 54 | | Arg i -> gen.Emit(Ldarg i) 55 | | Local (local, name) -> gen.Emit(ILOpCode.ldloc local name) 56 | | Field fi -> gen.Emit(Ldarg_0); gen.Emit(Ldfld fi) 57 | gen.Emit(Newobj ctor) 58 | )) 59 | stack.Push(RestoreGen gen) 60 | 61 | stack.Push(Compiling (fun gen -> 62 | gen.Emit(Ret) 63 | lambda.CreateType() |> ignore 64 | )) 65 | stack.Push(Assumption IfRet) 66 | stack.Push(bodyCompileInfo) 67 | let newVarEnv = List.zip needVarInfos fields |> List.map (fun ((var, _), fi) -> (var, Field fi)) 68 | stack.Push(Compiling (fun _ -> 69 | varEnvRef := (argVar, Arg 1)::newVarEnv 70 | )) 71 | 72 | invokeGen 73 | 74 | let emit (parentMod: ModuleBuilderWrapper) (gen, varEnvRef: VariableEnv ref, argVar: Var, bodyType: Type) bodyCompileInfo (stack: CompileStack) = 75 | let varEnv = !varEnvRef 76 | 77 | let lambda = parentMod.DefineLambda(argVar.Type, bodyType) 78 | let baseType = lambda.BaseType 79 | 80 | let needVarInfos = 81 | varEnv 82 | |> List.fold (fun acc (v, info) -> if List.forall (fun (v2, _) -> v <> v2) acc then (v, info)::acc else acc) [] 83 | |> List.rev 84 | 85 | let fields = needVarInfos |> List.map (fun (var, _) -> lambda.DefineField(var.Name, var.Type, FieldAttributes.Private)) 86 | let ctor = emitCtor baseType lambda fields needVarInfos 87 | emitInvoke baseType (lambda, fields, ctor) (gen, varEnvRef, needVarInfos, argVar, bodyType) bodyCompileInfo stack 88 | -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/ModuleBuilderWrapper.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open System.Reflection.Emit 16 | open System.Diagnostics 17 | open System.Collections.Generic 18 | 19 | [] 20 | module internal ModuleBuilder = 21 | 22 | let private setDebuggingAttr (asm: AssemblyBuilder) = 23 | let attr = typeof 24 | let ctor = attr.GetConstructor([| typeof |]) 25 | let builder = CustomAttributeBuilder(ctor, [| DebuggableAttribute.DebuggingModes.DisableOptimizations ||| DebuggableAttribute.DebuggingModes.Default |]) 26 | asm.SetCustomAttribute(builder) 27 | 28 | let defineDynamicModule name (asm: AssemblyBuilder) = 29 | #if DEVELOPMENT 30 | setDebuggingAttr asm 31 | match DebugUtil.assemblyFilePath with 32 | | Some path -> asm.DefineDynamicModule(name, path, true) 33 | | None -> asm.DefineDynamicModule(name, true) 34 | #else 35 | asm.DefineDynamicModule(name) 36 | #endif 37 | 38 | type internal ModuleBuilderWrapper private (builder: ModuleBuilder, name: string) = 39 | let countDict = Dictionary() 40 | static member Create(asm: AssemblyBuilder, name: string) = 41 | ModuleBuilderWrapper(ModuleBuilder.defineDynamicModule name asm, name) 42 | 43 | member __.RawBuilder = builder 44 | member __.Name = name 45 | 46 | member __.FreshTypeName(typeNamePrefix: string) = 47 | match countDict.TryGetValue(typeNamePrefix) with 48 | | true, count -> 49 | let res = typeNamePrefix + (string count) 50 | countDict.[typeNamePrefix] <- count + 1 51 | res 52 | | false, _ -> 53 | countDict.Add(typeNamePrefix, 1) 54 | typeNamePrefix + "0" -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/NullableOpTranslator.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open System.Reflection 16 | open Microsoft.FSharp.Quotations 17 | open Microsoft.FSharp.Linq.NullableOperators 18 | 19 | module internal NullableOpTranslator = 20 | 21 | let (|Op|_|) expr altOpExpr (mi: MethodInfo) = 22 | let genMethod = Expr.getGenericMethodInfo expr 23 | if genMethod = mi then 24 | let altGenOp = Expr.getGenericMethodInfo altOpExpr 25 | Some altGenOp 26 | else 27 | None 28 | 29 | let transIfNeed (mi: MethodInfo) (argsExprs: Expr list) (stack: CompileStack) = 30 | if mi.IsGenericMethod then 31 | match mi.GetGenericMethodDefinition() with 32 | | Op <@ (?-) @> <@ (-) @> op 33 | | Op <@ (?/) @> <@ (/) @> op 34 | | Op <@ (?%) @> <@ (%) @> op -> 35 | let op = op.MakeGenericMethod(mi.GetGenericArguments()) 36 | let lhs = argsExprs.[0] 37 | let rhs = argsExprs.[1] 38 | let tmp = Var("$tmp", lhs.Type) 39 | let hasValue = lhs.Type.GetProperty("HasValue") 40 | let value = lhs.Type.GetProperty("Value") 41 | let expr = 42 | Expr.Let( 43 | tmp, 44 | lhs, 45 | Expr.IfThenElse( 46 | Expr.PropertyGet(Expr.Var(tmp), hasValue), 47 | Expr.NewObject( 48 | mi.ReturnType.GetConstructor([|op.ReturnType|]), 49 | [Expr.Call(op, [Expr.PropertyGet(Expr.Var(tmp), value); rhs])]), 50 | Expr.DefaultValue(mi.ReturnType) 51 | )) 52 | stack.Push(CompileTarget expr) 53 | true 54 | | Op <@ (-?) @> <@ (-) @> op 55 | | Op <@ (/?) @> <@ (/) @> op 56 | | Op <@ (%?) @> <@ (%) @> op -> 57 | let op = op.MakeGenericMethod(mi.GetGenericArguments()) 58 | let lhs = argsExprs.[0] 59 | let rhs = argsExprs.[1] 60 | let tmp = Var("$tmp", rhs.Type) 61 | let hasValue = rhs.Type.GetProperty("HasValue") 62 | let value = rhs.Type.GetProperty("Value") 63 | let expr = 64 | Expr.Let( 65 | tmp, 66 | rhs, 67 | Expr.IfThenElse( 68 | Expr.PropertyGet(Expr.Var(tmp), hasValue), 69 | Expr.NewObject( 70 | mi.ReturnType.GetConstructor([|op.ReturnType|]), 71 | [Expr.Call(op, [lhs; Expr.PropertyGet(Expr.Var(tmp), value)])]), 72 | Expr.DefaultValue(mi.ReturnType) 73 | )) 74 | stack.Push(CompileTarget expr) 75 | true 76 | | Op <@ (?-?) @> <@ (-) @> op 77 | | Op <@ (?/?) @> <@ (/) @> op 78 | | Op <@ (?%?) @> <@ (%) @> op -> 79 | let op = op.MakeGenericMethod(mi.GetGenericArguments()) 80 | let lhs = argsExprs.[0] 81 | let rhs = argsExprs.[1] 82 | let tmp1 = Var("$tmp1", lhs.Type) 83 | let hasValue1 = lhs.Type.GetProperty("HasValue") 84 | let value1 = lhs.Type.GetProperty("Value") 85 | let tmp2 = Var("$tmp2", rhs.Type) 86 | let hasValue2 = rhs.Type.GetProperty("HasValue") 87 | let value2 = rhs.Type.GetProperty("Value") 88 | let expr = 89 | Expr.Let( 90 | tmp1, 91 | lhs, 92 | Expr.Let( 93 | tmp2, 94 | rhs, 95 | Expr.IfThenElse( 96 | <@@ %%(Expr.PropertyGet(Expr.Var(tmp1), hasValue1)) && %%(Expr.PropertyGet(Expr.Var(tmp2), hasValue2)) @@>, 97 | Expr.NewObject( 98 | mi.ReturnType.GetConstructor([|op.ReturnType|]), 99 | [Expr.Call(op, [Expr.PropertyGet(Expr.Var(tmp1), value1); Expr.PropertyGet(Expr.Var(tmp2), value2)])]), 100 | Expr.DefaultValue(mi.ReturnType) 101 | ))) 102 | stack.Push(CompileTarget expr) 103 | true 104 | | _ -> false 105 | else 106 | false -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/Stringizer.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open System 16 | open System.Reflection 17 | 18 | [] 19 | module internal Stringizer = 20 | 21 | let rec private toSimpleName (typ: Type) = 22 | if typ = typeof then "obj" 23 | elif typ = typeof then "unit" 24 | elif typ = typeof then "unit" 25 | elif typ = typeof then "int" 26 | elif typ = typeof then "char" 27 | elif typ = typeof then "float" 28 | elif typ = typeof then "bool" 29 | elif typ = typeof then "string" 30 | elif typ = typeof then "exn" 31 | else 32 | if typ.IsGenericType then 33 | let genTypeDef = typ.GetGenericTypeDefinition() 34 | if genTypeDef = typedefof<_ list> then 35 | toSimpleName (typ.GetGenericArguments().[0]) + " list" 36 | elif genTypeDef = typedefof<_ option> then 37 | toSimpleName (typ.GetGenericArguments().[0]) + " option" 38 | elif genTypeDef = typedefof<_ seq> then 39 | toSimpleName (typ.GetGenericArguments().[0]) + " seq" 40 | elif genTypeDef = typedefof> then 41 | "Map<" + toSimpleName (typ.GetGenericArguments().[0]) + ", " + toSimpleName (typ.GetGenericArguments().[1]) + ">" 42 | elif genTypeDef = typedefof<_ -> _> then 43 | "(" + toSimpleName (typ.GetGenericArguments().[0]) + " -> " + toSimpleName (typ.GetGenericArguments().[1]) + ")" 44 | elif genTypeDef = typedefof> then 45 | toSimpleName (typ.GetGenericArguments().[0]) 46 | elif genTypeDef = typedefof<_ * _> then 47 | String.concat " * " (typ.GetGenericArguments() |> Array.map toSimpleName) 48 | elif genTypeDef = typedefof<_ * _ * _> then 49 | String.concat " * " (typ.GetGenericArguments() |> Array.map toSimpleName) 50 | elif genTypeDef = typedefof<_ * _ * _ * _> then 51 | String.concat " * " (typ.GetGenericArguments() |> Array.map toSimpleName) 52 | elif genTypeDef = typedefof<_ * _ * _ * _ * _> then 53 | String.concat " * " (typ.GetGenericArguments() |> Array.map toSimpleName) 54 | elif genTypeDef = typedefof<_ * _ * _ * _ * _ * _> then 55 | String.concat " * " (typ.GetGenericArguments() |> Array.map toSimpleName) 56 | elif genTypeDef = typedefof<_ * _ * _ * _ * _ * _ * _> then 57 | String.concat " * " (typ.GetGenericArguments() |> Array.map toSimpleName) 58 | elif genTypeDef = typedefof> then 59 | let strTo7 = 60 | String.concat " * " (typ.GetGenericArguments().[0..6] |> Array.map toSimpleName) 61 | strTo7 + " * " + toSimpleName (typ.GetGenericArguments().[7]) 62 | else 63 | let genArgs = typ.GetGenericArguments() 64 | let str = string typ 65 | let pos = str.IndexOf("`") 66 | str.Substring(0, pos) + "<" + (String.concat ", " (genArgs |> Array.map toSimpleName)) + ">" 67 | elif typ.IsArray then 68 | (toSimpleName (typ.GetElementType())) + "[]" 69 | else 70 | string typ 71 | 72 | type Type with 73 | member this.ToReadableText() = toSimpleName this 74 | 75 | type FieldInfo with 76 | member this.ToReadableText() = 77 | let typ = this.DeclaringType.ToReadableText() 78 | typ + "." + this.Name 79 | 80 | type MethodInfo with 81 | member this.ToReadableText() = 82 | let retType = this.ReturnType.ToReadableText() 83 | let selfType = this.DeclaringType.ToReadableText() 84 | let paramsType = this.GetParameters() |> Array.map (fun p -> p.ParameterType.ToReadableText()) |> String.concat ", " 85 | match this.GetGenericArguments() with 86 | | null | [||] -> retType + " " + selfType + "." + this.Name + "(" + paramsType + ")" 87 | | genericArgs -> 88 | let str = this.Name 89 | let genericArgs = genericArgs |> Array.map (fun a -> a.ToReadableText()) |> String.concat ", " 90 | match str.IndexOf("`") with 91 | | -1 -> retType + " " + selfType + "." + this.Name + "<" + genericArgs + ">(" + paramsType + ")" 92 | | pos -> retType + " " + selfType + "." + this.Name.Substring(0, pos) + "<" + genericArgs + ">(" + paramsType + ")" 93 | 94 | type ConstructorInfo with 95 | member this.ToReadableText() = 96 | let paramsType = this.GetParameters() |> Array.map (fun p -> p.ParameterType.ToReadableText()) |> String.concat ", " 97 | this.DeclaringType.ToReadableText() + ".ctor(" + paramsType + ")" 98 | 99 | type PropertyInfo with 100 | member this.ToReadableText() = 101 | let retType = this.PropertyType.ToReadableText() 102 | let selfType = this.DeclaringType.ToReadableText() 103 | let paramsType = this.GetIndexParameters() |> Array.map (fun p -> p.ParameterType.ToReadableText()) |> String.concat ", " 104 | retType + " " + selfType + "." + this.Name + "[" + paramsType + "]" 105 | 106 | let private b2s (b: byte) = b.ToString("X").PadLeft(2, '0') 107 | let private richInfoStr (x: float) = 108 | if Double.IsNaN(x) then "// NaN" 109 | elif Double.IsPositiveInfinity(x) then "// infinity" 110 | elif Double.IsNegativeInfinity(x) then "// -infinity" 111 | else 112 | let str = string x 113 | try 114 | if float str = x then "// " + str 115 | else "// about " + str 116 | with 117 | _ -> "// about " + str 118 | 119 | type Double with 120 | member private this.ToBytesStr() = 121 | "(" + (BitConverter.GetBytes(this) |> Array.map b2s |> String.concat " ") + ")" 122 | 123 | member this.ToStringWithRichInfo() = 124 | let bytesStr = this.ToBytesStr() 125 | bytesStr + " " + richInfoStr this 126 | 127 | let private richInfoStr2 (x: float32) = 128 | if Single.IsNaN(x) then "// NaN" 129 | elif Single.IsPositiveInfinity(x) then "// infinity" 130 | elif Single.IsNegativeInfinity(x) then "// -infinity" 131 | else 132 | let str = string x 133 | try 134 | if float32 str = x then "// " + str 135 | else "// about " + str 136 | with 137 | _ -> "// about " + str 138 | 139 | type Single with 140 | member private this.ToBytesStr() = 141 | "(" + (BitConverter.GetBytes(this) |> Array.map b2s |> String.concat " ") + ")" 142 | 143 | member this.ToStringWithRichInfo() = 144 | let bytesStr = this.ToBytesStr() 145 | bytesStr + " " + richInfoStr2 this -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/TupleEmitter.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open System 16 | open Microsoft.FSharp.Quotations 17 | open Microsoft.FSharp.Quotations.Patterns 18 | open Microsoft.FSharp.Reflection 19 | 20 | module internal TupleEmitter = 21 | let private getMethod = function 22 | | Call (_, mi, _) -> mi 23 | | expr -> failwithf "expr is not Method call: %A" expr 24 | 25 | let private getTypeFromHandleM = getMethod <@ Type.GetTypeFromHandle(RuntimeTypeHandle()) @> 26 | let private makeTupleM = getMethod <@ FSharpValue.MakeTuple([||], typeof) @> 27 | let private unboxGenericM = (getMethod <@ (null: obj) :?> string @>).GetGenericMethodDefinition() 28 | 29 | let private newTuple1 types = typedefof>.MakeGenericType(types).GetConstructor(types) 30 | let private newTuple2 types = typedefof<_ * _>.MakeGenericType(types).GetConstructor(types) 31 | let private newTuple3 types = typedefof<_ * _ * _>.MakeGenericType(types).GetConstructor(types) 32 | let private newTuple4 types = typedefof<_ * _ * _ * _>.MakeGenericType(types).GetConstructor(types) 33 | let private newTuple5 types = typedefof<_ * _ * _ * _ * _>.MakeGenericType(types).GetConstructor(types) 34 | let private newTuple6 types = typedefof<_ * _ * _ * _ * _ * _>.MakeGenericType(types).GetConstructor(types) 35 | let private newTuple7 types = typedefof<_ * _ * _ * _ * _ * _ * _>.MakeGenericType(types).GetConstructor(types) 36 | 37 | let private emitNewTuple (types: Type list) (gen: ILGeneratorWrapper) = 38 | let typesArr = Array.ofList types 39 | match typesArr with 40 | | [|_|] -> gen.Emit(Newobj (newTuple1 typesArr)) 41 | | [|_; _|] -> gen.Emit(Newobj (newTuple2 typesArr)) 42 | | [|_; _; _|] -> gen.Emit(Newobj (newTuple3 typesArr)) 43 | | [|_; _; _; _|] -> gen.Emit(Newobj (newTuple4 typesArr)) 44 | | [|_; _; _; _; _|] -> gen.Emit(Newobj (newTuple5 typesArr)) 45 | | [|_; _; _; _; _; _|] -> gen.Emit(Newobj (newTuple6 typesArr)) 46 | | [|_; _; _; _; _; _; _|] -> gen.Emit(Newobj (newTuple7 typesArr)) 47 | | _greaterThen7 -> 48 | failwith "unsupported tuple type." 49 | 50 | let emit (elems: Expr list) (stack: CompileStack) = 51 | if elems.Length < 8 then 52 | let types = elems |> List.map (fun e -> e.Type) 53 | stack.Push(Compiling (emitNewTuple types)) 54 | elems |> List.rev |> List.iter (fun argExpr -> stack.Push(CompileTarget argExpr)) 55 | else 56 | // TODO : [performance issue] rewrite using tuple ctor 57 | let tupleType = FSharpType.MakeTupleType(elems |> List.map (fun e -> e.Type) |> List.toArray) 58 | stack.Push(Assumed (function 59 | | IfRet, gen -> gen.Emit(Tailcall); gen.Emit(Call (Method (unboxGenericM.MakeGenericMethod(tupleType)))) 60 | | _, gen -> gen.Emit(Call (Method (unboxGenericM.MakeGenericMethod(tupleType)))))) 61 | stack.Push(Compiling (fun gen -> 62 | gen.Emit(Ldtoken (TokType tupleType)) 63 | gen.Emit(Call (Method getTypeFromHandleM)) 64 | gen.Emit(Call (Method makeTupleM)) 65 | )) 66 | stack.Push(CompileTarget (Expr.NewArray(typeof, elems |> List.map (fun e -> Expr.Coerce(e, typeof))))) -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/TypeBuilderWrapper.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open System 16 | open System.Reflection 17 | open System.Reflection.Emit 18 | 19 | type internal TypeBuilderWrapper private (moduleBuilder: ModuleBuilderWrapper, builder: TypeBuilder, name: string) = 20 | static member Create(moduleBuilder, builder, name) = 21 | TypeBuilderWrapper(moduleBuilder, builder, name) 22 | 23 | member __.Parent = moduleBuilder 24 | member __.RawBuilder = builder 25 | member __.Name = name 26 | member __.BaseType = builder.BaseType 27 | 28 | member __.CreateType() = builder.CreateType() 29 | 30 | [] 31 | module internal ModuleBuilderWrapperExtension = 32 | let private genericFSharpFuncType = typedefof<_ -> _> 33 | let private fsharpFuncType argType retType = genericFSharpFuncType.MakeGenericType([|argType; retType|]) 34 | 35 | type ModuleBuilderWrapper with 36 | member this.DefineType(name: string, attrs: TypeAttributes, baseType: Type, interfaces: Type list) = 37 | let typ = this.RawBuilder.DefineType(name, attrs, baseType, Array.ofList interfaces) 38 | TypeBuilderWrapper.Create(this, typ, name) 39 | 40 | member this.DefineLambda(argType, retType) = 41 | this.DefineType(this.FreshTypeName("lambda"), TypeAttributes.Public, fsharpFuncType argType retType, []) -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/VariableEnv.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler 14 | 15 | open System 16 | open System.Reflection 17 | open System.Reflection.Emit 18 | open Microsoft.FSharp.Quotations 19 | 20 | type internal VariableInfo = 21 | | Arg of int 22 | | Local of LocalBuilder * string 23 | | Field of FieldInfo 24 | 25 | type internal VariableEnv = (Var * VariableInfo) list 26 | -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/paket.references: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bleis-tift/FSharp.Quotations.Compiler/ec7be81498cc02fdb8ab68b86bf14eab090f4a5c/src/FSharp.Quotations.Compiler/paket.references -------------------------------------------------------------------------------- /src/FSharp.Quotations.Compiler/paket.template: -------------------------------------------------------------------------------- 1 | type project 2 | owners 3 | bleis-tift 4 | authors 5 | bleis-tift 6 | projectUrl 7 | http://github.com/bleis-tift/FSharp.Quotations.Compiler 8 | iconUrl 9 | https://raw.githubusercontent.com/bleis-tift/FSharp.Quotations.Compiler/master/docs/files/img/logo.png 10 | licenseUrl 11 | http://github.com/bleis-tift/FSharp.Quotations.Compiler/blob/master/LICENSE.txt 12 | requireLicenseAcceptance 13 | false 14 | copyright 15 | Copyright 2015 16 | tags 17 | fsharp F# quotations compiler 18 | summary 19 | A compiler for F# expression tree 20 | description 21 | A compiler for F# expression tree. This library is based on System.Reflection.Emit technology. 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests.CSharp/CSharpClass.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | */ 13 | using System; 14 | using System.Collections.Generic; 15 | using System.Linq; 16 | using System.Text; 17 | using System.Threading.Tasks; 18 | 19 | namespace FSharp.Quotations.Compiler.Tests.CSharp 20 | { 21 | public class CSharpClass 22 | { 23 | public static int StaticField = 42; 24 | 25 | public static int OptionalArgument(int x, int y = -1) 26 | { 27 | return x + y; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests.CSharp/FSharp.Quotations.Compiler.Tests.CSharp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B69BD2F7-BD0B-4DEC-AF95-6069212101A8} 8 | Library 9 | Properties 10 | FSharp.Quotations.Compiler.Tests.CSharp 11 | FSharp.Quotations.Compiler.Tests.CSharp 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 53 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests.CSharp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 6 | // アセンブリに関連付けられている情報を変更するには、 7 | // これらの属性値を変更してください。 8 | [assembly: AssemblyTitle("FSharp.Quotations.Compiler.Tests.CSharp")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("FSharp.Quotations.Compiler.Tests.CSharp")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから 18 | // 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 19 | // その型の ComVisible 属性を true に設定してください。 20 | [assembly: ComVisible(false)] 21 | 22 | // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です 23 | [assembly: Guid("515f37db-fb7d-431e-a68c-d62ba18eefb4")] 24 | 25 | // アセンブリのバージョン情報は、以下の 4 つの値で構成されています: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を 33 | // 既定値にすることができます: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/ArithmeticOpTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | open System 16 | 17 | [] 18 | module ArithmeticOpTest = 19 | [] 20 | let ``+ int`` () = <@ +(1) @> |> check 1 21 | 22 | [] 23 | let ``- int`` () = 24 | <@ -(1) @> |> check -1 25 | <@ - Int32.MinValue @> |> check Int32.MinValue 26 | 27 | [] 28 | let ``int + int`` () = 29 | <@ 1 + 2 @> |> check 3 30 | <@ Int32.MaxValue + 1 @> |> check Int32.MinValue 31 | 32 | [] 33 | let ``int - int`` () = 34 | <@ 3 - 1 @> |> check 2 35 | <@ Int32.MinValue - 1 @> |> check Int32.MaxValue 36 | 37 | [] 38 | let ``int * int`` () = 39 | <@ 2 * 3 @> |> check 6 40 | <@ Int32.MinValue * -1 @> |> check Int32.MinValue 41 | 42 | [] 43 | let ``int / int`` () = 44 | <@ 5 / 2 @> |> check 2 45 | <@ Int32.MinValue / -1 @> |> checkExn<_, OverflowException> 46 | <@ 1 / 0 @> |> checkExn<_, DivideByZeroException> 47 | 48 | [] 49 | let ``int % int``() = 50 | <@ 5 % 2 @> |> check 1 51 | <@ Int32.MinValue % -1 @> |> checkExn<_, OverflowException> 52 | <@ 1 % 0 @> |> checkExn<_, DivideByZeroException> 53 | 54 | [] 55 | let ``+ bigint`` () = 56 | <@ +(1I) @> |> check (+(1I)) 57 | 58 | [] 59 | let ``- bigint`` () = 60 | <@ -(1I) @> |> check (-(1I)) 61 | 62 | [] 63 | let ``bigint + bigint`` () = 64 | <@ 1I + 1I @> |> check (1I + 1I) 65 | 66 | [] 67 | let ``bigint - bigint`` () = 68 | <@ 1I - 1I @> |> check (1I - 1I) 69 | 70 | [] 71 | let ``bigint * bigint`` () = 72 | <@ 1I * 1I @> |> check (1I * 1I) 73 | 74 | [] 75 | let ``bigint / bigint`` () = 76 | <@ 1I / 1I @> |> check (1I / 1I) 77 | 78 | [] 79 | let ``bigint % bigint`` () = 80 | <@ 1I % 1I @> |> check (1I % 1I) 81 | 82 | [] 83 | let ``char + char`` () = 84 | <@ 'a' + 'a' @> |> check ('a' + 'a') 85 | <@ Char.MaxValue + (char 1) @> |> check (Char.MaxValue + (char 1)) 86 | 87 | [] 88 | let ``+ float`` () = <@ +(1.0) @> |> check 1.0 89 | 90 | [] 91 | let ``- float`` () = 92 | <@ -(1.0) @> |> check -1.0 93 | <@ - (Double.MinValue) @> |> check Double.MaxValue 94 | 95 | [] 96 | let ``float + float`` () = 97 | <@ 1.0 + 2.0 @> |> check 3.0 98 | <@ Double.MaxValue + Double.MaxValue @> |> check infinity 99 | 100 | [] 101 | let ``float - float`` () = 102 | <@ 3.0 - 1.0 @> |> check 2.0 103 | <@ Double.MinValue - Double.MaxValue @> |> check -infinity 104 | 105 | [] 106 | let ``float * float`` () = 107 | <@ 2.0 * 3.0 @> |> check 6.0 108 | <@ Double.MinValue * -1.0 @> |> check Double.MaxValue 109 | 110 | [] 111 | let ``float ** float`` () = <@ 3.0 ** 2.0 @> |> check 9.0 112 | 113 | [] 114 | let ``float / float`` () = 115 | <@ 5.0 / 2.0 @> |> check 2.5 116 | <@ 1.0 / 0.0 @> |> check infinity 117 | <@ 1.0 / -0.0 @> |> check -infinity 118 | <@ 0.0 / 0.0 @> |> check nan 119 | 120 | [] 121 | let ``+ decimal`` () = 122 | <@ +(1.0) @> |> check (+(1.0)) 123 | 124 | [] 125 | let ``- decimal`` () = 126 | <@ -(1.0) @> |> check (-(1.0)) 127 | 128 | [] 129 | let ``decimal + decimal`` () = 130 | <@ 1.0m + 1.0m @> |> check (1.0m + 1.0m) 131 | 132 | [] 133 | let ``decimal - decimal`` () = 134 | <@ 1.0m - 1.0m @> |> check (1.0m - 1.0m) 135 | 136 | [] 137 | let ``decimal * decimal`` () = 138 | <@ 1.0m * 1.0m @> |> check (1.0m * 1.0m) 139 | 140 | [] 141 | let ``decimal / decimal`` () = 142 | <@ 1.0m / 1.0m @> |> check (1.0m / 1.0m) 143 | 144 | [] 145 | let ``decimal % decimal`` () = 146 | <@ 1.0m % 1.0m @> |> check (1.0m % 1.0m) 147 | 148 | [] 149 | let ``string + string`` () = 150 | <@ "aaa" + "bbb" @> |> check "aaabbb" 151 | 152 | [] 153 | [] 154 | [] 155 | [] 156 | let ``+ byte `` (i) = <@ +(i) @> |> check i 157 | 158 | [] 159 | [] 160 | [] 161 | [] 162 | let `` byte + byte `` (b1:byte, b2:byte) = <@ b1 + b2 @> |> check(b1 + b2) 163 | 164 | [] 165 | [] 166 | [] 167 | [] 168 | let `` byte - byte `` (b1:byte, b2:byte) = <@ b1 - b2 @> |> check(b1 - b2) 169 | 170 | [] 171 | [] 172 | [] 173 | [] 174 | [] 175 | let `` byte % byte `` (b1:byte, b2:byte) = <@ b1 % b2 @> |> check(b1 % b2) 176 | 177 | [] 178 | [] 179 | [] 180 | [] 181 | [] 182 | [] 183 | let `` byte * byte `` (b1:byte, b2:byte) = <@ b1 * b2 @> |> check(b1 * b2) 184 | 185 | [] 186 | [] 187 | [] 188 | [] 189 | [] 190 | [] 191 | let `` byte / byte `` (b1:byte, b2:byte) = <@ b1 / b2 @> |> check(b1 / b2) 192 | 193 | [] 194 | [] 195 | let `` byte / 0 `` (b1:byte, b2:byte) = <@ b1 / b2 @> |> checkExn<_, DivideByZeroException> 196 | 197 | [] 198 | [] 199 | let `` byte % 0 `` (b1:byte, b2:byte) = <@ b1 % b2 @> |> checkExn<_, DivideByZeroException> 200 | 201 | module Checked = 202 | open Microsoft.FSharp.Core.Operators.Checked 203 | 204 | [] 205 | let ``- int`` () = 206 | <@ -(1) @> |> check -1 207 | <@ - Int32.MinValue @> |> checkExn<_, OverflowException> 208 | 209 | [] 210 | let ``int + int`` () = 211 | <@ 1 + 2 @> |> check 3 212 | <@ Int32.MaxValue + 1 @> |> checkExn<_, OverflowException> 213 | 214 | [] 215 | let ``int - int`` () = 216 | <@ 3 - 1 @> |> check 2 217 | <@ Int32.MinValue - 1 @> |> checkExn<_, OverflowException> 218 | 219 | [] 220 | let ``int * int`` () = 221 | <@ 2 * 3 @> |> check 6 222 | <@ Int32.MinValue * -1 @> |> checkExn<_, OverflowException> 223 | 224 | [] 225 | let ``+ bigint`` () = 226 | <@ +(1I) @> |> check (+(1I)) 227 | 228 | [] 229 | let ``- bigint`` () = 230 | <@ -(1I) @> |> check (-(1I)) 231 | 232 | [] 233 | let ``bigint + bigint`` () = 234 | <@ 1I + 1I @> |> check (1I + 1I) 235 | 236 | [] 237 | let ``bigint - bigint`` () = 238 | <@ 1I - 1I @> |> check (1I - 1I) 239 | 240 | [] 241 | let ``bigint * bigint`` () = 242 | <@ 1I * 1I @> |> check (1I * 1I) 243 | 244 | [] 245 | let ``bigint / bigint`` () = 246 | <@ 1I / 1I @> |> check (1I / 1I) 247 | 248 | [] 249 | let ``bigint % bigint`` () = 250 | <@ 1I % 1I @> |> check (1I % 1I) 251 | 252 | [] 253 | let ``char + char`` () = 254 | <@ 'a' + 'a' @> |> check ('a' + 'a') 255 | <@ Char.MaxValue + (char 1) @> |> checkExn<_, OverflowException> 256 | 257 | [] 258 | let ``- float`` () = 259 | <@ -(1.0) @> |> check -1.0 260 | <@ - (Double.MinValue) @> |> check Double.MaxValue 261 | 262 | [] 263 | let ``float + float`` () = 264 | <@ 1.0 + 2.0 @> |> check 3.0 265 | <@ Double.MaxValue + Double.MaxValue @> |> check infinity 266 | 267 | [] 268 | let ``float - float`` () = 269 | <@ 3.0 - 1.0 @> |> check 2.0 270 | <@ Double.MinValue - Double.MaxValue @> |> check -infinity 271 | 272 | [] 273 | let ``float * float`` () = 274 | <@ 2.0 * 3.0 @> |> check 6.0 275 | <@ Double.MinValue * -1.0 @> |> check Double.MaxValue 276 | 277 | [] 278 | let ``+ decimal`` () = 279 | <@ +(1.0) @> |> check (+(1.0)) 280 | 281 | [] 282 | let ``- decimal`` () = 283 | <@ -(1.0) @> |> check (-(1.0)) 284 | 285 | [] 286 | let ``decimal + decimal`` () = 287 | <@ 1.0m + 1.0m @> |> check (1.0m + 1.0m) 288 | 289 | [] 290 | let ``decimal - decimal`` () = 291 | <@ 1.0m - 1.0m @> |> check (1.0m - 1.0m) 292 | 293 | [] 294 | let ``decimal * decimal`` () = 295 | <@ 1.0m * 1.0m @> |> check (1.0m * 1.0m) 296 | 297 | [] 298 | let ``decimal / decimal`` () = 299 | <@ 1.0m / 1.0m @> |> check (1.0m / 1.0m) 300 | 301 | [] 302 | let ``decimal % decimal`` () = 303 | <@ 1.0m % 1.0m @> |> check (1.0m % 1.0m) 304 | 305 | [] 306 | let ``byte - byte`` () = 307 | <@ 254uy - 255uy @> |> checkExn<_, OverflowException> 308 | 309 | [] 310 | let ``byte + byte`` () = 311 | <@ 1uy + 255uy @> |> checkExn<_, OverflowException> 312 | 313 | [] 314 | [] 315 | let `` byte * byte `` (b1:byte, b2:byte) = <@ b1 * b2 @> |> checkExn<_, OverflowException> 316 | 317 | [] 318 | let ``string + string`` () = 319 | <@ "aaa" + "bbb" @> |> check "aaabbb" -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/ArrayFuncTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | [] 16 | module ArrayFuncTest = 17 | [] 18 | let ``Array.empty`` () = 19 | <@ Array.empty: int[] @> |> check [||] 20 | <@ Array.empty: string[] @> |> check [||] 21 | 22 | [] 23 | let ``Array.init`` () = 24 | <@ Array.init 3 id @> |> check [|0; 1; 2|] 25 | <@ Array.init 3 string @> |> check [|"0"; "1"; "2"|] 26 | 27 | [] 28 | let ``Array.create`` () = 29 | <@ Array.create 3 1 @> |> check [|1; 1; 1|] 30 | <@ Array.create 3 "str" @> |> check [|"str"; "str"; "str"|] 31 | 32 | [] 33 | let ``Array.zeroCreate`` () = 34 | <@ Array.zeroCreate 3 @> |> check [|0; 0; 0|] 35 | <@ Array.zeroCreate 3 @> |> check [|null; null; null|] 36 | 37 | [] 38 | let ``Array.length`` () = <@ Array.length [|0; 1; 2|] @> |> check 3 39 | 40 | [] 41 | let ``Array.Length`` () = <@ [|0; 1; 2|].Length @> |> check 3 42 | 43 | [] 44 | let ``Array.Map`` () = <@ [|0..10|] |> Array.filter (fun x -> x % 5 = 0) @> |> check [|0; 5; 10|] -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/ArrayOpTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | open System 16 | 17 | [] 18 | module ArrayOpTest = 19 | [] 20 | let ``get elem from int[]`` () = 21 | <@ let xs = [|0..10|] in xs.[5] @> |> check 5 22 | <@ let xs = [|0..10|] in xs.[100] @> |> checkExn<_, IndexOutOfRangeException> 23 | 24 | [] 25 | let ``set elem to int[]`` () = 26 | <@ let xs = Array.zeroCreate 10 27 | xs.[5] <- 10 28 | xs.[5] @> 29 | |> check 10 30 | 31 | [] 32 | let ``slice int[]`` () = 33 | <@ let xs = [|0..10|] in xs.[2..8] @> |> check [|0..10|].[2..8] -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/BitOpTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | open System 16 | 17 | [] 18 | module BitOpTest = 19 | [] 20 | let ``int &&& int`` () = <@ 42 &&& 63 @> |> check 42 21 | 22 | [] 23 | let ``int ||| int`` () = <@ 42 ||| 0 @> |> check 42 24 | 25 | [] 26 | let ``int ^^^ int`` () = <@ 1 ^^^ 1 @> |> check 0 27 | 28 | [] 29 | let ``int >>> int`` () = 30 | <@ 42 >>> 1 @> |> check 21 31 | <@ 42 >>> 31 @> |> check 0 32 | <@ -1 >>> 1 @> |> check -1 33 | <@ -1 >>> 31 @> |> check -1 34 | <@ -1 >>> 32 @> |> check -1 35 | 36 | [] 37 | let ``int <<< int`` () = 38 | <@ 42 <<< 1 @> |> check 84 39 | <@ Int32.MaxValue <<< 1 @> |> check -2 40 | <@ Int32.MinValue <<< 1 @> |> check 0 41 | 42 | [] 43 | let ``~~~ int`` () = <@ ~~~1 @> |> check -2 44 | 45 | [] 46 | let ``bigint &&& bigint`` () = 47 | <@ 1I &&& 1I @> |> check (1I &&& 1I) 48 | 49 | [] 50 | let ``bigint ||| bigint`` () = 51 | <@ 1I ||| 1I @> |> check (1I ||| 1I) 52 | 53 | [] 54 | let ``bigint ^^^ bigint`` () = 55 | <@ 1I ^^^ 1I @> |> check (1I ^^^ 1I) 56 | 57 | [] 58 | let ``bigint >>> int`` () = 59 | <@ 42I >>> 1 @> |> check (42I >>> 1) 60 | 61 | [] 62 | let ``bigint <<< int`` () = 63 | <@ 42I <<< 1 @> |> check (42I <<< 1) 64 | [] 65 | let ``byte >>> int`` () = 66 | <@ 0uy >>> -1 @> |> check 0uy 67 | <@ 0uy >>> 0 @> |> check 0uy 68 | <@ 0uy >>> 1 @> |> check 0uy 69 | <@ 1uy >>> -2 @> |> check 0uy 70 | <@ 1uy >>> -1 @> |> check 0uy 71 | <@ 1uy >>> 0 @> |> check 1uy 72 | <@ 1uy >>> 1 @> |> check 0uy 73 | <@ 1uy >>> 2 @> |> check 0uy 74 | <@ 255uy >>> -256 @> |> check 255uy 75 | <@ 255uy >>> -255 @> |> check 127uy 76 | <@ 255uy >>> -2 @> |> check 3uy 77 | <@ 255uy >>> -1 @> |> check 1uy 78 | <@ 255uy >>> 0 @> |> check 255uy 79 | <@ 255uy >>> 1 @> |> check 127uy 80 | <@ 255uy >>> 2 @> |> check 63uy 81 | <@ 255uy >>> 255 @> |> check 1uy 82 | <@ 255uy >>> 256 @> |> check 255uy 83 | 84 | [] 85 | let ``byte <<< int`` () = 86 | <@ 0uy <<< -1 @> |> check 0uy 87 | <@ 0uy <<< 0 @> |> check 0uy 88 | <@ 0uy <<< 1 @> |> check 0uy 89 | <@ 1uy <<< -2 @> |> check 64uy 90 | <@ 1uy <<< -1 @> |> check 128uy 91 | <@ 1uy <<< 0 @> |> check 1uy 92 | <@ 1uy <<< 1 @> |> check 2uy 93 | <@ 1uy <<< 2 @> |> check 4uy 94 | <@ 255uy <<< -256 @> |> check 255uy 95 | <@ 255uy <<< -255 @> |> check 254uy 96 | <@ 255uy <<< -254 @> |> check 252uy 97 | <@ 255uy <<< -2 @> |> check 192uy 98 | <@ 255uy <<< -1 @> |> check 128uy 99 | <@ 255uy <<< 0 @> |> check 255uy 100 | <@ 255uy <<< 1 @> |> check 254uy 101 | <@ 255uy <<< 2 @> |> check 252uy 102 | <@ 255uy <<< 255 @> |> check 128uy 103 | <@ 255uy <<< 256 @> |> check 255uy 104 | 105 | [] 106 | let ``byte ^^^ byte`` () = 107 | <@ 0uy ^^^ 0uy @> |> check 0uy 108 | <@ 0uy ^^^ 1uy @> |> check 1uy 109 | <@ 1uy ^^^ 0uy @> |> check 1uy 110 | <@ 1uy ^^^ 1uy @> |> check 0uy 111 | <@ 1uy ^^^ 2uy @> |> check 3uy 112 | <@ 255uy ^^^ 0uy @> |> check 255uy 113 | <@ 255uy ^^^ 1uy @> |> check 254uy 114 | <@ 255uy ^^^ 128uy @> |> check 127uy 115 | <@ 255uy ^^^ 254uy @> |> check 1uy 116 | <@ 255uy ^^^ 255uy @> |> check 0uy 117 | 118 | [] 119 | let ``byte ||| byte`` () = 120 | <@ 0uy ||| 0uy @> |> check 0uy 121 | <@ 0uy ||| 1uy @> |> check 1uy 122 | <@ 0uy ||| 255uy @> |> check 255uy 123 | <@ 1uy ||| 0uy @> |> check 1uy 124 | <@ 1uy ||| 1uy @> |> check 1uy 125 | <@ 1uy ||| 255uy @> |> check 255uy 126 | <@ 128uy ||| 0uy @> |> check 128uy 127 | <@ 128uy ||| 1uy @> |> check 129uy 128 | <@ 128uy ||| 126uy @> |> check 254uy 129 | <@ 128uy ||| 127uy @> |> check 255uy 130 | <@ 128uy ||| 255uy @> |> check 255uy 131 | <@ 255uy ||| 0uy @> |> check 255uy 132 | <@ 255uy ||| 1uy @> |> check 255uy 133 | <@ 255uy ||| 128uy @> |> check 255uy 134 | <@ 255uy ||| 254uy @> |> check 255uy 135 | <@ 255uy ||| 255uy @> |> check 255uy 136 | 137 | [] 138 | let ``byte &&& byte`` () = 139 | <@ 0uy &&& 0uy @> |> check 0uy 140 | <@ 0uy &&& 1uy @> |> check 0uy 141 | <@ 0uy &&& 255uy @> |> check 0uy 142 | <@ 1uy &&& 0uy @> |> check 0uy 143 | <@ 1uy &&& 1uy @> |> check 1uy 144 | <@ 1uy &&& 255uy @> |> check 1uy 145 | <@ 128uy &&& 0uy @> |> check 0uy 146 | <@ 128uy &&& 127uy @> |> check 0uy 147 | <@ 128uy &&& 128uy @> |> check 128uy 148 | <@ 128uy &&& 255uy @> |> check 128uy 149 | <@ 255uy &&& 0uy @> |> check 0uy 150 | <@ 255uy &&& 1uy @> |> check 1uy 151 | <@ 255uy &&& 128uy @> |> check 128uy 152 | <@ 255uy &&& 254uy @> |> check 254uy 153 | <@ 255uy &&& 255uy @> |> check 255uy 154 | 155 | [] 156 | let ``~~~ byte`` () = 157 | <@ ~~~ 0uy @> |> check 255uy 158 | <@ ~~~ 1uy @> |> check 254uy 159 | <@ ~~~ 254uy @> |> check 1uy 160 | <@ ~~~ 255uy @> |> check 0uy 161 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/BoolOpTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | [] 16 | module BoolOpTest = 17 | [] 18 | [] 19 | [] 20 | [] 21 | let ``bool || bool`` (x, y, expected) = 22 | <@ x || y @> |> check expected 23 | 24 | [] 25 | [] 26 | [] 27 | [] 28 | let ``bool && bool`` (x, y, expected) = 29 | <@ x && y @> |> check expected -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/CmpOpTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | open System 16 | 17 | [] 18 | module CmpOpTest = 19 | [] 20 | let ``int = int`` () = 21 | <@ 1 = 1 @> |> check true 22 | <@ 0 = 1 @> |> check false 23 | 24 | [] 25 | let ``int <> int`` () = 26 | <@ 1 <> 1 @> |> check false 27 | <@ 0 <> 1 @> |> check true 28 | 29 | [] 30 | let ``int < int`` () = 31 | <@ 1 < 0 @> |> check false 32 | <@ 1 < 1 @> |> check false 33 | <@ 0 < 1 @> |> check true 34 | 35 | [] 36 | let ``int <= int`` () = 37 | <@ 1 <= 0 @> |> check false 38 | <@ 1 <= 1 @> |> check true 39 | <@ 0 <= 1 @> |> check true 40 | 41 | [] 42 | let ``int > int`` () = 43 | <@ 1 > 0 @> |> check true 44 | <@ 1 > 1 @> |> check false 45 | <@ 0 > 1 @> |> check false 46 | 47 | [] 48 | let ``int >= int`` () = 49 | <@ 1 >= 0 @> |> check true 50 | <@ 1 >= 1 @> |> check true 51 | <@ 0 >= 1 @> |> check false 52 | 53 | [] 54 | let ``bigint = bigint`` () = 55 | <@ 1I = 1I @> |> check true 56 | <@ 1I = 0I @> |> check false 57 | 58 | [] 59 | let ``bigint <> bigint`` () = 60 | <@ 1I = 1I @> |> check true 61 | <@ 1I = 0I @> |> check false 62 | 63 | [] 64 | let ``bigint < bigint`` () = 65 | <@ 1I < 0I @> |> check false 66 | <@ 1I < 1I @> |> check false 67 | <@ 0I < 1I @> |> check true 68 | 69 | [] 70 | let ``bigint <= bigint`` () = 71 | <@ 1I <= 0I @> |> check false 72 | <@ 1I <= 1I @> |> check true 73 | <@ 0I <= 1I @> |> check true 74 | 75 | [] 76 | let ``bigint > bigint`` () = 77 | <@ 1I > 0I @> |> check true 78 | <@ 1I > 1I @> |> check false 79 | <@ 0I > 1I @> |> check false 80 | 81 | [] 82 | let ``bigint >= bigint`` () = 83 | <@ 1I >= 0I @> |> check true 84 | <@ 1I >= 1I @> |> check true 85 | <@ 0I >= 1I @> |> check false 86 | 87 | let ``char = char`` () = 88 | <@ 'a' = 'a' @> |> check true 89 | <@ 'a' = 'b' @> |> check false 90 | 91 | [] 92 | let ``char <> char`` () = 93 | <@ 'a' <> 'a' @> |> check false 94 | <@ 'a' <> 'b' @> |> check true 95 | 96 | [] 97 | let ``char < char`` () = 98 | <@ 'a' < 'a' @> |> check false 99 | <@ 'a' < 'b' @> |> check true 100 | <@ 'b' < 'a' @> |> check false 101 | 102 | [] 103 | let ``char <= char`` () = 104 | <@ 'a' <= 'a' @> |> check true 105 | <@ 'a' <= 'b' @> |> check true 106 | <@ 'b' <= 'a' @> |> check false 107 | 108 | [] 109 | let ``char > char`` () = 110 | <@ 'a' > 'a' @> |> check false 111 | <@ 'a' > 'b' @> |> check false 112 | <@ 'b' > 'a' @> |> check true 113 | 114 | [] 115 | let ``char >= char`` () = 116 | <@ 'a' >= 'a' @> |> check true 117 | <@ 'a' >= 'b' @> |> check false 118 | <@ 'b' >= 'a' @> |> check true 119 | 120 | [] 121 | let ``float = float`` () = 122 | <@ 1.0 = 1.0 @> |> check true 123 | <@ 0.0 = 1.0 @> |> check false 124 | 125 | [] 126 | let ``float <> float`` () = 127 | <@ 1.0 <> 1.0 @> |> check false 128 | <@ 0.0 <> 1.0 @> |> check true 129 | 130 | [] 131 | let ``float < float`` () = 132 | <@ 1.0 < 0.0 @> |> check false 133 | <@ 1.0 < 1.0 @> |> check false 134 | <@ 0.0 < 1.0 @> |> check true 135 | 136 | [] 137 | let ``float <= float`` () = 138 | <@ 1.0 <= 0.0 @> |> check false 139 | <@ 1.0 <= 1.0 @> |> check true 140 | <@ 0.0 <= 1.0 @> |> check true 141 | 142 | [] 143 | let ``float > float`` () = 144 | <@ 1.0 > 0.0 @> |> check true 145 | <@ 1.0 > 1.0 @> |> check false 146 | <@ 0.0 > 1.0 @> |> check false 147 | 148 | [] 149 | let ``float >= float`` () = 150 | <@ 1.0 >= 0.0 @> |> check true 151 | <@ 1.0 >= 1.0 @> |> check true 152 | <@ 0.0 >= 1.0 @> |> check false 153 | 154 | [] 155 | let ``decimal = decimal`` () = 156 | <@ 1M = 1M @> |> check true 157 | <@ 1M = 0M @> |> check false 158 | 159 | [] 160 | let ``decimal <> decimal`` () = 161 | <@ 1M = 1M @> |> check true 162 | <@ 1M = 0M @> |> check false 163 | 164 | [] 165 | let ``decimal < decimal`` () = 166 | <@ 1M < 0M @> |> check false 167 | <@ 1M < 1M @> |> check false 168 | <@ 0M < 1M @> |> check true 169 | 170 | [] 171 | let ``decimal <= decimal`` () = 172 | <@ 1M <= 0M @> |> check false 173 | <@ 1M <= 1M @> |> check true 174 | <@ 0M <= 1M @> |> check true 175 | 176 | [] 177 | let ``decimal > decimal`` () = 178 | <@ 1M > 0M @> |> check true 179 | <@ 1M > 1M @> |> check false 180 | <@ 0M > 1M @> |> check false 181 | 182 | [] 183 | let ``decimal >= decimal`` () = 184 | <@ 1M >= 0M @> |> check true 185 | <@ 1M >= 1M @> |> check true 186 | <@ 0M >= 1M @> |> check false 187 | 188 | [] 189 | let ``bool = bool`` () = 190 | <@ true = true @> |> check true 191 | <@ false = true @> |> check false 192 | 193 | [] 194 | let ``bool <> bool`` () = 195 | <@ true <> true @> |> check false 196 | <@ false <> true @> |> check true 197 | 198 | [] 199 | let ``bool < bool`` () = 200 | <@ true < false @> |> check false 201 | <@ true < true @> |> check false 202 | <@ false < true @> |> check true 203 | 204 | [] 205 | let ``bool <= bool`` () = 206 | <@ true <= false @> |> check false 207 | <@ true <= true @> |> check true 208 | <@ false <= true @> |> check true 209 | 210 | [] 211 | let ``bool > bool`` () = 212 | <@ true > false @> |> check true 213 | <@ true > true @> |> check false 214 | <@ false > true @> |> check false 215 | 216 | [] 217 | let ``bool >= bool`` () = 218 | <@ true >= false @> |> check true 219 | <@ true >= true @> |> check true 220 | <@ false >= true @> |> check false 221 | 222 | [] 223 | let ``string = string`` () = 224 | <@ "aaa" = "aaa" @> |> check true 225 | <@ "bbb" = "aaa" @> |> check false 226 | 227 | [] 228 | let ``string <> string`` () = 229 | <@ "aaa" <> "aaa" @> |> check false 230 | <@ "bbb" <> "aaa" @> |> check true 231 | 232 | [] 233 | let ``string < string`` () = 234 | <@ "aaa" < "bbb" @> |> check true 235 | <@ "aaa" < "aaa" @> |> check false 236 | <@ "bbb" < "aaa" @> |> check false 237 | 238 | [] 239 | let ``string <= string`` () = 240 | <@ "aaa" <= "bbb" @> |> check true 241 | <@ "aaa" <= "aaa" @> |> check true 242 | <@ "bbb" <= "aaa" @> |> check false 243 | 244 | [] 245 | let ``string > string`` () = 246 | <@ "aaa" > "bbb" @> |> check false 247 | <@ "aaa" > "aaa" @> |> check false 248 | <@ "bbb" > "aaa" @> |> check true 249 | 250 | [] 251 | let ``string >= string`` () = 252 | <@ "aaa" >= "bbb" @> |> check false 253 | <@ "aaa" >= "aaa" @> |> check true 254 | <@ "bbb" >= "aaa" @> |> check true 255 | 256 | [] 257 | let ``int[] = int[]`` () = 258 | <@ [|1|] = [|1|] @> |> check true 259 | <@ [|1|] = [|2|] @> |> check false 260 | <@ [|1|] = [|1; 1|] @> |> check false 261 | 262 | [] 263 | let ``int[] <> int[]`` () = 264 | <@ [|1|] <> [|1|] @> |> check false 265 | <@ [|1|] <> [|2|] @> |> check true 266 | <@ [|1|] <> [|1; 1|] @> |> check true 267 | 268 | [] 269 | let ``int[] < int[]`` () = 270 | <@ [|1|] < [||] @> |> check false 271 | <@ [|1|] < [|1|] @> |> check false 272 | <@ [|1|] < [|2|] @> |> check true 273 | <@ [|1|] < [|1; 1|] @> |> check true 274 | <@ [|2|] < [|1; 1|] @> |> check true 275 | 276 | [] 277 | let ``int[] <= int[]`` () = 278 | <@ [|1|] <= [||] @> |> check false 279 | <@ [|1|] <= [|1|] @> |> check true 280 | <@ [|1|] <= [|2|] @> |> check true 281 | <@ [|1|] <= [|1; 1|] @> |> check true 282 | <@ [|2|] <= [|1; 1|] @> |> check true 283 | 284 | [] 285 | let ``int[] > int[]`` () = 286 | <@ [|1|] > [||] @> |> check true 287 | <@ [|1|] > [|1|] @> |> check false 288 | <@ [|1|] > [|2|] @> |> check false 289 | <@ [|1|] > [|1; 1|] @> |> check false 290 | <@ [|2|] > [|1; 1|] @> |> check false 291 | 292 | [] 293 | let ``int[] >= int[]`` () = 294 | <@ [|1|] >= [||] @> |> check true 295 | <@ [|1|] >= [|1|] @> |> check true 296 | <@ [|1|] >= [|2|] @> |> check false 297 | <@ [|1|] >= [|1; 1|] @> |> check false 298 | <@ [|2|] >= [|1; 1|] @> |> check false 299 | 300 | [] 301 | let ``byte = byte`` () = 302 | <@ 0uy = 0uy @> |> check true 303 | <@ 255uy = 255uy @> |> check true 304 | <@ 0uy = 255uy @> |> check false 305 | <@ 255uy = 0uy @> |> check false 306 | 307 | [] 308 | let ``byte <> byte`` () = 309 | <@ 0uy <> 0uy @> |> check false 310 | <@ 255uy <> 255uy @> |> check false 311 | <@ 0uy <> 255uy @> |> check true 312 | <@ 255uy <> 0uy @> |> check true 313 | 314 | [] 315 | let ``byte > byte`` () = 316 | <@ 1uy > 0uy @> |> check true 317 | <@ 255uy > 1uy @> |> check true 318 | <@ 255uy > 254uy @> |> check true 319 | <@ 0uy > 255uy @> |> check false 320 | <@ 255uy > 255uy @> |> check false 321 | 322 | [] 323 | let ``byte >= byte`` () = 324 | <@ 1uy >= 0uy @> |> check true 325 | <@ 255uy >= 1uy @> |> check true 326 | <@ 255uy >= 254uy @> |> check true 327 | <@ 255uy >= 255uy @> |> check true 328 | <@ 0uy >= 255uy @> |> check false 329 | <@ 254uy >= 255uy @> |> check false 330 | 331 | [] 332 | let ``byte < byte`` () = 333 | <@ 0uy < 1uy @> |> check true 334 | <@ 1uy < 255uy @> |> check true 335 | <@ 254uy < 255uy @> |> check true 336 | <@ 255uy < 0uy @> |> check false 337 | <@ 255uy < 255uy @> |> check false 338 | 339 | [] 340 | let ``byte <= byte`` () = 341 | <@ 0uy <= 1uy @> |> check true 342 | <@ 1uy <= 255uy @> |> check true 343 | <@ 254uy <= 255uy @> |> check true 344 | <@ 255uy <= 255uy @> |> check true 345 | <@ 255uy <= 0uy @> |> check false 346 | <@ 255uy <= 254uy @> |> check false 347 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/ControlFlowExprTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | open System 16 | 17 | [] 18 | module ControlFlowExprTest = 19 | [] 20 | let ``sequential`` () = 21 | <@ (); 10 @> |> check 10 22 | <@ ignore 10; 20 @> |> check 20 23 | <@ ignore 10; ignore 20; 30 @> |> check 30 24 | 25 | [] 26 | let ``if-then-else`` () = 27 | <@ if true then "T" else "F" @> |> check "T" 28 | <@ if false then "T" else "F" @> |> check "F" 29 | 30 | [] 31 | let ``if-then-else (unit)`` () = 32 | <@ let mutable n = 0 33 | if false then () 34 | else n <- 10 35 | n @> 36 | |> check 10 37 | 38 | [] 39 | let ``if-then without else`` () = 40 | <@ let mutable n = 0 41 | if true then n <- 10 42 | n @> 43 | |> check 10 44 | 45 | [] 46 | let ``if-then-else with tailcall`` () = 47 | <@ let cond () = true 48 | let f () = 42 49 | let g () = 12 50 | if cond () then f () else g () @> 51 | |> check 42 52 | 53 | [] 54 | let ``try-with`` () = 55 | <@ try 10 with _e -> -1 @> |> check 10 56 | <@ try failwith "" with _e -> -1 @> |> check -1 57 | 58 | [] 59 | let ``try-with raise exception`` () = 60 | <@ try failwith "oops!" with e -> e.Message @> 61 | |> check "oops!" 62 | 63 | [] 64 | let ``try-with filter`` () = 65 | <@ try failwith "x" with e when e.Message = "x" -> "ok" | _ -> "ng" @> 66 | |> check "ok" 67 | <@ try failwith "y" with e when e.Message = "x" -> "ok" | _ -> "ng" @> 68 | |> check "ng" 69 | 70 | [] 71 | let ``try-with type test`` () = 72 | <@ 73 | let f exn = 74 | try raise exn 75 | with 76 | | :? InvalidOperationException -> "invalid op" 77 | | :? ArgumentException -> " arg exn" 78 | | _ -> " other exn" 79 | f (InvalidOperationException()) + f (ArgumentException()) + f (Exception()) 80 | @> 81 | |> check "invalid op arg exn other exn" 82 | 83 | [] 84 | let ``try-finally`` () = 85 | <@ let x = ref 0 86 | try () finally x := 10 87 | !x @> 88 | |> check 10 89 | 90 | let run f = try f () with e -> e.GetType().Name 91 | 92 | [] 93 | let ``try with in let body`` () = 94 | <@ 95 | let v = 10 96 | try 97 | run (fun () -> "1") 98 | with 99 | _ -> "" 100 | @> 101 | |> check "1" 102 | 103 | [] 104 | let ``rethrow`` () = 105 | <@ try 106 | try failwith "oops!" 107 | with _ -> reraise () 108 | with e -> e.Message @> 109 | |> check "oops!" 110 | 111 | [] 112 | let ``match type test`` () = 113 | <@ 114 | let x = 115 | match "hoge" :> obj with 116 | | :? string -> "str" 117 | | :? int -> "int" 118 | | _ -> "other" 119 | let y = 120 | match 42 :> obj with 121 | | :? string -> "str" 122 | | :? int -> "int" 123 | | _ -> "other" 124 | x + y 125 | @> 126 | |> check "strint" 127 | 128 | [] 129 | let ``match option`` () = 130 | <@ 131 | let f x = 132 | match x with 133 | | Some n -> string n 134 | | None -> "none" 135 | f (Some 42) + f None 136 | @> 137 | |> check "42none" 138 | 139 | type SimpleDU = Tag1 | Tag2 140 | 141 | [] 142 | let ``match simple DU`` () = 143 | <@ 144 | let f x = 145 | match x with 146 | | Tag1 -> "1" 147 | | Tag2 -> "2" 148 | f Tag1 + f Tag2 149 | @> 150 | |> check "12" 151 | 152 | type SimpleDUWithValue = Tag1 of int | Tag2 153 | 154 | [] 155 | let ``match DU with value`` () = 156 | <@ 157 | let f x = 158 | match x with 159 | | Tag1 i -> string i 160 | | Tag2 -> "tag2" 161 | f (Tag1 0) + f Tag2 162 | @> 163 | |> check "0tag2" 164 | 165 | type RecDU = Tag1 | Tag2 of RecDU 166 | 167 | [] 168 | let ``match recursive DU`` () = 169 | <@ 170 | let f x = 171 | match x with 172 | | Tag1 -> "tag1" 173 | | Tag2 _ -> "tag2" 174 | f Tag1 + f (Tag2 Tag1) 175 | @> 176 | |> check "tag1tag2" 177 | 178 | [] 179 | let ``match list`` () = 180 | <@ 181 | let f lst = 182 | match lst with 183 | | x::xs -> string x + ":" + (string xs.Length) 184 | | [] -> "empty" 185 | f [] + f [1; 2; 3] 186 | @> 187 | |> check "empty1:2" 188 | 189 | let (|Number|_|) (str: string) = 190 | match Int32.TryParse(str) with 191 | | true, res -> Some res 192 | | _ -> None 193 | 194 | let (|EndsWith|_|) (suffix: string) (str: string) = 195 | if str.EndsWith(suffix) then Some suffix 196 | else None 197 | 198 | [] 199 | let ``match with and pattern`` () = 200 | <@ 201 | let f x = 202 | match x with 203 | | Number num & EndsWith("0") suffix -> (num, suffix) 204 | | _ -> (0, "") 205 | (f "100") 206 | @> 207 | |> check (100, "0") 208 | 209 | [] 210 | let ``match with and pattern2`` () = 211 | <@ 212 | let f x = 213 | match x with 214 | | EndsWith("00") suffix1 & EndsWith("0") suffix2 -> 215 | suffix1 + ", " + suffix2 216 | | _ -> "" 217 | (f "100") 218 | @> 219 | |> check "00, 0" 220 | 221 | [] 222 | let ``while loop`` () = 223 | <@ let res = ResizeArray<_>() 224 | let mutable i = 0 225 | while i <> 10 do 226 | res.Add(i) 227 | i <- i + 1 228 | res.ToArray() @> 229 | |> check [|0..9|] 230 | 231 | [] 232 | let ``for loop`` () = 233 | <@ let res = ResizeArray<_>() 234 | for x in 5..10 do 235 | res.Add(x) 236 | res.ToArray() @> 237 | |> check [|5..10|] 238 | 239 | [] 240 | let ``for loop that is compiled into while loop`` () = 241 | <@ let res = ResizeArray<_>() 242 | for x in [5..10] do 243 | res.Add(x) 244 | res.ToArray() @> 245 | |> check [|5..10|] -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/CustomClassTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | [] 16 | module CustomClassTest = 17 | type CustomClass(id: int) = 18 | member __.Id = id 19 | override __.Equals(o) = 20 | match o with 21 | | :? CustomClass as cc -> cc.Id = id 22 | | _ -> false 23 | override __.GetHashCode() = id.GetHashCode() 24 | override __.ToString() = string id 25 | 26 | static member (~+) (x: CustomClass) = CustomClass(abs x.Id) 27 | static member (~-) (x: CustomClass) = CustomClass(-x.Id) 28 | 29 | static member (-) (x: CustomClass, y: CustomClass) = CustomClass(x.Id - y.Id) 30 | static member (-) (x: CustomClass, y: int) = CustomClass(x.Id - y) 31 | static member (-) (x: int, y: CustomClass) = CustomClass(x - y.Id) 32 | 33 | static member (/) (x: CustomClass, y: CustomClass) = CustomClass(x.Id / y.Id) 34 | static member (/) (x: CustomClass, y: int) = CustomClass(x.Id / y) 35 | static member (/) (x: int, y: CustomClass) = CustomClass(x / y.Id) 36 | 37 | static member op_Explicit (x: CustomClass) = byte x.Id 38 | 39 | [] 40 | let ``+ CustomClass`` () = 41 | <@ + (CustomClass(42)) @> |> check (CustomClass(42)) 42 | <@ + (CustomClass(-42)) @> |> check (CustomClass(42)) 43 | 44 | [] 45 | let ``- CustomClass`` () = 46 | <@ - (CustomClass(42)) @> |> check (- (CustomClass(42))) 47 | 48 | [] 49 | let ``x - y`` () = 50 | <@ CustomClass(42) - CustomClass(10) @> |> check (CustomClass(32)) 51 | <@ CustomClass(42) - 10 @> |> check (CustomClass(32)) 52 | <@ 42 - CustomClass(10) @> |> check (CustomClass(32)) 53 | 54 | [] 55 | let ``x / y`` () = 56 | <@ CustomClass(42) / CustomClass(2) @> |> check (CustomClass(21)) 57 | <@ CustomClass(42) / 2 @> |> check (CustomClass(21)) 58 | <@ 42 / CustomClass(2) @> |> check (CustomClass(21)) 59 | 60 | [] 61 | let ``byte x`` () = 62 | <@ byte <| CustomClass(42) @> |> check (42uy) -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/ExtraTopLevelOpTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | [] 16 | module ExtraTopLevelOpTest = 17 | open System.Collections.Generic 18 | 19 | [] 20 | let ``dict`` () = 21 | <@ dict []: IDictionary @> |> check (dict []) 22 | <@ dict [(1, "one"); (2, "two")] @> |> check (dict [(1, "one"); (2, "two")]) 23 | 24 | [] 25 | let ``eprintf`` () = 26 | <@ eprintf "hoge" @> |> checkPrinted Error "hoge" 27 | <@ eprintf "hoge%d" 1 @> |> checkPrinted Error "hoge1" 28 | <@ eprintf "%s" "hoge" @> |> checkPrinted Error "hoge" 29 | 30 | let appendNewLine str = str + System.Environment.NewLine 31 | 32 | [] 33 | let ``eprintfn`` () = 34 | <@ eprintfn "hoge" @> |> checkPrinted Error (appendNewLine "hoge") 35 | <@ eprintfn "hoge%d" 1 @> |> checkPrinted Error (appendNewLine "hoge1") 36 | <@ eprintfn "%s" "hoge" @> |> checkPrinted Error (appendNewLine "hoge") 37 | 38 | [] 39 | let ``fprintf`` () = 40 | <@ let w = new RobWriter(System.Text.UTF8Encoding()) in fprintf w "hoge"; w.Result @> |> check "hoge" 41 | <@ let w = new RobWriter(System.Text.UTF8Encoding()) in fprintf w "hoge%d" 1; w.Result @> |> check "hoge1" 42 | <@ let w = new RobWriter(System.Text.UTF8Encoding()) in fprintf w "%s" "hoge"; w.Result @> |> check "hoge" 43 | 44 | [] 45 | let ``fprintfn`` () = 46 | <@ let w = new RobWriter(System.Text.UTF8Encoding()) in fprintfn w "hoge"; w.Result @> |> check (appendNewLine "hoge") 47 | <@ let w = new RobWriter(System.Text.UTF8Encoding()) in fprintfn w "hoge%d" 1; w.Result @> |> check (appendNewLine "hoge1") 48 | <@ let w = new RobWriter(System.Text.UTF8Encoding()) in fprintfn w "%s" "hoge"; w.Result @> |> check (appendNewLine "hoge") 49 | 50 | [] 51 | let ``printf`` () = 52 | <@ printf "hoge" @> |> checkPrinted Out "hoge" 53 | <@ printf "hoge%d" 1 @> |> checkPrinted Out "hoge1" 54 | <@ printf "%s" "hoge" @> |> checkPrinted Out "hoge" 55 | 56 | [] 57 | let ``printfn`` () = 58 | <@ printfn "hoge" @> |> checkPrinted Out (appendNewLine "hoge") 59 | <@ printfn "hoge%d" 1 @> |> checkPrinted Out (appendNewLine "hoge1") 60 | <@ printfn "%s" "hoge" @> |> checkPrinted Out (appendNewLine "hoge") 61 | 62 | [] 63 | let ``failwith`` () = <@ failwith "hoge" @> |> checkExnMsg "hoge" 64 | 65 | [] 66 | let ``failwithf`` () = 67 | <@ failwithf "hoge" @> |> checkExnMsg "hoge" 68 | <@ failwithf "hoge%d" 1 @> |> checkExnMsg "hoge1" 69 | <@ failwithf "%s" "hoge" @> |> checkExnMsg "hoge" 70 | 71 | [] 72 | let ``sprintf`` () = 73 | <@ sprintf "hoge" @> |> check "hoge" 74 | <@ sprintf "hoge%d" 1 @> |> check "hoge1" 75 | <@ sprintf "%s" "hoge" @> |> check "hoge" 76 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/FSharp.Quotations.Compiler.Tests.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Development 6 | AnyCPU 7 | 2.0 8 | 6b9e5f15-6da0-4d39-aab7-b28986d9447c 9 | Library 10 | FSharp.Quotations.Compiler.Tests 11 | FSharp.Quotations.Compiler.Tests 12 | v4.5 13 | 4.3.0.0 14 | FSharp.Quotations.Compiler.Tests 15 | 16 | ..\..\ 17 | 18 | 19 | true 20 | full 21 | false 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | 3 26 | bin\Debug\fsharp_project_scaffold_tests.XML 27 | Project 28 | 29 | 30 | 31 | 32 | 33 | 34 | pdbonly 35 | true 36 | true 37 | bin\Release\ 38 | TRACE;FULLTEST 39 | 3 40 | bin\Release\FSharp.Quotations.Compiler.Tests.xml 41 | 42 | 43 | 11 44 | 45 | 46 | true 47 | full 48 | false 49 | false 50 | TRACE;DEBUG 51 | 3 52 | bin\Debug\fsharp_project_scaffold_tests.XML 53 | Project 54 | 55 | 56 | bin\Debug\ 57 | 58 | 59 | 60 | 61 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets 62 | 63 | 64 | 65 | 66 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets 67 | 68 | 69 | 70 | 71 | 72 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | FSharp.Quotations.Compiler.Tests.CSharp 114 | {b69bd2f7-bd0b-4dec-af95-6069212101a8} 115 | True 116 | 117 | 118 | 119 | True 120 | 121 | 122 | 123 | 124 | 125 | FSharp.Quotations.Compiler 126 | {5beaa1fd-4b61-43a0-9dc6-351c4121d877} 127 | True 128 | 129 | 130 | 131 | 132 | 133 | 134 | ..\..\packages\FsUnit\Lib\Net20\FsUnit.NUnit.dll 135 | True 136 | True 137 | 138 | 139 | 140 | 141 | 142 | 143 | ..\..\packages\FsUnit\Lib\Net40\FsUnit.NUnit.dll 144 | True 145 | True 146 | 147 | 148 | 149 | 150 | 151 | 152 | ..\..\packages\NUnit\lib\nunit.framework.dll 153 | True 154 | True 155 | 156 | 157 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/FSharpTypeTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | [] 16 | module FSharpTypeTest = 17 | type Record = { 18 | Value1: int 19 | Value2: string 20 | } 21 | 22 | [] 23 | let ``new record`` () = 24 | <@ { Value1 = 10; Value2 = "str" } @> |> check { Value1 = 10; Value2 = "str" } 25 | 26 | [] 27 | let ``new generic record`` () = 28 | <@ { contents = 10 } @> |> check (ref 10) 29 | 30 | type SimpleDU = Tag 31 | 32 | [] 33 | let ``new simple DU`` () = <@ Tag @> |> check Tag 34 | 35 | type SimpleDUWithValue = Tag of int 36 | 37 | [] 38 | let ``new simple DU with value`` () = <@ Tag 42 @> |> check (Tag 42) 39 | 40 | [] 41 | let ``option`` () = 42 | <@ Some 42 @> |> check (Some 42) 43 | <@ None @> |> check None 44 | 45 | [] 46 | let ``tuple get`` () = 47 | <@ let a, b = 10, "hoge" in string a + b @> 48 | |> check "10hoge" 49 | 50 | [] 51 | let ``10 tuple get`` () = 52 | <@ 53 | let x1, x2, x3, x4, x5, x6, x7, x8, x9, x10 = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 54 | [x1; x2; x3; x4; x5; x6; x7; x8; x9; x10] 55 | @> 56 | |> check [1..10] 57 | 58 | [] 59 | let ``15 tuple get`` () = 60 | <@ 61 | let x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 62 | [x1; x2; x3; x4; x5; x6; x7; x8; x9; x10; x11; x12; x13; x14; x15] 63 | @> 64 | |> check [1..15] 65 | 66 | [] 67 | let ``create ref`` () = 68 | <@ ref 42 @> |> check (ref 42) 69 | <@ ref "" @> |> check (ref "") 70 | 71 | [] 72 | let ``reference ref`` () = 73 | <@ let x = ref 42 in !x @> |> check 42 74 | <@ let x = ref "" in !x @> |> check "" 75 | 76 | [] 77 | let ``substitute ref`` () = 78 | <@ let x = ref 42 in x := 10; !x @> |> check 10 79 | <@ let x = ref "" in x := "str"; !x @> |> check "str" 80 | 81 | [] 82 | let ``incr ref`` () = <@ let x = ref 0 in incr x; !x @> |> check 1 83 | 84 | [] 85 | let ``decr ref`` () = <@ let x = ref 0 in decr x; !x @> |> check -1 86 | 87 | [] 88 | [] 89 | [] 90 | [] 91 | let ``partial apply`` (a, b) = 92 | <@ let f x = (||) x in f a b @> |> check (a || b) 93 | <@ let f x = (&&) x in f a b @> |> check (a && b) -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/LetTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | [] 16 | module LetTest = 17 | [] 18 | let ``simple let`` () = <@ let n = 42 in n @> |> check 42 19 | 20 | [] 21 | let ``mutable let`` () = 22 | <@ let mutable n = 42 23 | ignore n 24 | n <- 0 25 | n @> 26 | |> check 0 27 | 28 | [] 29 | let ``nested let`` () = 30 | <@ let a = 10 31 | let b = a * 2 32 | let a = b + 2 33 | a @> 34 | |> check 22 35 | 36 | [] 37 | let ``more nested let`` () = 38 | <@ let a = 10 39 | let b = 40 | let a = a * 2 41 | a + 2 42 | a + b @> 43 | |> check 32 44 | 45 | [] 46 | let ``simple let rec`` () = <@ let rec n = 42 in n @> |> check 42 47 | 48 | [] 49 | let ``let _`` () = <@ let _ = 10 in true @> |> check true 50 | 51 | [] 52 | let ``let rec list`` () = 53 | <@ 54 | let rec a = 10 55 | and b = 20 56 | a + b 57 | @> 58 | |> check 30 59 | 60 | [] 61 | let ``application`` () = 62 | <@ 63 | let f (x: obj) = 64 | match x with 65 | | :? string -> "str" 66 | | :? int -> "int" 67 | | _ -> "other" 68 | (f ("hoge" :> obj)) + (f (20 :> obj)) 69 | @> 70 | |> check "strint" 71 | 72 | [] 73 | let ``application 2`` () = 74 | <@ 75 | let f a b = a + b 76 | f 10 20 77 | @> 78 | |> check 30 79 | 80 | [] 81 | let ``nested application`` () = 82 | <@ 83 | let f x = x + 10 84 | (fun x -> f x) 20 85 | @> 86 | |> check 30 87 | 88 | [] 89 | let ``application try-with`` () = 90 | let expr = <@ let const10 = fun (_: int) -> 10 in const10 (try 1 with _ -> 0) @> 91 | expr |> check 10 92 | 93 | [] 94 | let ``application try-finally`` () = 95 | let expr = <@ let const10 = fun (_: int) -> 10 in const10 (try 1 finally ()) @> 96 | expr |> check 10 97 | 98 | [] 99 | let ``nested unit property binding`` () = 100 | <@ let x = let y = Some () in y.Value in x @> |> check () 101 | 102 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/Limitations.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | open System 16 | open System.Collections.Generic 17 | open Microsoft.FSharp.Quotations 18 | 19 | [] 20 | module Limitations = 21 | 22 | let inline f1 x y = x + y 23 | let inline f2 x y = x - y 24 | 25 | [] 26 | let ``inline function`` () = 27 | <@ f1 20 10 @> |> check 30 // It's OK but... 28 | <@ f2 20 10 @> |> checkExnType (typeof) // (-) has NoDynamicInvocationAttribute. So it throws NotSupportedException. 29 | 30 | [] 31 | let ``mutable and try finally`` () = 32 | // try-finally is compiled to lambda. 33 | <@ let mutable x = 0 34 | try 35 | // This x is the field of the lambda. 36 | // So this assignment does not affect to outer x. 37 | x <- 10 38 | finally 39 | // This x is the field of the lambda. 40 | // So this assignment does not affect to outer x. 41 | x <- 20 42 | x @> 43 | |> check 0 44 | 45 | [] 46 | let ``mutable and try with`` () = 47 | // try-with is compiled to lambda. 48 | <@ let mutable x = 0 49 | try 50 | // This x is the field of the lambda. 51 | // So this assignment does not affect to outer x. 52 | x <- 10 53 | with 54 | | _ -> 55 | // This x is the field of the lambda. 56 | // So this assignment does not affect to outer x. 57 | x <- 20 58 | x @> 59 | |> check 0 60 | 61 | let rec factOuterQuotation = function 62 | | 0 -> 1 63 | | n -> n * (factOuterQuotation (n - 1)) 64 | 65 | [] 66 | let ``let rec`` () = 67 | <@ factOuterQuotation 5 @> |> check 120 // It's OK but... 68 | <@ let rec factInnerQuotation = function 69 | | 0 -> 1 70 | | n -> n * (factInnerQuotation (n - 1)) // Reference to factInnerQuotation does not exist in varenv at this point yet. 71 | factInnerQuotation 5 @> 72 | |> checkExnType (typeof) // So it throws KeyNotFoundException. 73 | 74 | let cast<'T> (expr: Expr) : Expr<'T> = expr |> Expr.Cast 75 | 76 | [] 77 | let ``Expr.Value is not supported the value type that does not have the literal`` () = 78 | Expr.Value(DateTime.Now) |> cast |> checkExnType (typeof) -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/ListTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | #nowarn "1104" 16 | 17 | [] 18 | module ListTest = 19 | [] 20 | let ``int list @ int list`` () = 21 | <@ [1; 2; 3] @ [4; 5; 6] @> |> check [1..6] 22 | <@ [1; 2; 3] @ [] @> |> check [1..3] 23 | <@ [] @ [4; 5; 6] @> |> check [4..6] 24 | 25 | [] 26 | let ``string list @ string list`` () = 27 | <@ ["a"; "b"] @ ["c"; "d"] @> |> check ["a"; "b"; "c"; "d"] 28 | <@ ["a"; "b"] @ [] @> |> check ["a"; "b"] 29 | <@ [] @ ["c"; "d"] @> |> check ["c"; "d"] 30 | 31 | [] 32 | let ``cons`` () = 33 | <@ 1::2::3::[] @> |> check [1..3] 34 | <@ "a"::"b"::"c"::[] @> |> check ["a"; "b"; "c"] 35 | 36 | [] 37 | let ``cons match`` () = 38 | <@ match [1..3] with 39 | | x::xs -> (x * 10) + (xs.Length) 40 | | [] -> -1 @> 41 | |> check 12 42 | 43 | [] 44 | let ``empty`` () = 45 | <@ List.empty : int list @> |> check [] 46 | <@ List.empty : string list @> |> check [] 47 | 48 | [] 49 | let ``sum`` () = <@ List.sum [1..10] @> |> check (List.sum [1..10]) 50 | 51 | [] 52 | let ``sumBy`` () = <@ List.sumBy int ["1"; "2"] @> |> check 3 53 | 54 | [] 55 | let ``filter`` () = 56 | <@ [1..10] |> List.filter (fun x -> x < 3) @> |> check [1; 2] 57 | <@ [1..10] |> List.filter ((=)5) @> |> check [5] -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/LiteralTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | [] 16 | module LiteralTest = 17 | [] 18 | let unit () = <@ () @> |> check () 19 | 20 | #if FULLTEST 21 | [] 22 | let int ([] i: int) = <@ i @> |> check i 23 | #else 24 | [] 25 | let int () = <@ 42 @> |> check 42 26 | #endif 27 | 28 | [] 29 | [] 30 | [] 31 | [] 32 | let ``byte`` (b:byte) = <@ b @> |> check b 33 | 34 | // TODO : more tests 35 | [] 36 | let sbyte () = <@ 1y @> |> check 1y 37 | 38 | // TODO : more tests 39 | [] 40 | let int16 () = <@ 1s @> |> check 1s 41 | 42 | // TODO : more tests 43 | [] 44 | let uint16 () = <@ 1us @> |> check 1us 45 | 46 | // TODO : more tests 47 | [] 48 | let uint32 () = <@ 1u @> |> check 1u 49 | 50 | #if FULLTEST 51 | [] 52 | let char ([] c: char) = <@ c @> |> check c 53 | #else 54 | [] 55 | let char () = <@ 'a' @> |> check 'a' 56 | #endif 57 | 58 | [] 59 | [] 60 | let bool (b: bool) = <@ b @> |> check b 61 | 62 | [] 63 | [] 64 | [] 65 | let int64 (i: int64) = <@ i @> |> check i 66 | 67 | [] 68 | [] 69 | [] 70 | let uint64 (i: uint64) = <@ i @> |> check i 71 | 72 | // TODO : more tests 73 | [] 74 | let bigint () = <@ 1I @> |> check 1I 75 | 76 | // TODO : more tests 77 | [] 78 | let float32 () = <@ 42.0f @> |> check 42.0f 79 | 80 | [] 81 | let float () = <@ 42.0 @> |> check 42.0 82 | 83 | // TODO : more tests 84 | [] 85 | let decimal () = 86 | <@ 42.0m @> |> check 42.0m 87 | <@ 42.0M @> |> check 42.0M 88 | 89 | [] 90 | [] 91 | let string (str: string) = <@ str @> |> check str 92 | 93 | [] 94 | let array () = 95 | <@ [||] @> |> check [||] 96 | <@ [|1; 2; 3|] @> |> check [|1; 2; 3|] 97 | <@ [|1..3|] @> |> check [|1; 2; 3|] 98 | <@ [|1..2..5|] @> |> check [|1; 3; 5|] 99 | 100 | [] 101 | let list () = 102 | <@ [] @> |> check [] 103 | <@ [1; 2; 3] @> |> check [1; 2; 3] 104 | <@ [1..3] @> |> check [1; 2; 3] 105 | <@ [1..2..5] @> |> check [1; 3; 5] 106 | 107 | [] 108 | let tuple () = 109 | <@ (1, "str") @> |> check (1, "str") 110 | <@ (1, 2, 3) @> |> check (1, 2, 3) 111 | 112 | [] 113 | let ``many tuple`` () = 114 | <@ (1, 2, 3, 4, 5, 6, 7, 8) @> |> check (1, 2, 3, 4, 5, 6, 7, 8) 115 | <@ (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) @> |> check (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) 116 | 117 | [] 118 | let ``nested tuple`` () = 119 | <@ (1, ("str", true)) @> |> check (1, ("str", true)) 120 | <@ (1, (1, 2, 3, 4, 5, 6, 7, 8)) @> |> check (1, (1, 2, 3, 4, 5, 6, 7, 8)) 121 | 122 | [] 123 | [] 124 | [] 125 | let ``byte .. byte`` (a:byte, b:byte) = <@ [a .. b] @> |> check [a .. b] 126 | 127 | [] 128 | [] 129 | [] 130 | [] 131 | [] 132 | let ``byte .. byte .. byte`` (a:byte, b:byte, c:byte) = <@ [a .. b .. c] @> |> check [a .. b .. c] 133 | 134 | [] 135 | let ``byte .. 0 .. byte`` (a:byte, b:byte) = <@ [a .. 0uy .. b] @> |> checkExn<_, System.ArgumentException> 136 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/MathFuncTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | [] 16 | module MathFuncTest = 17 | [] 18 | let ``abs int`` () = <@ abs -1 @> |> check 1 19 | 20 | [] 21 | let ``abs bigint`` () = <@ abs -1I @> |> check 1I 22 | 23 | [] 24 | let ``abs float`` () = <@ abs -1.0 @> |> check 1.0 25 | 26 | [] 27 | let ``abs decimal`` () = <@ abs -1.0M @> |> check 1.0M 28 | 29 | [] 30 | let ``acos float`` () = <@ acos 0.5 @> |> check (acos 0.5) 31 | 32 | [] 33 | let ``asin float`` () = <@ asin 0.5 @> |> check (asin 0.5) 34 | 35 | [] 36 | let ``atan float`` () = <@ atan 0.5 @> |> check (atan 0.5) 37 | 38 | [] 39 | let ``atan2 float float`` () = <@ atan2 0.5 -0.5 @> |> check (atan2 0.5 -0.5) 40 | 41 | [] 42 | let ``ceil float`` () = <@ ceil 1.5 @> |> check 2.0 43 | 44 | [] 45 | let ``ceil decimal`` () = <@ ceil 1.5M @> |> check 2.0M 46 | 47 | [] 48 | let ``cos float`` () = <@ cos 0.5 @> |> check (cos 0.5) 49 | 50 | [] 51 | let ``cosh float`` () = <@ cosh 0.5 @> |> check (cosh 0.5) 52 | 53 | [] 54 | let ``exp float`` () = <@ exp 0.5 @> |> check (exp 0.5) 55 | 56 | [] 57 | let ``floor float`` () = <@ floor 1.5 @> |> check 1.0 58 | 59 | [] 60 | let ``floor decimal`` () = <@ floor 1.5M @> |> check 1.0M 61 | 62 | [] 63 | let ``infinity`` () = <@ infinity @> |> check infinity 64 | 65 | [] 66 | let ``log float`` () = <@ log 0.5 @> |> check (log 0.5) 67 | 68 | [] 69 | let ``log10 float`` () = <@ log10 0.5 @> |> check (log10 0.5) 70 | 71 | [] 72 | let ``nan`` () = <@ nan @> |> check nan 73 | 74 | [] 75 | let ``pown bigint int`` () = <@ pown 2I 2 @> |> check (pown 2I 2) 76 | 77 | [] 78 | let ``pown float int`` () = <@ pown 0.5 2 @> |> check (pown 0.5 2) 79 | 80 | [] 81 | let ``pown decimal int`` () = <@ pown 0.5M 2 @> |> check (pown 0.5M 2) 82 | 83 | [] 84 | let ``round float`` () = <@ round 0.5 @> |> check (round 0.5) 85 | 86 | [] 87 | let ``round decimal`` () = <@ round 0.5M @> |> check (round 0.5M) 88 | 89 | [] 90 | let ``sign int`` () = <@ sign -10 @> |> check -1 91 | 92 | [] 93 | let ``sign bigint`` () = <@ sign -10I @> |> check (sign -10I) 94 | 95 | [] 96 | let ``sign float`` () = <@ sign -1.0 @> |> check -1 97 | 98 | [] 99 | let ``sign decimal`` () = <@ sign -1.0M @> |> check -1 100 | 101 | [] 102 | let ``sin float`` () = <@ sin 0.5 @> |> check (sin 0.5) 103 | 104 | [] 105 | let ``sinh float`` () = <@ sinh 0.5 @> |> check (sinh 0.5) 106 | 107 | [] 108 | let ``sqrt float`` () = <@ sqrt 0.5 @> |> check (sqrt 0.5) 109 | 110 | [] 111 | let ``tan float`` () = <@ tan 0.5 @> |> check (tan 0.5) 112 | 113 | [] 114 | let ``tanh float`` () = <@ tanh 0.5 @> |> check (tanh 0.5) 115 | 116 | [] 117 | let ``truncate float`` () = <@ truncate 0.5 @> |> check (truncate 0.5) 118 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/NullableTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | open System 16 | open Microsoft.FSharp.Linq.NullableOperators 17 | 18 | module NumericLiteralN = 19 | let n x = Nullable<_>(x) 20 | 21 | let inline FromZero () = n LanguagePrimitives.GenericZero 22 | let inline FromOne () = n LanguagePrimitives.GenericOne 23 | let FromInt32 x = n x 24 | 25 | [] 26 | module NullableTest = 27 | let nil<'T when 'T : (new: unit -> 'T) and 'T : struct and 'T :> ValueType> = Nullable<'T>() 28 | 29 | [] 30 | let ``?>=`` () = 31 | <@ 10N ?>= 5 @> |> check true 32 | <@ 5N ?>= 5 @> |> check true 33 | <@ 0N ?>= 5 @> |> check false 34 | <@ nil ?>= 5 @> |> check false 35 | 36 | [] 37 | let ``?>`` () = 38 | <@ 10N ?> 5 @> |> check true 39 | <@ 5N ?> 5 @> |> check false 40 | <@ 0N ?> 5 @> |> check false 41 | <@ nil ?> 5 @> |> check false 42 | 43 | [] 44 | let ``?<=`` () = 45 | <@ 10N ?<= 5 @> |> check false 46 | <@ 5N ?<= 5 @> |> check true 47 | <@ 0N ?<= 5 @> |> check true 48 | <@ nil ?<= 5 @> |> check false 49 | 50 | [] 51 | let ``?<`` () = 52 | <@ 10N ?< 5 @> |> check false 53 | <@ 5N ?< 5 @> |> check false 54 | <@ 0N ?< 5 @> |> check true 55 | <@ nil ?< 5 @> |> check false 56 | 57 | [] 58 | let ``?=`` () = 59 | <@ 10N ?= 5 @> |> check false 60 | <@ 5N ?= 5 @> |> check true 61 | <@ 0N ?= 5 @> |> check false 62 | <@ nil ?= 5 @> |> check false 63 | 64 | [] 65 | let ``?<>`` () = 66 | <@ 10N ?<> 5 @> |> check true 67 | <@ 5N ?<> 5 @> |> check false 68 | <@ 0N ?<> 5 @> |> check true 69 | <@ nil ?<> 5 @> |> check true 70 | 71 | [] 72 | let ``?+`` () = 73 | <@ 10N ?+ 5 @> |> check 15N 74 | <@ nil ?+ 5 @> |> check nil 75 | 76 | [] 77 | let ``+?`` () = 78 | <@ 10 +? 5N @> |> check 15N 79 | <@ 5 +? nil @> |> check nil 80 | 81 | [] 82 | let ``?+?`` () = 83 | <@ 10N ?+? 5N @> |> check 15N 84 | <@ 5N ?+? nil @> |> check nil 85 | <@ nil ?+? 5N @> |> check nil 86 | <@ nil ?+? nil @> |> check nil 87 | 88 | [] 89 | let ``?-`` () = 90 | <@ 10N ?- 5 @> |> check 5N 91 | <@ nil ?- 5 @> |> check nil 92 | 93 | [] 94 | let ``-?`` () = 95 | <@ 10 -? 5N @> |> check 5N 96 | <@ 5 -? nil @> |> check nil 97 | 98 | [] 99 | let ``?-?`` () = 100 | <@ 10N ?-? 5N @> |> check 5N 101 | <@ 5N ?-? nil @> |> check nil 102 | <@ nil ?-? 5N @> |> check nil 103 | <@ nil ?-? nil @> |> check nil 104 | 105 | [] 106 | let ``?*`` () = 107 | <@ 10N ?* 5 @> |> check 50N 108 | <@ nil ?* 5 @> |> check nil 109 | 110 | [] 111 | let ``*?`` () = 112 | <@ 10 *? 5N @> |> check 50N 113 | <@ 5 *? nil @> |> check nil 114 | 115 | [] 116 | let ``?*?`` () = 117 | <@ 10N ?*? 5N @> |> check 50N 118 | <@ 5N ?*? nil @> |> check nil 119 | <@ nil ?*? 5N @> |> check nil 120 | <@ nil ?*? nil @> |> check nil 121 | 122 | [] 123 | let ``?/`` () = 124 | <@ 10N ?/ 5 @> |> check 2N 125 | <@ nil ?/ 5 @> |> check nil 126 | 127 | [] 128 | let ``/?`` () = 129 | <@ 10 /? 5N @> |> check 2N 130 | <@ 5 /? nil @> |> check nil 131 | 132 | [] 133 | let ``?/?`` () = 134 | <@ 10N ?/? 5N @> |> check 2N 135 | <@ 5N ?/? nil @> |> check nil 136 | <@ nil ?/? 5N @> |> check nil 137 | <@ nil ?/? nil @> |> check nil 138 | 139 | [] 140 | let ``?%`` () = 141 | <@ 10N ?% 5 @> |> check 0N 142 | <@ nil ?% 5 @> |> check nil 143 | 144 | [] 145 | let ``%?`` () = 146 | <@ 10 %? 5N @> |> check 0N 147 | <@ 5 %? nil @> |> check nil 148 | 149 | [] 150 | let ``?%?`` () = 151 | <@ 10N ?%? 5N @> |> check 0N 152 | <@ 5N ?%? nil @> |> check nil 153 | <@ nil ?%? 5N @> |> check nil 154 | <@ nil ?%? nil @> |> check nil -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/ObjTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | open System 16 | open FSharp.Quotations.Compiler.Tests.CSharp 17 | 18 | [] 19 | module ObjTest = 20 | type Class (value: int) as this = 21 | [] val mutable public InstanceField : string 22 | do 23 | this.InstanceField <- "str" 24 | member val Value = value with get, set 25 | static member val SValue = -1 with get, set 26 | member __.VarArgMethod([] xs: int[]) = xs.Length 27 | member __.OptArgMethod(x: int, ?y: int) = x + (defaultArg y -1) 28 | override __.Equals(x) = 29 | match x with 30 | | :? Class as other -> value = other.Value 31 | | _ -> false 32 | override __.GetHashCode() = value 33 | override __.ToString() = sprintf "Class(%d)" value 34 | 35 | [] 36 | let ``new`` () = <@ new Class(42) @> |> check (new Class(42)) 37 | 38 | [] 39 | let ``struct default value`` () = <@ System.Guid() @> |> check (System.Guid()) 40 | 41 | [] 42 | let ``variable argument method call`` () = 43 | <@ let x = Class(42) 44 | x.VarArgMethod(10, 20, 30) @> 45 | |> check 3 46 | 47 | // call variable argument method written by C# 48 | <@ String.Format("{0}{1}", "hoge", 42) @> |> check "hoge42" 49 | 50 | [] 51 | let ``optional argument method call`` () = 52 | <@ let x = Class(42) 53 | x.OptArgMethod(10) @> 54 | |> check 9 55 | 56 | // call optional argument method written by C# 57 | <@ CSharpClass.OptionalArgument(10) @> |> check 9 58 | 59 | [] 60 | let ``ToString()`` () = <@ (Class(42).ToString()) @> |> check (Class(42).ToString()) 61 | 62 | [] 63 | let ``property get`` () = <@ (Class(42)).Value @> |> check 42 64 | 65 | [] 66 | let ``property set`` () = 67 | <@ let c = Class(42) 68 | c.Value <- 10 69 | c.Value 70 | @> |> check 10 71 | 72 | [] 73 | let ``static property get`` () = <@ Class.SValue @> |> check -1 74 | 75 | [] 76 | let ``static property set`` () = 77 | <@ Class.SValue <- 10 78 | Class.SValue 79 | @> |> check 10 80 | 81 | [] 82 | let ``field get`` () = <@ let c = Class(10) in c.InstanceField @> |> check "str" 83 | 84 | [] 85 | let ``field set`` () = 86 | <@ let c = Class(10) 87 | c.InstanceField <- "new str" 88 | c.InstanceField 89 | @> |> check "new str" 90 | 91 | [] 92 | let ``static field get`` () = <@ CSharpClass.StaticField @> |> check CSharpClass.StaticField 93 | 94 | [] 95 | let ``static field set`` () = 96 | let initialStaticFieldValue = CSharpClass.StaticField 97 | try 98 | <@ CSharpClass.StaticField <- initialStaticFieldValue * 2 99 | CSharpClass.StaticField @> 100 | |> check (initialStaticFieldValue * 2) 101 | finally 102 | CSharpClass.StaticField <- initialStaticFieldValue 103 | 104 | [] 105 | type Struct(i: int) = 106 | member __.Value = i 107 | 108 | [] 109 | let ``copied struct property get`` () = 110 | <@ 111 | let x = Struct(1) 112 | let y = x 113 | y.Value 114 | @> 115 | |> check 1 116 | 117 | [] 118 | let ``struct property get`` () = 119 | <@ Struct(1).Value @> 120 | |> check 1 121 | 122 | [] 123 | let ``value type stringify`` () = 124 | <@ (1).ToString() @> |> check ((1).ToString()) 125 | <@ (true).ToString() @> |> check ((true).ToString()) 126 | <@ 'a'.ToString() @> |> check ('a'.ToString()) 127 | <@ "aaa".ToString() @> |> check ("aaa".ToString()) 128 | <@ (box 1).ToString() @> |> check ((box 1).ToString()) 129 | <@ (box true).ToString() @> |> check ((box true).ToString()) 130 | <@ (box 'a').ToString() @> |> check ((box 'a').ToString()) 131 | <@ (box "aaa").ToString() @> |> check ((box "aaa").ToString()) 132 | <@ Struct(1).ToString() @> |> check (Struct(1).ToString()) 133 | 134 | [] 135 | let ``value type stringify in lambda`` () = 136 | <@ (fun (x: int) -> x.ToString()) 42 @> |> check "42" 137 | 138 | [] 139 | let ``value type stringify in lambda2`` () = 140 | <@ let x = 42 in (fun () -> x.ToString()) () @> |> check "42" 141 | 142 | [] 143 | let ``value type get type`` () = 144 | <@ (1).GetType() @> |> check ((1).GetType()) 145 | <@ (true).GetType() @> |> check ((true).GetType()) 146 | <@ 'a'.GetType() @> |> check ('a'.GetType()) 147 | <@ "aaa".GetType() @> |> check ("aaa".GetType()) 148 | <@ (box 1).GetType() @> |> check ((box 1).GetType()) 149 | <@ (box true).GetType() @> |> check ((box true).GetType()) 150 | <@ (box 'a').GetType() @> |> check ((box 'a').GetType()) 151 | <@ (box "aaa").GetType() @> |> check ((box "aaa").GetType()) 152 | <@ Struct(1).GetType() @> |> check (Struct(1).GetType()) 153 | 154 | [] 155 | [] 156 | [] 157 | let ``int compare to`` (a: int, b: int) = 158 | <@ let a = a in a.CompareTo(b) @> |> check (a.CompareTo(b)) 159 | <@ let a = a :> IComparable<_> in a.CompareTo(b) @> |> check ((a :> IComparable<_>).CompareTo(b)) 160 | 161 | [] 162 | let ``bool compare to`` ([] a: bool, [] b: bool) = 163 | <@ let a = a in a.CompareTo(b) @> |> check (a.CompareTo(b)) 164 | <@ let a = a :> IComparable<_> in a.CompareTo(b) @> |> check ((a :> IComparable<_>).CompareTo(b)) 165 | 166 | [] 167 | [] 168 | [] 169 | let ``char compare to`` (a: char, b: char) = 170 | <@ let a = a in a.CompareTo(b) @> |> check (a.CompareTo(b)) 171 | <@ let a = a :> IComparable<_> in a.CompareTo(b) @> |> check ((a :> IComparable<_>).CompareTo(b)) 172 | 173 | [] 174 | [] 175 | [] 176 | let ``string compare to`` (a: string, b: string) = 177 | <@ let a = a in a.CompareTo(b) @> |> check (a.CompareTo(b)) 178 | <@ let a = a :> IComparable<_> in a.CompareTo(b) @> |> check ((a :> IComparable<_>).CompareTo(b)) 179 | 180 | [] 181 | let ``value type compare to null`` () = 182 | <@ (1).CompareTo(null) @> |> check ((1).CompareTo(null)) 183 | <@ (true).CompareTo(null) @> |> check ((true).CompareTo(null)) 184 | <@ 'a'.CompareTo(null) @> |> check ('a'.CompareTo(null)) 185 | <@ "aaa".CompareTo(null) @> |> check ("aaa".CompareTo(null)) 186 | <@ (1 :> IComparable).CompareTo(null) @> |> check ((1 :> IComparable).CompareTo(null)) 187 | <@ (true :> IComparable).CompareTo(null) @> |> check ((true :> IComparable).CompareTo(null)) 188 | <@ ('a' :> IComparable).CompareTo(null) @> |> check (('a' :> IComparable).CompareTo(null)) 189 | <@ ("aaa" :> IComparable).CompareTo(null) @> |> check (("aaa" :> IComparable).CompareTo(null)) 190 | 191 | [] 192 | [] 193 | [] 194 | let ``int equals`` (a: int, b: int) = 195 | <@ let a = a in a.Equals(b) @> |> check (a.Equals(b)) 196 | <@ let a = a in a.Equals(box b) @> |> check (a.Equals(box b)) 197 | <@ let a = a in (box a).Equals(box b) @> |> check ((box a).Equals(box b)) 198 | 199 | [] 200 | let ``bool equals`` ([] a: bool, [] b: bool) = 201 | <@ let a = a in a.Equals(b) @> |> check (a.Equals(b)) 202 | <@ let a = a in a.Equals(box b) @> |> check (a.Equals(box b)) 203 | <@ let a = a in (box a).Equals(box b) @> |> check ((box a).Equals(box b)) 204 | 205 | [] 206 | [] 207 | [] 208 | let ``char equals`` (a: char, b: char) = 209 | <@ let a = a in a.Equals(b) @> |> check (a.Equals(b)) 210 | <@ let a = a in a.Equals(box b) @> |> check (a.Equals(box b)) 211 | <@ let a = a in (box a).Equals(box b) @> |> check ((box a).Equals(box b)) 212 | 213 | [] 214 | [] 215 | [] 216 | let ``string equals`` (a: string, b: string) = 217 | <@ let a = a in a.Equals(b) @> |> check (a.Equals(b)) 218 | <@ let a = a in a.Equals(box b) @> |> check (a.Equals(box b)) 219 | <@ let a = a in (box a).Equals(box b) @> |> check ((box a).Equals(box b)) 220 | 221 | [] 222 | let ``value type equals null`` () = 223 | <@ (1).CompareTo(null) @> |> check ((1).CompareTo(null)) 224 | <@ (true).CompareTo(null) @> |> check ((true).CompareTo(null)) 225 | <@ 'a'.CompareTo(null) @> |> check ('a'.CompareTo(null)) 226 | <@ "aaa".CompareTo(null) @> |> check ("aaa".CompareTo(null)) 227 | 228 | [] 229 | let ``struct equals`` () = 230 | <@ Struct(1).Equals(Struct(1)) @> |> check (Struct(1).Equals(Struct(1))) 231 | 232 | [] 233 | let ``value type get type code`` () = 234 | <@ (1).GetTypeCode() @> |> check ((1).GetTypeCode()) 235 | <@ (true).GetTypeCode() @> |> check ((true).GetTypeCode()) 236 | <@ 'a'.GetTypeCode() @> |> check ('a'.GetTypeCode()) 237 | <@ "aaa".GetTypeCode() @> |> check ("aaa".GetTypeCode()) 238 | 239 | [] 240 | let ``value type get hash code`` () = 241 | <@ (1).GetHashCode() @> |> check ((1).GetHashCode()) 242 | <@ (true).GetHashCode() @> |> check ((true).GetHashCode()) 243 | <@ 'a'.GetHashCode() @> |> check ('a'.GetHashCode()) 244 | <@ "aaa".GetHashCode() @> |> check ("aaa".GetHashCode()) 245 | <@ Struct(1).GetHashCode() @> |> check (Struct(1).GetHashCode()) 246 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/Pitfall.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | open System 16 | open Microsoft.FSharp.Quotations 17 | open Microsoft.FSharp.Quotations.Patterns 18 | open FsUnit 19 | 20 | #nowarn "25" 21 | 22 | [] 23 | module Pitfall = 24 | [] 25 | let ``pitfall: void method call expression returns unit as value of Type property`` () = 26 | let Call (_, mi, _) as expr = <@ Console.WriteLine() @> 27 | typeof |> should not' (equal typeof) 28 | mi.ReturnType |> should equal typeof 29 | expr.Type |> should equal typeof -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/RangeOpTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | [] 16 | module RangeOpTest = 17 | [] 18 | let ``byte .. byte`` () = 19 | <@ seq { 1uy..255uy } @> |> check (seq { 1uy..255uy }) 20 | <@ [ 1uy..255uy ] @> |> check [ 1uy..255uy ] 21 | 22 | [] 23 | let ``byte .. byte .. byte`` () = 24 | <@ seq { 1uy..2uy..255uy } @> |> check (seq { 1uy..2uy..255uy }) 25 | <@ [ 1uy..2uy..255uy ] @> |> check [ 1uy..2uy..255uy ] -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/SeqTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | module SeqTest = 16 | [] 17 | let ``int seq`` () = 18 | <@ seq [1..10] @> |> check (seq [1..10]) 19 | <@ seq { 1..10 } @> |> check (seq { 1..10 }) 20 | 21 | [] 22 | let ``empty`` () = 23 | <@ Seq.empty : int seq @> |> check Seq.empty 24 | <@ Seq.empty : string seq @> |> check Seq.empty 25 | 26 | [] 27 | let ``sum`` () = 28 | <@ Seq.sum [1..10] @> |> check (Seq.sum [1..10]) 29 | <@ Seq.sum (seq [1..10]) @> |> check (Seq.sum (seq [1..10])) 30 | <@ Seq.sum (seq { 1..10 }) @> |> check (Seq.sum (seq { 1..10 })) 31 | 32 | [] 33 | let ``sumBy`` () = 34 | <@ Seq.sumBy int ["1"; "2"] @> |> check 3 35 | <@ Seq.sumBy int (seq ["1"; "2"]) @> |> check 3 36 | <@ Seq.sumBy int (seq { yield "1"; yield "2" }) @> |> check 3 37 | 38 | [] 39 | let ``filter`` () = 40 | <@ [1..10] |> Seq.filter (fun x -> x < 3) @> |> check (seq [1; 2]) 41 | <@ [1..10] |> Seq.filter ((=)5) @> |> check (seq [5]) -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/StringFuncTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | open System 16 | 17 | [] 18 | module StringFuncTest = 19 | [] 20 | let ``String.Empty`` () = <@ String.Empty @> |> check "" 21 | 22 | [] 23 | let ``String.length`` () = 24 | <@ String.length "str" @> |> check 3 25 | <@ String.length null @> |> check 0 26 | 27 | [] 28 | let ``String.Length`` () = 29 | <@ "str".Length @> |> check 3 30 | <@ (null:string).Length @> |> checkExnType typeof 31 | 32 | [] 33 | let ``String.IndexOf`` () = 34 | <@ "str".IndexOf("r") @> |> check 2 35 | <@ (null:string).IndexOf("r") @> |> checkExnType typeof 36 | 37 | [] 38 | let ``String.map`` () = 39 | <@ String.map (fun ch -> char (int ch + 1)) "abc" @> 40 | |> check (String.map (fun ch -> char (int ch + 1)) "abc") 41 | 42 | [] 43 | let ``String.filter`` () = 44 | <@ String.forall (fun ch -> Char.IsLetter(ch)) "abc" @> |> check true 45 | 46 | [] 47 | let ``nested case`` () = 48 | <@ String.forall (fun ch -> Char.IsLetter(ch)) (String.map (fun ch -> char (int ch + 1)) "abc") @> |> check true -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/StringOpTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | #nowarn "62" 16 | 17 | [] 18 | module StringOpTest = 19 | [] 20 | [] 21 | [] 22 | [] 23 | let ``string ^ string`` (x, y) = <@ x ^ y @> |> check (x ^ y) -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/TestUtil.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | open NUnit.Framework 16 | open FsUnit 17 | 18 | open Microsoft.FSharp.Quotations 19 | open FSharp.Quotations.Compiler 20 | open System 21 | open System.IO 22 | 23 | [] 24 | module TestUtil = 25 | type TestModule () = 26 | inherit TestFixtureAttribute() 27 | 28 | type Test () = 29 | inherit TestAttribute() 30 | 31 | [] 32 | type Values ([] arguments: obj []) = 33 | inherit ValuesAttribute(arguments) 34 | 35 | [] 36 | type TestCase ([] arguments: obj []) = 37 | inherit TestCaseAttribute(arguments) 38 | 39 | type Ignore(message:string) = 40 | inherit IgnoreAttribute(message) 41 | 42 | type IntRange(from: int, ``to``: int, step: int) = 43 | inherit RangeAttribute(from, ``to``, step) 44 | 45 | new (from, ``to``) = IntRange(from, ``to``, 1) 46 | 47 | type CharRange(from: char, ``to``: char) = 48 | inherit ValuesAttribute([|from .. ``to``|] |> Array.map (fun e -> e :> obj)) 49 | 50 | new (from, ``to``) = CharRange(from, ``to``) 51 | 52 | let check (expected: 'T) (expr: Expr<'T>) = 53 | expr.Execute() 54 | |> should equal expected 55 | 56 | let checkExn<'T, 'TExn when 'TExn :> exn> (expr: Expr<'T>) = 57 | try 58 | expr.Execute() |> ignore 59 | Assert.Fail("exception is not thrown.") 60 | with :? 'TExn -> () 61 | 62 | let checkExnMsg<'T, 'TExn when 'TExn :> exn> (expected: string) (expr: Expr<'T>) = 63 | try 64 | expr.Execute() |> ignore 65 | Assert.Fail("exception is not thrown.") 66 | with 67 | :? 'TExn as e -> 68 | e.Message |> should equal expected 69 | 70 | let checkExnType (expectedType: Type) (expr: Expr<_>) = 71 | try 72 | expr.Execute() |> ignore 73 | Assert.Fail("exception is not thrown.") 74 | with e -> 75 | e.GetType() |> should equal expectedType 76 | 77 | type RobWriter(encoding: Text.Encoding) = 78 | inherit TextWriter() 79 | 80 | let mutable result = "" 81 | 82 | member __.Result = result 83 | 84 | override __.Encoding = encoding 85 | override __.Write(c: char) = 86 | result <- result + c.ToString() 87 | 88 | type PrintType = Error | Out 89 | 90 | let private getDefaultPrinter printType: (TextWriter * (TextWriter -> unit)) = 91 | match printType with 92 | | Error -> (stderr, fun w -> System.Console.SetError(w)) 93 | | Out -> (stdout, fun w -> System.Console.SetOut(w)) 94 | 95 | let checkPrinted printType (expected: string) (expr: Expr) = 96 | let (defaultPrinter, setter) = getDefaultPrinter printType 97 | use writer = new RobWriter(defaultPrinter.Encoding) 98 | setter writer 99 | expr.Execute() 100 | setter defaultPrinter 101 | writer.Result |> should equal expected 102 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/TypeOpTest.fs: -------------------------------------------------------------------------------- 1 | (* 2 | * FSharp.Quotations.Compiler - a compiler for F# expression tree 3 | * Written in 2015 by bleis-tift (hey_c_est_la_vie@hotmail.co.jp) 4 | * kyonmm, zakky-dev 5 | * 6 | * To the extent possible under law, the author(s) have dedicated all copyright 7 | * and related and neighboring rights to this software to the public domain worldwide. 8 | * This software is distributed without any warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication along with this software. 11 | * If not, see . 12 | *) 13 | namespace FSharp.Quotations.Compiler.Tests 14 | 15 | open System 16 | 17 | [] 18 | module TypeOpTest = 19 | 20 | [] 21 | let ``int :> obj`` () = <@ 42 :> obj @> |> check (42 :> obj) 22 | 23 | [] 24 | let ``bigint :> obj`` () = <@ 1I :> obj @> |> check (1I :> obj) 25 | 26 | [] 27 | let `` char :> obj`` () = <@ 'c' :> obj @> |> check ('c' :> obj) 28 | 29 | [] 30 | let ``decimal :> obj`` () = <@ 1M :> obj @> |> check (1M :> obj) 31 | 32 | [] 33 | [] 34 | [] 35 | [] 36 | let ``byte :> obj`` (b:byte) = <@ b :> obj @> |> check (b :> obj) 37 | 38 | [] 39 | let ``string :> obj`` () = <@ "hoge" :> obj @> |> check ("hoge" :> obj) 40 | 41 | [] 42 | let ``int :> IEquatable`` () = 43 | <@ 42 :> IEquatable @> |> check (42 :> IEquatable) 44 | 45 | [] 46 | let ``bigint :> IEquatable`` () = 47 | <@ 42I :> IEquatable @> |> check (42I :> IEquatable) 48 | 49 | [] 50 | let ``char :> IEquatable`` () = 51 | <@ 'c' :> IEquatable @> |> check ('c' :> IEquatable) 52 | 53 | [] 54 | let ``decimal :> IEquatable`` () = 55 | <@ 1M :> IEquatable @> |> check (1M :> IEquatable) 56 | 57 | [] 58 | [] 59 | [] 60 | [] 61 | let ``byte :> IEquatable`` (b:byte) = 62 | <@ b :> IEquatable @> |> check (b :> IEquatable) 63 | 64 | [] 65 | let ``string :> IEquatable`` () = 66 | <@ "hoge" :> IEquatable @> |> check ("hoge" :> IEquatable) 67 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /tests/FSharp.Quotations.Compiler.Tests/paket.references: -------------------------------------------------------------------------------- 1 | NUnit 2 | NUnit.Runners 3 | FsUnit --------------------------------------------------------------------------------