项目作者: solodon4

项目描述 :
Functional programming style pattern-matching library for C++
高级语言: C++
项目地址: git://github.com/solodon4/Mach7.git
创建时间: 2014-05-27T02:03:55Z
项目社区:https://github.com/solodon4/Mach7

开源协议:Other

下载




Mach7: Pattern Matching for C++ Build Status: Linux, OSX Build Status: Windows Build Status: GitHub Actions

by Yuriy Solodkyy, Gabriel Dos Reis, Bjarne Stroustrup

Abstract

Pattern matching is an abstraction mechanism that can greatly simplify source code.
Commonly, pattern matching is built into a language to provide better syntax, faster
code, correctness guarantees and improved diagnostics. Mach7 is a library solution
to pattern matching in C++ that maintains many of these features. All the patterns
in Mach7 are user-definable, can be stored in variables, passed among functions,
and allow the use of open class hierarchies.

Mach7 by Example

Fibonacci numbers demonstrates the use of patterns with built-in types in Mach7:

  1. // Fibonacci numbers
  2. int fib(int n)
  3. {
  4. var<int> m;
  5. Match(n)
  6. {
  7. Case(1) return 1;
  8. Case(2) return 1;
  9. Case(2*m) return sqr(fib(m+1)) - sqr(fib(m-1));
  10. Case(2*m+1) return sqr(fib(m+1)) + sqr(fib(m));
  11. }
  12. EndMatch
  13. }

Lambda calculator demonstrates use of pattern matching to decompose objects and nested patterns:

  1. // Declare C++ equivalent of an Algebraic Data Type Term and its 3 variants:
  2. struct Term { virtual ~Term() {} };
  3. struct Var : Term { std::string name; };
  4. struct Abs : Term { Var& var; Term& body;};
  5. struct App : Term { Term& func; Term& arg; };
  6. // Tell Mach7 library which members should be bound in which binding positions
  7. namespace mch
  8. {
  9. template <> struct bindings<Var> { Members(Var::name); };
  10. template <> struct bindings<Abs> { Members(Abs::var , Abs::body); };
  11. template <> struct bindings<App> { Members(App::func, App::arg); };
  12. }
  13. // Implement fully-functional lambda-calculator
  14. Term* eval(Term* t)
  15. {
  16. var<const Var&> v;
  17. var<const Term&> b,a;
  18. Match(*t)
  19. {
  20. Case(C<Var>()) return &match0;
  21. Case(C<Abs>()) return &match0;
  22. Case(C<App>(C<Abs>(v,b),a)) return eval(subs(b,v,a));
  23. Otherwise() cerr << "error"; return nullptr ;
  24. }
  25. EndMatch
  26. }

It can also be used to demonstrate relational matching on several arguments:

  1. bool operator==(const Term& left, const Term& right)
  2. {
  3. var<std::string> s;
  4. var<const Term&> v,t,f;
  5. Match(left,right)
  6. {
  7. Case(C<Var>(s), C<Var>(+s) ) return true;
  8. Case(C<Abs>(&v,&t), C<Abs>(&+v,&+t)) return true;
  9. Case(C<App>(&f,&t), C<App>(&+f,&+t)) return true;
  10. Otherwise() return false;
  11. }
  12. EndMatch
  13. return false; // To prevent all control path warning
  14. }

Next example demonstrates that the library can deal efficiently and in a type-safe manner with non-polymorphic classes
like boost::variant as well.

  1. void print(const boost::variant<double,float,int>& v)
  2. {
  3. var<double> d; var<float> f; var<int> n;
  4. Match(v)
  5. {
  6. Case(C<double>(d)) cout << "double " << d << endl; break;
  7. Case(C<float> (f)) cout << "float " << f << endl; break;
  8. Case(C<int> (n)) cout << "int " << n << endl; break;
  9. }
  10. EndMatch
  11. }

Breve syntax is not the only thing Mach7 has to offer - the generated code is
faster than Visitors!

