├── .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 | [](http://issuestats.com/github/bleis-tift/FSharp.Quotations.Compiler)
2 | [](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 |
32 |
33 |
34 |
35 | @RenderBody()
36 |
37 |
38 |
39 |
58 |
59 |
60 |
61 |
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 |
32 |
33 |
34 |
35 | @RenderBody()
36 |
37 |
38 |
39 |
58 |
59 |
60 |
61 |
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 | [