For a more detailed set of examples, have a look at the code that was prepared for
CppCon 2014 presentation,
and implemented using visitors as well as
pattern matching. These are simple enough
to help you get started on your own Mach7 project.

Continuous Integration

We use Travis CI and AppVeyor for continuous integration
and currently have all check-ins validated in the following configurations:

Build Status G++ Clang
Linux 4.9 3.4
OSX 4.9 3.5
Build Status: Visual C++ 2019 2017 2015 2013 2012 2010 /analyze
x86 Fail OK OK OK OK OK OK
x64 Fail OK OK OK OK N/A OK

Build Status: GitHub Actions

Branches

  • master - main development branch
  • release - cleaned-up branch with non-essential files deleted. FI from but does not RI back to master to avoid deletion of files there. Don’t do any actual editing in this branch.

Building sources

If you haven’t done so yet, get a copy of this Git
repo locally by executing:

  1. git clone https://github.com/solodon4/Mach7.git

The library itself is header only and does not require building. To build unit and
timing tests we’ve accumulated over time several scripts, which we don’t completely
abandon in favor of newer ones as they maintain the flags the original experiments
on the library were built with.

Using CMake (3.2 or later)

CMake support is the most recent and is still very experimental at this point. To
build with cmake, perform the following commands from within Mach7 folder:

  1. cmake -H. -Bbuild
  2. cmake --build build --target install

Note: this requires administrative privileges under all systems, if you don’t like this, try commands below:

  1. cmake -H. -Bbuild -DCMAKE_INSTALL_PREFIX=/wherever/doesn't/require/administrative/priviege
  2. cmake --build build --target install

But please make sure msvc/clang/gcc is able to find the path your provide above when
including Mach7’s headers in your own project:

Using Makefiles for GCC (4.4 or later) or Clang (3.3 or later)

Top-level Makefile synopsis:

  1. make - build all library tests
  2. make all - same as above right now
  3. make unit - build all unit tests
  4. make time - build all timing tests
  5. make cmpl - build all tests for timing the compilation times of the library
  6. make clean - clean all built targets and intermediaries
  7. make test - run all the built tests
  8. make check - run those tests for which there are correct_output/*.out files and check that the output is the same
  9. make doc - build Mach7 documentation (requires doxygen)
  10. make includes.png - build graph representation of header inclusions (requires graphviz dot)

To see a list of more specific targets supported by other makefiles, see comments inside them.

To build a particular file, say test/unit/example05.cpp, build a target with
the same filename and extension .exe instead of .cpp (even on Unix family OS).
For example:

  1. cd $MACH7_ROOT/code/test/unit
  2. make example05.exe

Lower-level makefiles support most of the phony targets of the top-level makefile,
to which the top-level makefile forwards the corresponding calls. For example:

To build and run just the unit tests:

  1. cd $MACH7_ROOT/code/test/unit
  2. make
  3. make check
  4. make test

Similarly, to build and run all the timing tests:

  1. cd $MACH7_ROOT/code/test/time
  2. make
  3. make test

Using Visual C++ (2010 or later)

Mach7 uses its own build.bat
script to build all the examples and unit tests that come with it. The script
assumes each .cpp file to be a standalone program. You can find
the most up-to-date list of supported commands
by running:

  1. build.bat /?
Syntax:
  1. build [ pgo | repro | tmp | <ver> ] [ filemask*.cpp ... ]
  2. build [ syntax | timing | cmp | doc | clean | test | check ]
Commands supported so far:
  1. build [ pgo | repro | tmp | <ver> | <arch> ] [ filemask*.cpp ... ] - build given C++ files
  2. build - Build all examples using the most recent MS Visual C++ compiler installed
  3. build unit - Build all unit tests
  4. build syntax - Build all supported library options combination for syntax variations
  5. build timing - Build all supported library options combination for timing variations
  6. build cmp - Build all executables for comparison with other languages
  7. build doc - Build Mach7 documentation
  8. build clean - Clean all built examples
  9. build test - Run all built examples
  10. build check - Run those examples for which there are correct_output/*.out files and
  11. check that output is the same
Modifiers:
  1. pgo - Perform Profile-Guided Optimization on produced executables
  2. repro - In case of error, create and compile a pre-processed repro
  3. tmp - Keep temporaries
  4. <ver> - Use a specific version of Visual Studio to compile the source
  5. code. <ver> can be one of the following:
  6. - 2019 - Visual C++ 16.0
  7. - 2017 - Visual C++ 15.0
  8. - 2015 - Visual C++ 14.0
  9. - 2013 - Visual C++ 12.0
  10. - 2012 - Visual C++ 11.0
  11. - 2010 - Visual C++ 10.0
  12. - 2008 - Visual C++ 9.0
  13. - 2005 - Visual C++ 8.0
  14. - 2003 - Visual C++ 7.1
  15. 0000 - Do not use any VS to set up the environment, I will set it up by myself
  16. <arch> - Target architecture. Can be one of the following: x86, x64, arm

Talks

Publications

Others about Mach7

Projects using Mach7

  • Yodl: a VHDL frontend for Yosys
  • Arrow: Arrow is a fast (as or faster than C) general-purpose programming language. It does not employ a garbage collector and has minimal runtime overhead.

License

Mach7 is licensed under the BSD License.

Support

If you have any question about Mach7 or have trouble using it, the best way to get answers is to post an
issue and label it as
Question. This will contribute to our
poor man’s FAQ and hopefully help others
with a similar question. I get notifications about new issues and usually respond within the
same day. If you prefer not to discuss your question on GitHub, feel free to send me a
mach7support@gmail.com">private email (note there is a
+ in the email address).

Call for Help

We are looking for contributors to the project. If you are a student taking a
programming languages class or any other class that would require you to write
a small compiler or interpreter, we would love you try Mach7 for the job. We
promise to help with any issues you might have with the library.

Known bugs and limitations

Right now, there are several experimental headers that one would need to include to enable one or the other syntax
to work. This is a work in progress, so before you start working with a particular syntax, check examples with that
syntax and make note of which of headers they include. We will clear this eventually leaving only one header, but at
the moment it is a mess, and the most intuitive match.hpp is probably not the header you want as it represents older
experiments. The most recent experimentation and the header you are probably looking for is
mach7/type_switchN-patterns-xtl.hpp.

The library is not yet suitable for multi-threaded environment. Lock-free version of vtbl-map is in the works.

Please refrain from using solution or project files checked in here. They are not in sync with most recent changes
to directory structure and are difficult to maintain. They will ultimately be replaced with a less verbose system
(likely CMake), and in the meantime please use build.bat to build tests on Windows.

For the most up-to-date list of known issues see Mach7 Issues.

Memory_1647813422262.pdf
OCamlComparison_1647813422265.pdf
VisitorsCompare_1647813422268.pdf
Yuriy_1647813422318.pdf
coverpage_1647813422348.pdf
obj-layout_1647813422367.pdf
v-table_1647813422384.pdf
obj-layout_1647813422437.pdf
v-table_1647813422466.pdf
sigplanconf-template_1647813422473.pdf
OpenPatternMatching-OOPSLA-1_1647813422599.pdf
OpenPatternMatching-OOPSLA_1647813422687.pdf
OpenPatternMatching_1647813422730.pdf
OpenPatternMatchingUpdated_1647813422821.pdf
PatternMatching_1647813422878.pdf
2013-10-25-GPCE-Open Pattern Matching for C++ Notes_1647813437886.pdf
2013-10-27-GPCE-Open Pattern Matching for C++_1647813438534.pdf
ClassHierarchies_1647813439631.pdf
OpenSourceReleaseNotification_1647813420369.pdf
PivotOpenSourceReleaseNotification_1647813420489.pdf
SAILOpenSourceReleaseNotification_1647813420501.pdf
ClassHierarchies_1647813420576.pdf
DCast-vs-Visitors_1647813420651.pdf
Inheritance_1647813420723.pdf
Memory_1647813420742.pdf
OCamlComparison_1647813420784.pdf
VisitorsCompare_1647813420829.pdf
mlpatmat-before_1647813420876.pdf
obj-layout_1647813421182.pdf
v-table_1647813421373.pdf
ClassHierarchies_1647813421394.pdf
DCast-vs-Visitors_1647813421414.pdf
Inheritance_1647813421434.pdf
Memory_1647813421487.pdf
OCamlComparison_1647813421512.pdf
pptypeswitch-peter_1647813421715.pdf
typeswitch-comments-gregory_1647813421878.pdf
typeswitch_comments_1647813421972.pdf
techreport_1647813422054.pdf
VisitorsCompare_1647813422113.pdf
coverpage_1647813422116.pdf
ClassHierarchies_1647813422177.pdf
DCast-vs-Visitors_1647813422228.pdf
Inheritance_1647813422245.pdf
2011-09-26-INRIA-C++ Pattern Matching Library_1647813423014.pptx
2012-09-18-OOPSLA-TypeSwitch_1647813423293.pptx
2012-09-24-OOPSLA-TypeSwitch_1647813423812.pptx
2012-09-28-OOPSLA-TypeSwitch_1647813424320.pptx
2012-09-29-OOPSLA-TypeSwitch_1647813424839.pptx
2012-10-07-OOPSLA-TypeSwitch_1647813425397.pptx
2012-10-08-OOPSLA-TypeSwitch_1647813426171.pptx
2012-10-09-OOPSLA-TypeSwitch_1647813427050.pptx
2012-10-10-OOPSLA-TypeSwitch_1647813427926.pptx
2012-10-12-Parasol-TypeSwitch_1647813428659.pptx
2012-10-25-OOPSLA-TypeSwitch-Actually-Presented_1647813429523.pptx
2012-10-25-OOPSLA-TypeSwitch_1647813430379.pptx
2013-04-12 National Instruments_1647813431252.pptx
2013-04-18 Bjarne's Class_1647813432107.pptx
2013-07-01 Coverity_1647813433218.pptx
2013-07-02 Coverity_1647813434245.pptx
2013-07-15 NVidia_1647813435232.pptx
2013-07-17 Intel_1647813436181.pptx
2013-07-18 Microsoft_1647813437235.pptx
2013-10-27-GPCE-Open Pattern Matching for C++_1647813438753.pptx
2014-05-14-C++ Now-The Design and Evolution of an Open Pattern Matching Library for C++_1647813439098.pptx
2014-09-12 CppCon_1647813439325.pptx
C++ Pattern Matching Library - INRIA_1647813439433.pptx
Rebuttal_1647813420416.docx
Rebuttal-OOPSLA-2012_1647813421541.docx
Rebuttal1_1647813421557.docx
Rebuttal2_1647813421594.docx
Type switch rebuttal_1647813421636.docx
PatternMatchingFix_1647813422968.docx
Mach7OpenSourceReleaseNotification_1647813418328.pdf
OpenPatternMatchingPoster_1647813418389.pdf
pos014-solodkyy-poster_1647813418447.pdf
pos014-solodkyy_1647813418537.pdf
OpenPatternMatching-Extended-Abstract_1647813418587.pdf
Timing-N-arg_1647813418612.pdf
Timing-N-arg_1647813418646.pdf
OpenPatternMatching_1647813418670.pdf
Timing-N-arg_1647813418709.pdf
Timing-N-arg_1647813418714.pdf
OpenPatternMatching_1647813418740.pdf
Timing-N-arg_1647813418835.pdf
Timing-N-arg_1647813418840.pdf
OpenPatternMatching-Poster_1647813418910.pdf
Timing-N-arg-All_1647813418952.pdf
Timing-N-arg-GCC-4.6.1_1647813419039.pdf
Timing-N-arg-GCC-4.7.2_1647813419091.pdf
Timing-N-arg_1647813419112.pdf