[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2\njobs:\n    build:\n        working_directory: ~/matlab2cpp\n        docker:\n            - image: circleci/python:2.7.14\n        steps:\n            - checkout\n            - restore_cache:\n                key: reqs-{{ checksum \"requirements.txt\" }}\n            - run:\n                name: \"Install Python requirements\"\n                command: |\n                    virtualenv venv\n                    . venv/bin/activate\n                    pip install -Ur requirements.txt\n                    pip install -e .\n            - save_cache:\n                key: reqs-{{ checksum \"requirements.txt\" }}\n                paths:\n                    - venv\n            - run:\n                name: \"Run tests\"\n                command: |\n                    . venv/bin/activate\n                    python setup.py test\n            - run:\n                name: \"Coverage report\"\n                command: |\n                    . venv/bin/activate\n                    codecov\n"
  },
  {
    "path": ".coveragerc",
    "content": "[run]\nbranch = True\nsource = codecov\n\n[report]\nexclude_lines =\n    coverage: ignore\n    def __repr__\n    raise NotImplementedError\n    if __name__ == .__main__.:\n\nignore_errors = True\nprecision = 2\nskip_covered = True\nomit =\n    doc/*\n    test/*\n    setup.py\n"
  },
  {
    "path": ".gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nenv/\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\n*.egg-info/\n.installed.cfg\n*.egg\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.coverage\n.cache\nnosetests.xml\ncoverage.xml\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2015, jonathf\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of matlab2cpp nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n"
  },
  {
    "path": "PKG-INFO",
    "content": "Metadata-Version: 1.0\nName: matlab2cpp\nVersion: 0.2\nSummary: A semi-automatic tool for converting Matlab to C++\nHome-page: http://www.github.org/jonathf/matlab2cpp\nAuthor: Jonathan Feinberg\nAuthor-email: jonathan@feinberg.no\nLicense: BSD\nDescription: UNKNOWN\nPlatform: Mac, Linux and Windows\n"
  },
  {
    "path": "README.rst",
    "content": ".. attention::\n\n    Matlab2cpp er currently unmaintained. As a mainteiner this project ended up\n    on the short end of the stick of what I unfortunatly have time for.\n\n    Anyone who want to make changes to it, might do so. I am very open to\n    a change in overship.\n\n    I am sorry for the inconvinience.\n\n    Jonathan\n\n==========\nMatlab2Cpp\n==========\n\n``matlab2cpp`` is a semi-automatic tool for converting code from Matlab to C++.\n\nAfter installing, the ``matlab2cpp`` command line executable ``m2cpp`` will be\navailable in path that can be used to convert Matlab code.\n\nNote that it is not meant as a complete tool for creating runnable C++ code.\nFor example, the `eval`-function can not be supported because there is no\ngeneral way to implement it in C++. Instead the program is a support tool,\nwhich aims at speed up the conversion process as much as possible for a user\nthat needs to convert Matlab programs by hand anyway. The software does this by\nconverting the basic structures of the Matlab-program (functions, branches,\nloops, etc.), adds variable declarations, and for some simple code, do\na complete translation. And any problem the program encounters during\nconversion will be written in a log-file. From there manual conversions can be\ndone by hand.\n\nCurrently, the code will not convert the large library collection of functions\nthat Matlab currently possesses. However, there is no reason for the code not\nto support these features in time. The extension library is easy to extend.\n\nInstallation\n------------\nInstallation by running the ``pip`` command::\n\n    pip install matlab2cpp\n\nThe source-to-source parser do not have any requirements beyond having Python\ninstalled. However, the generated output does have a few requirements to be\ncompilable. They are as follows.\n\n``C++11``\n    Code produces follows the ``C++11`` standard.\n``armadillo``\n    Armadillo is a linear algebra library for the C++ language. The Armadillo\n    library can be found at `http://arma.sourceforge.net`_. Some functionality\n    in Armadillo rely on a math library like LAPACK, BLAS, OpenBLAS or MKL.\n    When installing Armadillo, it will look for installed math libraries.\n\n    If Armadillo is installed, the library can be linked with the link flag\n    ``-l armadillo``. Armadillo can also be linked directly, see the ``FAQ`` at\n    the Armadillo webpage for more information.\n\n    I believe MKL is the fastest math library and it can be downloaded for free\n    at `https://software.intel.com/en-us/articles/free-mkl`_.\n``TBB``\n    By inserting pragmas in the code, for loops can be marked by the user. The\n    program can then either insert ``OpenMP`` or ``TBB`` code to parallelize\n    the for loop. To compile ``TBB`` code, the ``TBB`` library has to be\n    installed. See :ref:`parallel_flags` for more details.\n\nAn illustrating Example\n-----------------------\n\nAssuming Linux installation and `m2cpp` is available in path. Code works\nanalogous in Mac and Windows.\n\nConsider a file `example.m` with the following content::\n\n    function y=f(x)\n        y = x+4\n    end\n    function g()\n        x = [1,2,3]\n        f(x)\n    end\n\nRun conversion on the file: ::\n\n    $ m2cpp example.m\n\nThis will create two files: ``example.m.hpp`` and ``example.m.py``.\n\nIn ``example.m.hpp``, the translated C++ code is placed. It looks as follows::\n\n    #include <armadillo>\n    using namespace arma ;\n\n    TYPE f(TYPE x)\n    {\n      TYPE y ;\n      y = x+4 ;\n      return y ;\n    }\n\n    void g()\n    {\n      TYPE x ;\n      x = [1, 2, 3] ;\n      f(x) ;\n    }\n\nMatlab doesn't declare variables explicitly, so m2cpp is unable to complete\nthe translation.  To create a full conversion, the variables must be declared.\nDeclarations can be done in the file ``example.m.py``. After the first run, it\nwill look as follows::\n\n    # Supplement file\n    #\n    # Valid inputs:\n    #\n    # uint    int     float   double cx_double\n    # uvec    ivec    fvec    vec    cx_vec\n    # urowvec irowvec frowvec rowvec cx_rowvec\n    # umat    imat    fmat    mat    cx_mat\n    # ucube   icube   fcube   cube   cx_cube\n    #\n    # char    string  struct  structs func_lambda\n\n    functions = {\n      \"f\" : {\n        \"y\" : \"\",\n        \"x\" : \"\",\n      },\n      \"g\" : {\n        \"x\" : \"\",\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n\nIn addition to defining includes at the bottom, it is possible to declare\nvariables manually by inserting type names into the respective empty strings.\nHowever, some times it is possible to guess some of the variable types from\ncontext.  To let the software try to guess variable types, run conversion with\nthe ``-s`` flag::\n\n    $ m2cpp example.m -s\n\nThe file ``example.m.py`` will then automatically be populated with data types\nfrom context::\n\n    # ...\n\n    functions = {\n      \"f\" : {\n        \"y\" : \"irowvec\",\n        \"x\" : \"irowvec\",\n      },\n      \"g\" : {\n        \"x\" : \"irowvec\",\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n\nIt will not always be successful and some of the types might in some cases be\nwrong. It is therefore also possible to adjust these values manually at any\ntime.\n\nHaving run the conversion with the variables converted, creates a new output\nfor ``example.m.hpp``::\n\n    #include <armadillo>\n    using namespace arma ;\n\n    irowvec f(irowvec x)\n    {\n      irowvec y ;\n      y = x+4 ;\n      return y ;\n    }\n\n    void g()\n    {\n      irowvec x ;\n      int _x [] = [1, 2, 3] ;\n      x = irowvec(_x, 3, false) ;\n      f(x) ;\n    }\n\nThis is valid and runnable C++ code. For such a small example, no manual\nadjustments were necessary.\n"
  },
  {
    "path": "conftest.py",
    "content": "\"\"\"Global configuration.\"\"\"\nimport os\nimport inspect\nimport shutil\n\nimport pytest\nimport matlab2cpp\nfrom matlab2cpp import collection\n\n\n@pytest.fixture(scope=\"session\")\ndef workspace_folder(tmpdir_factory):\n    \"\"\"Create a temporary folder to perform tests from.\"\"\"\n    return str(tmpdir_factory.mktemp(\"workspace\"))\n\n\n@pytest.fixture(scope=\"function\", autouse=True)\ndef workspace(workspace_folder, doctest_namespace):\n    \"\"\"Fill temporary folder for each test.\"\"\"\n    # move data to workspace:\n    source = os.path.join(os.path.dirname(inspect.stack()[0][1]), \"test\", \"data\")\n    if os.path.isdir(workspace_folder):\n        shutil.rmtree(workspace_folder)\n    shutil.copytree(source, workspace_folder)\n\n    # add content to doctest namespace:\n    doctest_namespace[\"workspace\"] = workspace_folder\n    doctest_namespace[\"matlab2cpp\"] = matlab2cpp\n    doctest_namespace[\"collection\"] = collection\n\n    # change to workspace:\n    curdir = os.path.abspath(os.path.curdir)\n    os.chdir(workspace_folder)\n\n    yield workspace_folder\n\n    # clean up:\n    os.chdir(curdir)\n    shutil.rmtree(workspace_folder)\n"
  },
  {
    "path": "doc/previous_doc/Makefile",
    "content": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nPAPER         =\nBUILDDIR      = build\n\n# User-friendly check for sphinx-build\nifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)\n$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)\nendif\n\n# Internal variables.\nPAPEROPT_a4     = -D latex_paper_size=a4\nPAPEROPT_letter = -D latex_paper_size=letter\nALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source\n# the i18n builder cannot share the environment and doctrees with the others\nI18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source\n\n.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext\n\nhelp:\n\t@echo \"Please use \\`make <target>' where <target> is one of\"\n\t@echo \"  html       to make standalone HTML files\"\n\t@echo \"  dirhtml    to make HTML files named index.html in directories\"\n\t@echo \"  singlehtml to make a single large HTML file\"\n\t@echo \"  pickle     to make pickle files\"\n\t@echo \"  json       to make JSON files\"\n\t@echo \"  htmlhelp   to make HTML files and a HTML help project\"\n\t@echo \"  qthelp     to make HTML files and a qthelp project\"\n\t@echo \"  applehelp  to make an Apple Help Book\"\n\t@echo \"  devhelp    to make HTML files and a Devhelp project\"\n\t@echo \"  epub       to make an epub\"\n\t@echo \"  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\"\n\t@echo \"  latexpdf   to make LaTeX files and run them through pdflatex\"\n\t@echo \"  latexpdfja to make LaTeX files and run them through platex/dvipdfmx\"\n\t@echo \"  text       to make text files\"\n\t@echo \"  man        to make manual pages\"\n\t@echo \"  texinfo    to make Texinfo files\"\n\t@echo \"  info       to make Texinfo files and run them through makeinfo\"\n\t@echo \"  gettext    to make PO message catalogs\"\n\t@echo \"  changes    to make an overview of all changed/added/deprecated items\"\n\t@echo \"  xml        to make Docutils-native XML files\"\n\t@echo \"  pseudoxml  to make pseudoxml-XML files for display purposes\"\n\t@echo \"  linkcheck  to check all external links for integrity\"\n\t@echo \"  doctest    to run all doctests embedded in the documentation (if enabled)\"\n\t@echo \"  coverage   to run coverage check of the documentation (if enabled)\"\n\nclean:\n\trm -rf $(BUILDDIR)/*\n\nhtml:\n\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/html.\"\n\ndirhtml:\n\t$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/dirhtml.\"\n\nsinglehtml:\n\t$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml\n\t@echo\n\t@echo \"Build finished. The HTML page is in $(BUILDDIR)/singlehtml.\"\n\npickle:\n\t$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle\n\t@echo\n\t@echo \"Build finished; now you can process the pickle files.\"\n\njson:\n\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json\n\t@echo\n\t@echo \"Build finished; now you can process the JSON files.\"\n\nhtmlhelp:\n\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp\n\t@echo\n\t@echo \"Build finished; now you can run HTML Help Workshop with the\" \\\n\t      \".hhp project file in $(BUILDDIR)/htmlhelp.\"\n\nqthelp:\n\t$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp\n\t@echo\n\t@echo \"Build finished; now you can run \"qcollectiongenerator\" with the\" \\\n\t      \".qhcp project file in $(BUILDDIR)/qthelp, like this:\"\n\t@echo \"# qcollectiongenerator $(BUILDDIR)/qthelp/matlab2cpp.qhcp\"\n\t@echo \"To view the help file:\"\n\t@echo \"# assistant -collectionFile $(BUILDDIR)/qthelp/matlab2cpp.qhc\"\n\napplehelp:\n\t$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp\n\t@echo\n\t@echo \"Build finished. The help book is in $(BUILDDIR)/applehelp.\"\n\t@echo \"N.B. You won't be able to view it unless you put it in\" \\\n\t      \"~/Library/Documentation/Help or install it in your application\" \\\n\t      \"bundle.\"\n\ndevhelp:\n\t$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp\n\t@echo\n\t@echo \"Build finished.\"\n\t@echo \"To view the help file:\"\n\t@echo \"# mkdir -p $$HOME/.local/share/devhelp/matlab2cpp\"\n\t@echo \"# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/matlab2cpp\"\n\t@echo \"# devhelp\"\n\nepub:\n\t$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub\n\t@echo\n\t@echo \"Build finished. The epub file is in $(BUILDDIR)/epub.\"\n\nlatex:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo\n\t@echo \"Build finished; the LaTeX files are in $(BUILDDIR)/latex.\"\n\t@echo \"Run \\`make' in that directory to run these through (pdf)latex\" \\\n\t      \"(use \\`make latexpdf' here to do that automatically).\"\n\nlatexpdf:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through pdflatex...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\nlatexpdfja:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through platex and dvipdfmx...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\ntext:\n\t$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text\n\t@echo\n\t@echo \"Build finished. The text files are in $(BUILDDIR)/text.\"\n\nman:\n\t$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man\n\t@echo\n\t@echo \"Build finished. The manual pages are in $(BUILDDIR)/man.\"\n\ntexinfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo\n\t@echo \"Build finished. The Texinfo files are in $(BUILDDIR)/texinfo.\"\n\t@echo \"Run \\`make' in that directory to run these through makeinfo\" \\\n\t      \"(use \\`make info' here to do that automatically).\"\n\ninfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo \"Running Texinfo files through makeinfo...\"\n\tmake -C $(BUILDDIR)/texinfo info\n\t@echo \"makeinfo finished; the Info files are in $(BUILDDIR)/texinfo.\"\n\ngettext:\n\t$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale\n\t@echo\n\t@echo \"Build finished. The message catalogs are in $(BUILDDIR)/locale.\"\n\nchanges:\n\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes\n\t@echo\n\t@echo \"The overview file is in $(BUILDDIR)/changes.\"\n\nlinkcheck:\n\t$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck\n\t@echo\n\t@echo \"Link check complete; look for any errors in the above output \" \\\n\t      \"or in $(BUILDDIR)/linkcheck/output.txt.\"\n\ndoctest:\n\t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest\n\t@echo \"Testing of doctests in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/doctest/output.txt.\"\n\ncoverage:\n\t$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage\n\t@echo \"Testing of coverage in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/coverage/python.txt.\"\n\nxml:\n\t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml\n\t@echo\n\t@echo \"Build finished. The XML files are in $(BUILDDIR)/xml.\"\n\npseudoxml:\n\t$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml\n\t@echo\n\t@echo \"Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml.\"\n"
  },
  {
    "path": "doc/previous_doc/source/conf.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# matlab2cpp documentation build configuration file, created by\n# sphinx-quickstart on Mon Jun  8 10:41:13 2015.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\nimport sys\nimport os\nimport shlex\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\nsys.path.insert(0, os.path.abspath('../..'))\n\n# -- General configuration ------------------------------------------------\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\n\nextensions = [\"sphinx.ext.autodoc\", \"sphinx.ext.napoleon\",\n    \"sphinxcontrib.autoprogram\", \"sphinxarg.ext\"]\n\nnapoleon_google_docstring = True\nnapoleon_numpy_docstring = True\nnapoleon_include_private_with_doc = False\nnapoleon_include_special_with_doc = False\nnapoleon_use_admonition_for_examples = False\nnapoleon_use_admonition_for_notes = False\nnapoleon_use_admonition_for_references = False\nnapoleon_use_ivar = False\nnapoleon_use_param = True\nnapoleon_use_rtype = True\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n# source_suffix = ['.rst', '.md']\nsource_suffix = '.rst'\n\n# The encoding of source files.\n#source_encoding = 'utf-8-sig'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = u'matlab2cpp'\ncopyright = u'2015, Jonathan Feinberg'\nauthor = u'Jonathan Feinberg'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = '0.5'\n# The full version, including alpha/beta/rc tags.\nrelease = '0.5'\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = None\n\n# There are two options for replacing |today|: either, you set today to some\n# non-false value, then it is used:\n#today = ''\n# Else, today_fmt is used as the format for a strftime call.\n#today_fmt = '%B %d, %Y'\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\nexclude_patterns = []\n\n# The reST default role (used for this markup: `text`) to use for all\n# documents.\n#default_role = None\n\n# If true, '()' will be appended to :func: etc. cross-reference text.\n#add_function_parentheses = True\n\n# If true, the current module name will be prepended to all description\n# unit titles (such as .. function::).\n#add_module_names = True\n\n# If true, sectionauthor and moduleauthor directives will be shown in the\n# output. They are ignored by default.\n#show_authors = False\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# A list of ignored prefixes for module index sorting.\n#modindex_common_prefix = []\n\n# If true, keep warnings as \"system message\" paragraphs in the built documents.\n#keep_warnings = False\n\n# If true, `todo` and `todoList` produce output, else they produce nothing.\ntodo_include_todos = False\n\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\nhtml_theme = 'classic'\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#html_theme_options = {}\n\n# Add any paths that contain custom themes here, relative to this directory.\n#html_theme_path = []\n\n# The name for this set of Sphinx documents.  If None, it defaults to\n# \"<project> v<release> documentation\".\n#html_title = None\n\n# A shorter title for the navigation bar.  Default is the same as html_title.\n#html_short_title = None\n\n# The name of an image file (relative to this directory) to place at the top\n# of the sidebar.\n#html_logo = None\n\n# The name of an image file (within the static path) to use as favicon of the\n# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32\n# pixels large.\n#html_favicon = None\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['_static']\n\n# Add any extra paths that contain custom files (such as robots.txt or\n# .htaccess) here, relative to this directory. These files are copied\n# directly to the root of the documentation.\n#html_extra_path = []\n\n# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,\n# using the given strftime format.\n#html_last_updated_fmt = '%b %d, %Y'\n\n# If true, SmartyPants will be used to convert quotes and dashes to\n# typographically correct entities.\n#html_use_smartypants = True\n\n# Custom sidebar templates, maps document names to template names.\n#html_sidebars = {}\n\n# Additional templates that should be rendered to pages, maps page names to\n# template names.\n#html_additional_pages = {}\n\n# If false, no module index is generated.\n#html_domain_indices = True\n\n# If false, no index is generated.\n#html_use_index = True\n\n# If true, the index is split into individual pages for each letter.\nhtml_split_index = True\n\n# If true, links to the reST sources are added to the pages.\n#html_show_sourcelink = True\n\n# If true, \"Created using Sphinx\" is shown in the HTML footer. Default is True.\n#html_show_sphinx = True\n\n# If true, \"(C) Copyright ...\" is shown in the HTML footer. Default is True.\n#html_show_copyright = True\n\n# If true, an OpenSearch description file will be output, and all pages will\n# contain a <link> tag referring to it.  The value of this option must be the\n# base URL from which the finished HTML is served.\n#html_use_opensearch = ''\n\n# This is the file name suffix for HTML files (e.g. \".xhtml\").\n#html_file_suffix = None\n\n# Language to be used for generating the HTML full-text search index.\n# Sphinx supports the following languages:\n#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'\n#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'\n#html_search_language = 'en'\n\n# A dictionary with options for the search language support, empty by default.\n# Now only 'ja' uses this config value\n#html_search_options = {'type': 'default'}\n\n# The name of a javascript file (relative to the configuration directory) that\n# implements a search results scorer. If empty, the default will be used.\n#html_search_scorer = 'scorer.js'\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'matlab2cppdoc'\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n# The paper size ('letterpaper' or 'a4paper').\n#'papersize': 'letterpaper',\n\n# The font size ('10pt', '11pt' or '12pt').\n#'pointsize': '10pt',\n\n# Additional stuff for the LaTeX preamble.\n#'preamble': '',\n\n# Latex figure (float) alignment\n#'figure_align': 'htbp',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n  (master_doc, 'matlab2cpp.tex', u'matlab2cpp Documentation',\n   u'Jonathan Feinberg', 'manual'),\n]\n\n# The name of an image file (relative to this directory) to place at the top of\n# the title page.\n#latex_logo = None\n\n# For \"manual\" documents, if this is true, then toplevel headings are parts,\n# not chapters.\n#latex_use_parts = False\n\n# If true, show page references after internal links.\n#latex_show_pagerefs = False\n\n# If true, show URL addresses after external links.\n#latex_show_urls = False\n\n# Documents to append as an appendix to all manuals.\n#latex_appendices = []\n\n# If false, no module index is generated.\n#latex_domain_indices = True\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    (master_doc, 'matlab2cpp', u'matlab2cpp Documentation',\n     [author], 1)\n]\n\n# If true, show URL addresses after external links.\n#man_show_urls = False\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n  (master_doc, 'matlab2cpp', u'matlab2cpp Documentation',\n   author, 'matlab2cpp', 'One line description of project.',\n   'Miscellaneous'),\n]\n\n# Documents to append as an appendix to all manuals.\n#texinfo_appendices = []\n\n# If false, no module index is generated.\n#texinfo_domain_indices = True\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#texinfo_show_urls = 'footnote'\n\n# If true, do not generate a @detailmenu in the \"Top\" node's menu.\n#texinfo_no_detailmenu = False\n"
  },
  {
    "path": "doc/previous_doc/source/dev00_overview.rst",
    "content": ".. _dev00:\n\nModule overview\n===============\n\n.. automodule:: matlab2cpp\n\n\n"
  },
  {
    "path": "doc/previous_doc/source/dev01_qfuncs.rst",
    "content": ".. _dev01:\n\nQuick translation functions\n---------------------------\n\n.. automodule:: matlab2cpp.qfunctions\n\n.. autofunction:: matlab2cpp.build\n.. autofunction:: matlab2cpp.qcpp\n.. autofunction:: matlab2cpp.qhpp\n.. autofunction:: matlab2cpp.qpy\n.. autofunction:: matlab2cpp.qlog\n.. autofunction:: matlab2cpp.qscript\n.. autofunction:: matlab2cpp.qtree\n"
  },
  {
    "path": "doc/previous_doc/source/dev02_tree.rst",
    "content": ".. _dev02:\n\nThe tree constructor\n====================\n\n.. automodule:: matlab2cpp.tree\n\nThe Builder class\n-----------------\n.. autoclass:: matlab2cpp.Builder\n    :members:\n    :special-members:\n\nAssignment constructors\n-----------------------\n.. automodule:: matlab2cpp.tree.assign\n    :members:\n\nLoop and branch constructors\n----------------------------\n.. automodule:: matlab2cpp.tree.branches\n    :members:\n\nCode block constructor\n----------------------\n.. automodule:: matlab2cpp.tree.codeblock\n    :members:\n\nExpression constructor\n----------------------\n.. automodule:: matlab2cpp.tree.expression\n    :members:\n\nFunction constructors\n---------------------\n.. automodule:: matlab2cpp.tree.functions\n    :members:\n\nMiscelenious constructors\n-------------------------\n.. automodule:: matlab2cpp.tree.misc\n    :members:\n\nVariable constructors\n---------------------\n.. automodule:: matlab2cpp.tree.variables\n    :members:\n\nFind-end functions\n------------------\n.. automodule:: matlab2cpp.tree.findend\n    :members:\n\nIterators\n---------\n.. automodule:: matlab2cpp.tree.iterate\n    :members:\n\nIdentify structures\n-------------------\n.. automodule:: matlab2cpp.tree.identify\n    :members:\n\nMatlab constants\n----------------\n.. automodule:: matlab2cpp.tree.constants\n    :members:\n"
  },
  {
    "path": "doc/previous_doc/source/dev03_node.rst",
    "content": ".. _dev03:\n\nNode representation\n===================\n.. automodule:: matlab2cpp.node\n\nThe Node class\n--------------\n.. autoclass:: matlab2cpp.Node\n   :members: \n\nNode backend\n------------\n.. automodule:: matlab2cpp.node.backend\n\nQuick references\n----------------\n.. automodule:: matlab2cpp.node.reference\n"
  },
  {
    "path": "doc/previous_doc/source/dev04_datatype.rst",
    "content": ".. _dev04:\nDatatypes\n=========\n\n.. automodule:: matlab2cpp.datatype\n\n"
  },
  {
    "path": "doc/previous_doc/source/dev05_configure.rst",
    "content": ".. _dev05:\n\nAuto-configure datatype\n=======================\n.. automodule:: matlab2cpp.configure\n"
  },
  {
    "path": "doc/previous_doc/source/dev06_collection.rst",
    "content": ".. _dev06:\n\nCollection\n==========\n.. automodule:: matlab2cpp.collection\n\n.. autoclass:: matlab2cpp.collection.All\n.. autoclass:: matlab2cpp.collection.Assign\n.. autoclass:: matlab2cpp.collection.Assigns\n.. autoclass:: matlab2cpp.collection.Band\n.. autoclass:: matlab2cpp.collection.Bcomment\n.. autoclass:: matlab2cpp.collection.Block\n.. autoclass:: matlab2cpp.collection.Bor\n.. autoclass:: matlab2cpp.collection.Branch\n.. autoclass:: matlab2cpp.collection.Break\n.. autoclass:: matlab2cpp.collection.Case\n.. autoclass:: matlab2cpp.collection.Catch\n.. autoclass:: matlab2cpp.collection.Cell\n.. autoclass:: matlab2cpp.collection.Cget\n.. autoclass:: matlab2cpp.collection.Colon\n.. autoclass:: matlab2cpp.collection.Counter\n.. autoclass:: matlab2cpp.collection.Cset\n.. autoclass:: matlab2cpp.collection.Ctranspose\n.. autoclass:: matlab2cpp.collection.Cvar\n.. autoclass:: matlab2cpp.collection.Declares\n.. autoclass:: matlab2cpp.collection.Ecomment\n.. autoclass:: matlab2cpp.collection.Elementdivision\n.. autoclass:: matlab2cpp.collection.Elexp\n.. autoclass:: matlab2cpp.collection.Elif\n.. autoclass:: matlab2cpp.collection.Elmul\n.. autoclass:: matlab2cpp.collection.Else\n.. autoclass:: matlab2cpp.collection.End\n.. autoclass:: matlab2cpp.collection.Eq\n.. autoclass:: matlab2cpp.collection.Error\n.. autoclass:: matlab2cpp.collection.Exp\n.. autoclass:: matlab2cpp.collection.Expr\n.. autoclass:: matlab2cpp.collection.Fget\n.. autoclass:: matlab2cpp.collection.Float\n.. autoclass:: matlab2cpp.collection.For\n.. autoclass:: matlab2cpp.collection.Fset\n.. autoclass:: matlab2cpp.collection.Func\n.. autoclass:: matlab2cpp.collection.Funcs\n.. autoclass:: matlab2cpp.collection.Fvar\n.. autoclass:: matlab2cpp.collection.Ge\n.. autoclass:: matlab2cpp.collection.Get\n.. autoclass:: matlab2cpp.collection.Gt\n.. autoclass:: matlab2cpp.collection.Header\n.. autoclass:: matlab2cpp.collection.Headers\n.. autoclass:: matlab2cpp.collection.If\n.. autoclass:: matlab2cpp.collection.Imag\n.. autoclass:: matlab2cpp.collection.Include\n.. autoclass:: matlab2cpp.collection.Includes\n.. autoclass:: matlab2cpp.collection.Inline\n.. autoclass:: matlab2cpp.collection.Inlines\n.. autoclass:: matlab2cpp.collection.Int\n.. autoclass:: matlab2cpp.collection.Lambda\n.. autoclass:: matlab2cpp.collection.Land\n.. autoclass:: matlab2cpp.collection.Lcomment\n.. autoclass:: matlab2cpp.collection.Le\n.. autoclass:: matlab2cpp.collection.Leftelementdivision\n.. autoclass:: matlab2cpp.collection.Leftmatrixdivision\n.. autoclass:: matlab2cpp.collection.Log\n.. autoclass:: matlab2cpp.collection.Lor\n.. autoclass:: matlab2cpp.collection.Lt\n.. autoclass:: matlab2cpp.collection.Main\n.. autoclass:: matlab2cpp.collection.Matrix\n.. autoclass:: matlab2cpp.collection.Matrixdivision\n.. autoclass:: matlab2cpp.collection.Minus\n.. autoclass:: matlab2cpp.collection.Mul\n.. autoclass:: matlab2cpp.collection.Ne\n.. autoclass:: matlab2cpp.collection.Neg\n.. autoclass:: matlab2cpp.collection.Nget\n.. autoclass:: matlab2cpp.collection.Not\n.. autoclass:: matlab2cpp.collection.Nset\n.. autoclass:: matlab2cpp.collection.Opr\n.. autoclass:: matlab2cpp.collection.Otherwise\n.. autoclass:: matlab2cpp.collection.Params\n.. autoclass:: matlab2cpp.collection.Paren\n.. autoclass:: matlab2cpp.collection.Plus\n.. autoclass:: matlab2cpp.collection.Program\n.. autoclass:: matlab2cpp.collection.Project\n.. autoclass:: matlab2cpp.collection.Resize\n.. autoclass:: matlab2cpp.collection.Return\n.. autoclass:: matlab2cpp.collection.Returns\n.. autoclass:: matlab2cpp.collection.Set\n.. autoclass:: matlab2cpp.collection.Sget\n.. autoclass:: matlab2cpp.collection.Sset\n.. autoclass:: matlab2cpp.collection.Statement\n.. autoclass:: matlab2cpp.collection.String\n.. autoclass:: matlab2cpp.collection.Struct\n.. autoclass:: matlab2cpp.collection.Structs\n.. autoclass:: matlab2cpp.collection.Switch\n.. autoclass:: matlab2cpp.collection.Transpose\n.. autoclass:: matlab2cpp.collection.Try\n.. autoclass:: matlab2cpp.collection.Tryblock\n.. autoclass:: matlab2cpp.collection.Var\n.. autoclass:: matlab2cpp.collection.Vector\n.. autoclass:: matlab2cpp.collection.Warning\n.. autoclass:: matlab2cpp.collection.While\n"
  },
  {
    "path": "doc/previous_doc/source/dev07_rules.rst",
    "content": ".. _dev07:\n\nTranslation rules\n=================\n\n.. automodule:: matlab2cpp.rules\n\nDatatype driven rules\n---------------------\n\n.. automodule:: matlab2cpp.rules._cell\n.. automodule:: matlab2cpp.rules._char\n.. automodule:: matlab2cpp.rules._cube\n.. automodule:: matlab2cpp.rules._cx_cube\n.. automodule:: matlab2cpp.rules._cx_double\n.. automodule:: matlab2cpp.rules._cx_mat\n.. automodule:: matlab2cpp.rules._cx_rowvec\n.. automodule:: matlab2cpp.rules._cx_vec\n.. automodule:: matlab2cpp.rules._double\n.. automodule:: matlab2cpp.rules._fcube\n.. automodule:: matlab2cpp.rules._float\n.. automodule:: matlab2cpp.rules._fmat\n.. automodule:: matlab2cpp.rules._frowvec\n.. automodule:: matlab2cpp.rules._fvec\n.. automodule:: matlab2cpp.rules._icube\n.. automodule:: matlab2cpp.rules._imat\n.. automodule:: matlab2cpp.rules._int\n.. automodule:: matlab2cpp.rules._irowvec\n.. automodule:: matlab2cpp.rules._ivec\n.. automodule:: matlab2cpp.rules._mat\n.. automodule:: matlab2cpp.rules._rowvec\n.. automodule:: matlab2cpp.rules._string\n.. automodule:: matlab2cpp.rules._struct\n.. automodule:: matlab2cpp.rules._structs\n.. automodule:: matlab2cpp.rules._ucube\n.. automodule:: matlab2cpp.rules._umat\n.. automodule:: matlab2cpp.rules._urowvec\n.. automodule:: matlab2cpp.rules._uvec\n.. automodule:: matlab2cpp.rules._uword\n.. automodule:: matlab2cpp.rules._vec\n\nOther rules\n-----------\n\n.. automodule:: matlab2cpp.rules._code_block\n.. automodule:: matlab2cpp.rules._expression\n.. automodule:: matlab2cpp.rules._func_lambda\n.. automodule:: matlab2cpp.rules._func_return\n.. automodule:: matlab2cpp.rules._func_returns\n.. automodule:: matlab2cpp.rules._matrix\n.. automodule:: matlab2cpp.rules._program\n.. automodule:: matlab2cpp.rules._reserved\n.. automodule:: matlab2cpp.rules._unknown\n.. automodule:: matlab2cpp.rules._verbatim\n"
  },
  {
    "path": "doc/previous_doc/source/dev08_supplement.rst",
    "content": ".. _dev08:\n\nDatatype scope\n==============\n.. automodule:: matlab2cpp.supplement\n\nInput/Output classes\n--------------------\n.. autoclass:: matlab2cpp.supplement.Ftypes\n.. autoclass:: matlab2cpp.supplement.Stypes\n.. autoclass:: matlab2cpp.supplement.Itypes\n.. autoclass:: matlab2cpp.supplement.Vtypes\n\nStringify supplement file\n-------------------------\n.. autofunction:: matlab2cpp.supplement.str_variables\n"
  },
  {
    "path": "doc/previous_doc/source/dev09_testsuite.rst",
    "content": ".. _dev09:\n\nTestsuite\n=========\n.. automodule:: matlab2cpp.testsuite\n"
  },
  {
    "path": "doc/previous_doc/source/index.rst",
    "content": "Matlab2cpp Manual\n=================\n\n===========\nUser Manual\n===========\n\n.. toctree::\n    :maxdepth: 3\n\n    usr00_intro\n    usr01_interaction\n    usr02_datatype\n    usr03_rules\n    usr04_node\n\n================\nDeveloper Manual\n================\n\n.. toctree::\n    :maxdepth: 3\n\n    dev00_overview\n    dev01_qfuncs\n    dev02_tree\n    dev03_node\n    dev04_datatype\n    dev05_configure\n    dev06_collection\n    dev07_rules\n    dev08_supplement\n    dev09_testsuite\n"
  },
  {
    "path": "doc/previous_doc/source/usr00_intro.rst",
    "content": ".. _usr00:\n\nIntroduction\n============\n.. include:: ../../README.md\n"
  },
  {
    "path": "doc/previous_doc/source/usr01_interaction.rst",
    "content": ".. automodule:: matlab2cpp.manual.usr01_interaction\n"
  },
  {
    "path": "doc/previous_doc/source/usr02_datatype.rst",
    "content": ".. automodule:: matlab2cpp.manual.usr02_datatype\n"
  },
  {
    "path": "doc/previous_doc/source/usr03_rules.rst",
    "content": ".. automodule:: matlab2cpp.manual.usr03_rules\n"
  },
  {
    "path": "doc/previous_doc/source/usr04_node.rst",
    "content": ".. automodule:: matlab2cpp.manual.usr04_node\n"
  },
  {
    "path": "doc/user_manual/Makefile",
    "content": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nPAPER         =\nBUILDDIR      = build\n\n# User-friendly check for sphinx-build\nifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)\n$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)\nendif\n\n# Internal variables.\nPAPEROPT_a4     = -D latex_paper_size=a4\nPAPEROPT_letter = -D latex_paper_size=letter\nALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source\n# the i18n builder cannot share the environment and doctrees with the others\nI18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source\n\n.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext\n\nhelp:\n\t@echo \"Please use \\`make <target>' where <target> is one of\"\n\t@echo \"  html       to make standalone HTML files\"\n\t@echo \"  dirhtml    to make HTML files named index.html in directories\"\n\t@echo \"  singlehtml to make a single large HTML file\"\n\t@echo \"  pickle     to make pickle files\"\n\t@echo \"  json       to make JSON files\"\n\t@echo \"  htmlhelp   to make HTML files and a HTML help project\"\n\t@echo \"  qthelp     to make HTML files and a qthelp project\"\n\t@echo \"  applehelp  to make an Apple Help Book\"\n\t@echo \"  devhelp    to make HTML files and a Devhelp project\"\n\t@echo \"  epub       to make an epub\"\n\t@echo \"  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\"\n\t@echo \"  latexpdf   to make LaTeX files and run them through pdflatex\"\n\t@echo \"  latexpdfja to make LaTeX files and run them through platex/dvipdfmx\"\n\t@echo \"  text       to make text files\"\n\t@echo \"  man        to make manual pages\"\n\t@echo \"  texinfo    to make Texinfo files\"\n\t@echo \"  info       to make Texinfo files and run them through makeinfo\"\n\t@echo \"  gettext    to make PO message catalogs\"\n\t@echo \"  changes    to make an overview of all changed/added/deprecated items\"\n\t@echo \"  xml        to make Docutils-native XML files\"\n\t@echo \"  pseudoxml  to make pseudoxml-XML files for display purposes\"\n\t@echo \"  linkcheck  to check all external links for integrity\"\n\t@echo \"  doctest    to run all doctests embedded in the documentation (if enabled)\"\n\t@echo \"  coverage   to run coverage check of the documentation (if enabled)\"\n\nclean:\n\trm -rf $(BUILDDIR)/*\n\nhtml:\n\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/html.\"\n\ndirhtml:\n\t$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/dirhtml.\"\n\nsinglehtml:\n\t$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml\n\t@echo\n\t@echo \"Build finished. The HTML page is in $(BUILDDIR)/singlehtml.\"\n\npickle:\n\t$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle\n\t@echo\n\t@echo \"Build finished; now you can process the pickle files.\"\n\njson:\n\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json\n\t@echo\n\t@echo \"Build finished; now you can process the JSON files.\"\n\nhtmlhelp:\n\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp\n\t@echo\n\t@echo \"Build finished; now you can run HTML Help Workshop with the\" \\\n\t      \".hhp project file in $(BUILDDIR)/htmlhelp.\"\n\nqthelp:\n\t$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp\n\t@echo\n\t@echo \"Build finished; now you can run \"qcollectiongenerator\" with the\" \\\n\t      \".qhcp project file in $(BUILDDIR)/qthelp, like this:\"\n\t@echo \"# qcollectiongenerator $(BUILDDIR)/qthelp/matlab2cpp.qhcp\"\n\t@echo \"To view the help file:\"\n\t@echo \"# assistant -collectionFile $(BUILDDIR)/qthelp/matlab2cpp.qhc\"\n\napplehelp:\n\t$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp\n\t@echo\n\t@echo \"Build finished. The help book is in $(BUILDDIR)/applehelp.\"\n\t@echo \"N.B. You won't be able to view it unless you put it in\" \\\n\t      \"~/Library/Documentation/Help or install it in your application\" \\\n\t      \"bundle.\"\n\ndevhelp:\n\t$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp\n\t@echo\n\t@echo \"Build finished.\"\n\t@echo \"To view the help file:\"\n\t@echo \"# mkdir -p $$HOME/.local/share/devhelp/matlab2cpp\"\n\t@echo \"# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/matlab2cpp\"\n\t@echo \"# devhelp\"\n\nepub:\n\t$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub\n\t@echo\n\t@echo \"Build finished. The epub file is in $(BUILDDIR)/epub.\"\n\nlatex:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo\n\t@echo \"Build finished; the LaTeX files are in $(BUILDDIR)/latex.\"\n\t@echo \"Run \\`make' in that directory to run these through (pdf)latex\" \\\n\t      \"(use \\`make latexpdf' here to do that automatically).\"\n\nlatexpdf:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through pdflatex...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\nlatexpdfja:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through platex and dvipdfmx...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\ntext:\n\t$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text\n\t@echo\n\t@echo \"Build finished. The text files are in $(BUILDDIR)/text.\"\n\nman:\n\t$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man\n\t@echo\n\t@echo \"Build finished. The manual pages are in $(BUILDDIR)/man.\"\n\ntexinfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo\n\t@echo \"Build finished. The Texinfo files are in $(BUILDDIR)/texinfo.\"\n\t@echo \"Run \\`make' in that directory to run these through makeinfo\" \\\n\t      \"(use \\`make info' here to do that automatically).\"\n\ninfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo \"Running Texinfo files through makeinfo...\"\n\tmake -C $(BUILDDIR)/texinfo info\n\t@echo \"makeinfo finished; the Info files are in $(BUILDDIR)/texinfo.\"\n\ngettext:\n\t$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale\n\t@echo\n\t@echo \"Build finished. The message catalogs are in $(BUILDDIR)/locale.\"\n\nchanges:\n\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes\n\t@echo\n\t@echo \"The overview file is in $(BUILDDIR)/changes.\"\n\nlinkcheck:\n\t$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck\n\t@echo\n\t@echo \"Link check complete; look for any errors in the above output \" \\\n\t      \"or in $(BUILDDIR)/linkcheck/output.txt.\"\n\ndoctest:\n\t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest\n\t@echo \"Testing of doctests in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/doctest/output.txt.\"\n\ncoverage:\n\t$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage\n\t@echo \"Testing of coverage in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/coverage/python.txt.\"\n\nxml:\n\t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml\n\t@echo\n\t@echo \"Build finished. The XML files are in $(BUILDDIR)/xml.\"\n\npseudoxml:\n\t$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml\n\t@echo\n\t@echo \"Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml.\"\n"
  },
  {
    "path": "doc/user_manual/source/conf.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# matlab2cpp documentation build configuration file, created by\n# sphinx-quickstart on Mon Jun  8 10:41:13 2015.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\nimport sys\nimport os\nimport shlex\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\nsys.path.insert(0, os.path.abspath('../../..'))\n\n# -- General configuration ------------------------------------------------\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\n\nextensions = [\"sphinx.ext.autodoc\", \"sphinx.ext.napoleon\",\n    \"sphinxcontrib.autoprogram\", \"sphinxarg.ext\"]\n\nnapoleon_google_docstring = True\nnapoleon_numpy_docstring = True\nnapoleon_include_private_with_doc = False\nnapoleon_include_special_with_doc = False\nnapoleon_use_admonition_for_examples = False\nnapoleon_use_admonition_for_notes = False\nnapoleon_use_admonition_for_references = False\nnapoleon_use_ivar = False\nnapoleon_use_param = True\nnapoleon_use_rtype = True\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n# source_suffix = ['.rst', '.md']\nsource_suffix = '.rst'\n\n# The encoding of source files.\n#source_encoding = 'utf-8-sig'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = u'matlab2cpp'\ncopyright = u'2015, Jonathan Feinberg'\nauthor = u'Jonathan Feinberg'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = '0.5'\n# The full version, including alpha/beta/rc tags.\nrelease = '0.5'\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = None\n\n# There are two options for replacing |today|: either, you set today to some\n# non-false value, then it is used:\n#today = ''\n# Else, today_fmt is used as the format for a strftime call.\n#today_fmt = '%B %d, %Y'\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\nexclude_patterns = []\n\n# The reST default role (used for this markup: `text`) to use for all\n# documents.\n#default_role = None\n\n# If true, '()' will be appended to :func: etc. cross-reference text.\n#add_function_parentheses = True\n\n# If true, the current module name will be prepended to all description\n# unit titles (such as .. function::).\n#add_module_names = True\n\n# If true, sectionauthor and moduleauthor directives will be shown in the\n# output. They are ignored by default.\n#show_authors = False\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# A list of ignored prefixes for module index sorting.\n#modindex_common_prefix = []\n\n# If true, keep warnings as \"system message\" paragraphs in the built documents.\n#keep_warnings = False\n\n# If true, `todo` and `todoList` produce output, else they produce nothing.\ntodo_include_todos = False\n\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\nhtml_theme = 'classic'\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#html_theme_options = {}\n\n# Add any paths that contain custom themes here, relative to this directory.\n#html_theme_path = []\n\n# The name for this set of Sphinx documents.  If None, it defaults to\n# \"<project> v<release> documentation\".\n#html_title = None\n\n# A shorter title for the navigation bar.  Default is the same as html_title.\n#html_short_title = None\n\n# The name of an image file (relative to this directory) to place at the top\n# of the sidebar.\n#html_logo = None\n\n# The name of an image file (within the static path) to use as favicon of the\n# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32\n# pixels large.\n#html_favicon = None\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['_static']\n\n# Add any extra paths that contain custom files (such as robots.txt or\n# .htaccess) here, relative to this directory. These files are copied\n# directly to the root of the documentation.\n#html_extra_path = []\n\n# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,\n# using the given strftime format.\n#html_last_updated_fmt = '%b %d, %Y'\n\n# If true, SmartyPants will be used to convert quotes and dashes to\n# typographically correct entities.\n#html_use_smartypants = True\n\n# Custom sidebar templates, maps document names to template names.\n#html_sidebars = {}\n\n# Additional templates that should be rendered to pages, maps page names to\n# template names.\n#html_additional_pages = {}\n\n# If false, no module index is generated.\n#html_domain_indices = True\n\n# If false, no index is generated.\n#html_use_index = True\n\n# If true, the index is split into individual pages for each letter.\nhtml_split_index = True\n\n# If true, links to the reST sources are added to the pages.\n#html_show_sourcelink = True\n\n# If true, \"Created using Sphinx\" is shown in the HTML footer. Default is True.\n#html_show_sphinx = True\n\n# If true, \"(C) Copyright ...\" is shown in the HTML footer. Default is True.\n#html_show_copyright = True\n\n# If true, an OpenSearch description file will be output, and all pages will\n# contain a <link> tag referring to it.  The value of this option must be the\n# base URL from which the finished HTML is served.\n#html_use_opensearch = ''\n\n# This is the file name suffix for HTML files (e.g. \".xhtml\").\n#html_file_suffix = None\n\n# Language to be used for generating the HTML full-text search index.\n# Sphinx supports the following languages:\n#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'\n#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'\n#html_search_language = 'en'\n\n# A dictionary with options for the search language support, empty by default.\n# Now only 'ja' uses this config value\n#html_search_options = {'type': 'default'}\n\n# The name of a javascript file (relative to the configuration directory) that\n# implements a search results scorer. If empty, the default will be used.\n#html_search_scorer = 'scorer.js'\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'matlab2cppdoc'\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n# The paper size ('letterpaper' or 'a4paper').\n#'papersize': 'letterpaper',\n\n# The font size ('10pt', '11pt' or '12pt').\n#'pointsize': '10pt',\n\n# Additional stuff for the LaTeX preamble.\n#'preamble': '',\n\n# Latex figure (float) alignment\n#'figure_align': 'htbp',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n  (master_doc, 'matlab2cpp.tex', u'matlab2cpp User Documentation',\n   u'Jonathan Feinberg', 'manual'),\n]\n\n# The name of an image file (relative to this directory) to place at the top of\n# the title page.\n#latex_logo = None\n\n# For \"manual\" documents, if this is true, then toplevel headings are parts,\n# not chapters.\n#latex_use_parts = False\n\n# If true, show page references after internal links.\n#latex_show_pagerefs = False\n\n# If true, show URL addresses after external links.\n#latex_show_urls = False\n\n# Documents to append as an appendix to all manuals.\n#latex_appendices = []\n\n# If false, no module index is generated.\n#latex_domain_indices = True\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    (master_doc, 'matlab2cpp', u'matlab2cpp Documentation',\n     [author], 1)\n]\n\n# If true, show URL addresses after external links.\n#man_show_urls = False\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n  (master_doc, 'matlab2cpp', u'matlab2cpp Documentation',\n   author, 'matlab2cpp', 'One line description of project.',\n   'Miscellaneous'),\n]\n\n# Documents to append as an appendix to all manuals.\n#texinfo_appendices = []\n\n# If false, no module index is generated.\n#texinfo_domain_indices = True\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#texinfo_show_urls = 'footnote'\n\n# If true, do not generate a @detailmenu in the \"Top\" node's menu.\n#texinfo_no_detailmenu = False\n"
  },
  {
    "path": "doc/user_manual/source/conf.py~",
    "content": "# -*- coding: utf-8 -*-\n#\n# matlab2cpp documentation build configuration file, created by\n# sphinx-quickstart on Mon Jun  8 10:41:13 2015.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\nimport sys\nimport os\nimport shlex\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\nsys.path.insert(0, os.path.abspath('../../..'))\n\n# -- General configuration ------------------------------------------------\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\n\nextensions = [\"sphinx.ext.autodoc\", \"sphinx.ext.napoleon\",\n    \"sphinxcontrib.autoprogram\", \"sphinxarg.ext\"]\n\nnapoleon_google_docstring = True\nnapoleon_numpy_docstring = True\nnapoleon_include_private_with_doc = False\nnapoleon_include_special_with_doc = False\nnapoleon_use_admonition_for_examples = False\nnapoleon_use_admonition_for_notes = False\nnapoleon_use_admonition_for_references = False\nnapoleon_use_ivar = False\nnapoleon_use_param = True\nnapoleon_use_rtype = True\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n# source_suffix = ['.rst', '.md']\nsource_suffix = '.rst'\n\n# The encoding of source files.\n#source_encoding = 'utf-8-sig'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = u'matlab2cpp'\ncopyright = u'2015, Jonathan Feinberg'\nauthor = u'Jonathan Feinberg'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = '0.5'\n# The full version, including alpha/beta/rc tags.\nrelease = '0.5'\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = None\n\n# There are two options for replacing |today|: either, you set today to some\n# non-false value, then it is used:\n#today = ''\n# Else, today_fmt is used as the format for a strftime call.\n#today_fmt = '%B %d, %Y'\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\nexclude_patterns = []\n\n# The reST default role (used for this markup: `text`) to use for all\n# documents.\n#default_role = None\n\n# If true, '()' will be appended to :func: etc. cross-reference text.\n#add_function_parentheses = True\n\n# If true, the current module name will be prepended to all description\n# unit titles (such as .. function::).\n#add_module_names = True\n\n# If true, sectionauthor and moduleauthor directives will be shown in the\n# output. They are ignored by default.\n#show_authors = False\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# A list of ignored prefixes for module index sorting.\n#modindex_common_prefix = []\n\n# If true, keep warnings as \"system message\" paragraphs in the built documents.\n#keep_warnings = False\n\n# If true, `todo` and `todoList` produce output, else they produce nothing.\ntodo_include_todos = False\n\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\nhtml_theme = 'classic'\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#html_theme_options = {}\n\n# Add any paths that contain custom themes here, relative to this directory.\n#html_theme_path = []\n\n# The name for this set of Sphinx documents.  If None, it defaults to\n# \"<project> v<release> documentation\".\n#html_title = None\n\n# A shorter title for the navigation bar.  Default is the same as html_title.\n#html_short_title = None\n\n# The name of an image file (relative to this directory) to place at the top\n# of the sidebar.\n#html_logo = None\n\n# The name of an image file (within the static path) to use as favicon of the\n# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32\n# pixels large.\n#html_favicon = None\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['_static']\n\n# Add any extra paths that contain custom files (such as robots.txt or\n# .htaccess) here, relative to this directory. These files are copied\n# directly to the root of the documentation.\n#html_extra_path = []\n\n# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,\n# using the given strftime format.\n#html_last_updated_fmt = '%b %d, %Y'\n\n# If true, SmartyPants will be used to convert quotes and dashes to\n# typographically correct entities.\n#html_use_smartypants = True\n\n# Custom sidebar templates, maps document names to template names.\n#html_sidebars = {}\n\n# Additional templates that should be rendered to pages, maps page names to\n# template names.\n#html_additional_pages = {}\n\n# If false, no module index is generated.\n#html_domain_indices = True\n\n# If false, no index is generated.\n#html_use_index = True\n\n# If true, the index is split into individual pages for each letter.\nhtml_split_index = True\n\n# If true, links to the reST sources are added to the pages.\n#html_show_sourcelink = True\n\n# If true, \"Created using Sphinx\" is shown in the HTML footer. Default is True.\n#html_show_sphinx = True\n\n# If true, \"(C) Copyright ...\" is shown in the HTML footer. Default is True.\n#html_show_copyright = True\n\n# If true, an OpenSearch description file will be output, and all pages will\n# contain a <link> tag referring to it.  The value of this option must be the\n# base URL from which the finished HTML is served.\n#html_use_opensearch = ''\n\n# This is the file name suffix for HTML files (e.g. \".xhtml\").\n#html_file_suffix = None\n\n# Language to be used for generating the HTML full-text search index.\n# Sphinx supports the following languages:\n#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'\n#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'\n#html_search_language = 'en'\n\n# A dictionary with options for the search language support, empty by default.\n# Now only 'ja' uses this config value\n#html_search_options = {'type': 'default'}\n\n# The name of a javascript file (relative to the configuration directory) that\n# implements a search results scorer. If empty, the default will be used.\n#html_search_scorer = 'scorer.js'\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'matlab2cppdoc'\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n# The paper size ('letterpaper' or 'a4paper').\n#'papersize': 'letterpaper',\n\n# The font size ('10pt', '11pt' or '12pt').\n#'pointsize': '10pt',\n\n# Additional stuff for the LaTeX preamble.\n#'preamble': '',\n\n# Latex figure (float) alignment\n#'figure_align': 'htbp',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n  (master_doc, 'matlab2cpp.tex', u'matlab2cpp Documentation',\n   u'Jonathan Feinberg', 'manual'),\n]\n\n# The name of an image file (relative to this directory) to place at the top of\n# the title page.\n#latex_logo = None\n\n# For \"manual\" documents, if this is true, then toplevel headings are parts,\n# not chapters.\n#latex_use_parts = False\n\n# If true, show page references after internal links.\n#latex_show_pagerefs = False\n\n# If true, show URL addresses after external links.\n#latex_show_urls = False\n\n# Documents to append as an appendix to all manuals.\n#latex_appendices = []\n\n# If false, no module index is generated.\n#latex_domain_indices = True\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    (master_doc, 'matlab2cpp', u'matlab2cpp Documentation',\n     [author], 1)\n]\n\n# If true, show URL addresses after external links.\n#man_show_urls = False\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n  (master_doc, 'matlab2cpp', u'matlab2cpp Documentation',\n   author, 'matlab2cpp', 'One line description of project.',\n   'Miscellaneous'),\n]\n\n# Documents to append as an appendix to all manuals.\n#texinfo_appendices = []\n\n# If false, no module index is generated.\n#texinfo_domain_indices = True\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#texinfo_show_urls = 'footnote'\n\n# If true, do not generate a @detailmenu in the \"Top\" node's menu.\n#texinfo_no_detailmenu = False\n"
  },
  {
    "path": "doc/user_manual/source/dev00_overview.rst~",
    "content": ".. _dev00:\n\nModule overview\n===============\n\n.. automodule:: matlab2cpp\n\n\n"
  },
  {
    "path": "doc/user_manual/source/index.rst",
    "content": "Matlab2cpp User Manual\n=================\n\n===========\nUser Manual\n===========\n\n.. toctree::\n    :maxdepth: 3\n\n    intro\n    installation\n    interaction\n    usr02_datatype\n    usr03_rules\n    usr04_node\n\n\n"
  },
  {
    "path": "doc/user_manual/source/index.rst~",
    "content": "Matlab2cpp User Manual\n=================\n\n===========\nUser Manual\n===========\n\n.. toctree::\n    :maxdepth: 3\n\n    usr00_intro\n    usr01_interaction\n    usr02_datatype\n    usr03_rules\n    usr04_node\n\n\n"
  },
  {
    "path": "doc/user_manual/source/usr00_intro.rst~",
    "content": ".. _usr00:\n\nIntroduction\n************\n..\n\t.. include:: ../../../README.md\n\n.. automodule:: matlab2cpp.manual.usr00_introduction\n"
  },
  {
    "path": "doc/user_manual/source/usr02_datatype.rst",
    "content": "..\n    .. automodule:: matlab2cpp.manual.usr02_datatype\n\n.. _usr02:\n\nConfiguring translation\n=======================\n\nOne of the translation challenges is how each variable type is determined. In\nC++ all variables have to be explicitly declared, while in Matlab they are\ndeclared implicitly at creation.  When translating between the two languages,\nthere are many variables where the data types are unknown and impossible for\nthe Matlab2cpp software to translate.  How to translate the behavior of an\ninteger is vastly different from an float matrix.\n\nTo differentiate between types, each node have an attribute\n:py:attr:`~matlab2cpp.Node.type` which represents the node datatype.\nDatatypes can be roughly split into two groups: **numerical** and\n**non-numerical** types.  The numerical types are as follows:\n\n+---------------+--------------+---------+---------+--------+-----------+\n|               | unsigned int | integer | float   | double | complex   |\n+===============+==============+=========+=========+========+===========+\n| `scalar`      | uword        | int     | float   | double | cx_double |\n+---------------+--------------+---------+---------+--------+-----------+\n| `vector`      | uvec         | ivec    | fvec    | vec    | cx_vec    |\n+---------------+--------------+---------+---------+--------+-----------+\n| `row\\-vector` | urowvec      | irowvec | frowvec | rowvec | cx_rowvec |\n+---------------+--------------+---------+---------+--------+-----------+\n| `matrix`      | umat         | imat    | fmat    | mat    | cx_mat    |\n+---------------+--------------+---------+---------+--------+-----------+\n| `cube`        | ucube        | icube   | fcube   | cube   | cx_cube   |\n+---------------+--------------+---------+---------+--------+-----------+\n\nValues along the horizontal axis represents the amount of memory reserved per\nelement, and the along the vertical axis represents the various number of\ndimensions.  The names are equivalent to the ones in the Armadillo package.\n\nThe non-numerical types are as follows:\n\n+----------------------------------+------------------------+\n| Name                             | Description            |\n+==================================+========================+\n| `char`                           | Single text character  |\n+----------------------------------+------------------------+\n| `string`                         | Text string            |\n+----------------------------------+------------------------+\n| :ref:`struct <struct>`           | Struct container       |\n+----------------------------------+------------------------+\n| :ref:`structs <structs>`         | Struct array container |\n+----------------------------------+------------------------+\n| :ref:`func_lambda <func_lambda>` | Anonymous function     |\n+----------------------------------+------------------------+\n\nFunction scope\n--------------\n\nIf not specified otherwise, the program will not assign datatype types to any\nof variables. The user could in theory navigate the node tree and assign the\nvariables one by one using the node attributes to navigate. (See section\n:ref:`usr04` for details.) However that would be very cumbersome. Instead the\ndatatypes are define collectively inside their scope. In the case of variables\nin functions, the scope variables are the variables declaration\n:py:class:`~matlab2cpp.Declares` and function parameters\n:py:class:`~matlab2cpp.Params`. To reach the variable that serves as\na scope-wide type, the node attribute :py:attr:`~matlab2cpp.Node.declare` can\nbe used.\n\nManually interacting with the variable scope is simpler then iterating through\nthe full tree, but can in many cases still be cumbersome. To simplefy\ninteraction with datatype scopes, each program has an suppliment attribute\n:py:attr:`~matlab2cpp.Node.ftypes`. The attribute is a nested dictionary where\nthe outer shell represents the function name the variables are defined. The\ninner shell is the variables where keys are variable names and values are\ntypes. It can be used to quickly retrievieng and inserting datatypes.\nFor example::\n\n    >>> tree = mc.build(\"function f(a)\")\n    >>> print tree.ftypes\n    {'f': {'a': ''}}\n    >>> tree.ftypes = {\"f\": {\"a\": \"int\"}}\n    >>> print mc.qscript(tree)\n    void f(int a)\n    {\n      // Empty block\n    }\n\n.. _func_lambda:\n\nAnonymous functions\n-------------------\n\nIn addition to normal function, Matlab have support for anonymous function\nthrough the name prefix ``@``.  For example::\n\n    >>> print mc.qscript(\"function f(); g = @(x) x^2; g(4)\")\n    void f()\n    {\n      std::function<double(int)> g ;\n      g = [] (int x) {pow(x, 2) ; } ;\n      g(4) ;\n    }\n\nThe translator creates an ``C++11`` lambda function with equivalent\nfunctionality.  To achieve this, the translator creates an extra function in\nthe node-tree.  The name of the function is the same as assigned variable with\na ``_``-prefix (and a number postfix, if name is taken).  The information about\nthis function dictate the behaviour of the output The supplement file have the\nfollowing form::\n\n    >>> print mc.qpy(\"function f(); g = @(x) x^2; g(4)\")\n    functions = {\n      \"_g\" : {\n              \"x\" : \"int\",\n      },\n      \"f\" : {\n        \"g\" : \"func_lambda\",\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n\nThe function `g` is a variable inside `f`'s function scope.  It has the datatype\n`func_lambda` to indicate that it should be handled as a function.  The\nassociated function scope `_g` contains the variables inside the definition of\nthe anonymous function.\n\n\n.. _struct:\n\nData structure\n--------------\n\nData structures in Matlab can be constructed explicitly through the\n``struct``-function.  However, they can also be constructed implicitly by\ndirect assignment.  For example will ``a.b=4`` create a ``struct`` with name\n``a`` that has one field ``b``.  When translating such a snippet, it creates\na C++-struct, such that::\n\n    >>> print mc.qhpp(\"function f(); a.b = 4.\", suggest=True)\n    #ifndef F_M_HPP\n    #define F_M_HPP\n    <BLANKLINE>\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    struct _A\n    {\n      double b ;\n    } ;\n    <BLANKLINE>\n    void f()\n    {\n      _A a ;\n      a.b = 4. ;\n    }\n    #endif\n\nIn the suppliment file, the local variable `a` will be assigned as a `struct`.\nIn addition, since the struct has content, the suppliment file creates a new\nsection for structs.  It will have the following form::\n\n    >>> print mc.qpy(\"function f(); a.b = 4.\", suggest=True)\n    functions = {\n      \"f\" : {\n        \"a\" : \"struct\",\n      },\n    }\n    structs = {\n      \"a\" : {\n        \"b\" : \"double\",\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n\nQuick retrieving and inserting struct variables can be done through the\n:py:attr:`~matlab2cpp.Node.stypes` attribute::\n\n    >>> tree = mc.build(\"a.b = 4\")\n    >>> tree.ftypes = {\"f\": {\"a\": \"struct\"}}\n    >>> tree.stypes = {\"a\": {\"b\": \"double\"}}\n    >>> print mc.qcpp(tree)\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    struct _A\n    {\n      double b ;\n    } ;\n    <BLANKLINE>\n    int main(int argc, char** argv)\n    {\n      _A a ;\n      a.b = 4 ;\n      return 0 ;\n    }\n\n.. _structs:\n\nStruct tables\n-------------\n\nGiven that the data structure is indexed, e.g. ``a(1).b``, it forms a struct\ntable.  Very similar to regular :ref:`structs <struct>`, which only has one\nvalue per element.  There are a couple of differences in the translation.\nFirst, the struct is declared as an array:\n\n    >>> print mc.qhpp(\"function f(); a(1).b = 4.\", suggest=True)\n    #ifndef F_M_HPP\n    #define F_M_HPP\n    <BLANKLINE>\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    struct _A\n    {\n      double b ;\n    } ;\n    <BLANKLINE>\n    void f()\n    {\n      _A a[100] ;\n      a[0].b = 4. ;\n    }\n    #endif\n\nThe translation assigned reserves 100 pointers for the content of ``a``.\nObviously, there are situations where this isn't enough (or too much), and the\nnumber should be increased. So second, to adjust this number, the suppliment\nfile specifies the number of elements in the integer ``_size``:\n\n    >>> print mc.qpy(\"function f(); a(1).b = 4.\", suggest=True)\n    functions = {\n      \"f\" : {\n        \"a\" : \"structs\",\n      },\n    }\n    structs = {\n      \"a\" : {\n        \"_size\" : 100,\n            \"b\" : \"double\",\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n\n.. _usr02_suggestion_engine:\n\nSuggestion engine\n-----------------\n\nThe examples so far, when the functions :py:func:`~matlab2cpp.qcpp`,\n:py:func:`~matlab2cpp.qhpp` and :py:func:`~matlab2cpp.qpy` are used, the\nargument ``suggest=True`` have been used, and all variable types have been\nfilled in. Consider the following program where this is not the case::\n\n    >>> print mc.qhpp(\"function c=f(); a = 4; b = 4.; c = a+b\", suggest=False)\n    #ifndef F_M_HPP\n    #define F_M_HPP\n    <BLANKLINE>\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    TYPE f()\n    {\n      TYPE a, b, c ;\n      a = 4 ;\n      b = 4. ;\n      c = a+b ;\n      return c ;\n    }\n    #endif\n\nSince all variables are unknown, the program decides to fill in the dummy\nvariable ``TYPE`` for each unknown variable. Any time variables are unknown,\n``TYPE`` is used. The supplement file created by `m2cpp` or\n:py:func:`~matlab2cpp.qpy` reflects all these unknown variables as follows::\n\n    >>> print mc.qpy(\"function c=f(); a = 4; b = 4.; c = a+b\", suggest=False)\n    functions = {\n      \"f\" : {\n        \"a\" : \"\", # int\n        \"b\" : \"\", # double\n        \"c\" : \"\",\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n\nBy flipping the boolean to ``True``, all the variables get assigned datatypes::\n\n    >>> print mc.qpy(\"function c=f(); a = 4; b = 4.; c = a+b\", suggest=True)\n    functions = {\n      \"f\" : {\n        \"a\" : \"int\",\n        \"b\" : \"double\",\n        \"c\" : \"double\",\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n\nThe resulting program will have the following complete form:\n\n    >>> print mc.qhpp(\n    ...     \"function c=f(); a = 4; b = 4.; c = a+b\", suggest=True)\n    #ifndef F_M_HPP\n    #define F_M_HPP\n    <BLANKLINE>\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    double f()\n    {\n      double b, c ;\n      int a ;\n      a = 4 ;\n      b = 4. ;\n      c = a+b ;\n      return c ;\n    }\n    #endif\n\nNote here though that the variable ``c`` didn't have a suggestion. The\nsuggestion is an interactive process such that ``a`` and ``b`` both must be\nknown beforehand.  The variable ``a`` and ``b`` get assigned the datatypes\n``int`` and ``double`` because of the direct assignment of variable.  After\nthis, the process starts over and tries to find other variables that suggestion\ncould fill out for.  In the case of the ``c`` variable, the assignment on the\nright were and addition between ``int`` and ``double``.  To not loose\nprecision, it then chooses to keep `double`, which is passed on to the ``c``\nvariable.  In practice the suggestions can potentially fill in all datatypes\nautomatically in large programs, and often quite intelligently. For example,\nvariables get suggested across function call scope::\n\n    >>> print mc.qscript('function y=f(x); y=x; function g(); z=f(4)')\n    int f(int x)\n    {\n      int y ;\n      y = x ;\n      return y ;\n    }\n    <BLANKLINE>\n    void g()\n    {\n      int z ;\n      z = f(4) ;\n    }\n\nAnd accross multiple files::\n\n    >>> builder = mc.Builder()\n    >>> builder.load(\"f.m\", \"function y=f(x); y=x\")\n    >>> builder.load(\"g.m\", \"function g(); z=f(4)\")\n    >>> builder.configure(suggest=True)\n    >>> tree_f, tree_g = builder[:]\n    >>> print mc.qscript(tree_f)\n    int f(int x)\n    {\n      int y ;\n      y = x ;\n      return y ;\n    }\n    >>> print mc.qscript(tree_g)\n    void g()\n    {\n      int z ;\n      z = f(4) ;\n    }\n\nVerbatim translations\n---------------------\n\nIn some cases, the translation can not be performed. For example, the Matlab\nfunction ``eval`` can not be properly translated. Matlab is interpreted, and\ncan easily take a string from local name space, and feed it to the interpreter.\nIn C++ however, the code must be pre-compiled. Not knowing what the string\ninput is before runtime, makes this difficult. So instead it makes more sense\nto make some custom translation by hand.\n\nSince ``matlab2cpp`` produces C++ files, it is possible to edit them after\ncreation. However, if changes are made to the Matlab-file at a later point, the\ncustom edits have to be added manually again. To resolve this, ``matlab2cpp``\nsupports verbatim translations through the suppliment file ``.py`` and through\nthe node attribute :py:attr:`~matlab2cpp.Node.vtypes`.\n:py:attr:`~matlab2cpp.node.vtype` is a dictionary where the keys are string\nfound in the orginal code, and the values are string of the replacement.\n\nPerforming a verbatim replacement has to be done before the node tree is\nconstructed. Assigning :py:attr:`~matlab2cpp.Node.vtypes` doesn't work very\nwell. Instead the replacement dictionary can be bassed as argument to\n:py:func:`~matlab2cpp.build`::\n\n    >>> tree = mc.build('''a=1\n    ... b=2\n    ... c=3''', vtypes = {\"b\": \"_replaced_text_\"})\n    >>> print mc.qscript(tree)\n    a = 1 ;\n    // b=2\n    _replaced_text_\n    c = 3 ;\n\nNote that when a match is found, the whole line is replaced. No also how the\nsource code is retained a comment above the verbatim translation. The\nverbatim key can only match a single line, however the replacement might span\nmultiple lines. For example::\n\n    >>> replace_code = '''one line\n    ... two line\n    ... three line'''\n    >>> tree = mc.build('''a=1\n    ... b=2\n    ... c=3''', vtypes={\"b\": replace_code})\n    >>> print mc.qscript(tree)\n    a = 1 ;\n    // b=2\n    one line\n    two line\n    three line\n    c = 3 ;\n\nVerbatims can also be utilized by modifying the .py file. Consider the Matlab script::\n\n    a = 1 ;\n    b = 2 ;\n    c = 3 ;\n\nUsing the m2cpp script to translate the Matlab script produces a C++ file and a .py file. By adding code to the .py file, verbatim translation can be added. This is done by using the keyword verbatims and setting it to a python dictionary. Similar to vtype, keys are strings found in the original code, and the values are string of the replacement::\n\n    functions = {\n    \"main\" : {\n    \"a\" : \"int\",\n    \"b\" : \"int\",\n    \"c\" : \"int\",\n    },\n    }\n    includes = [\n    '#include <armadillo>',\n    'using namespace arma ;',\n    ]\n    verbatims = {\"b = 2 ;\" : '''one line\n    two line\n    tree line'''\n    }\n\nIn the generated C++ file the second assignment is replaced with the verbatim translation::\n\n    int main(int argc, char** argv)\n    {\n      int a, c ;\n      a = 1 ;\n      // b = 2 ;\n      one line\n      two line\n      tree line\n      c = 3 ;\n      return 0 ;\n    }\n\n   \n"
  },
  {
    "path": "doc/user_manual/source/usr03_rules.rst",
    "content": ".. automodule:: matlab2cpp.manual.usr03_rules\n"
  },
  {
    "path": "doc/user_manual/source/usr04_node.rst",
    "content": ".. automodule:: matlab2cpp.manual.usr04_node\n"
  },
  {
    "path": "requirements.txt",
    "content": "pytest==3.2.2\npytest-runner==2.12.1\npytest-cov==2.5.1\ncodecov==2.0.16\n"
  },
  {
    "path": "setup.cfg",
    "content": "[aliases]\ntest = pytest\n\n[tool:pytest]\nnorecursedirs = test/data\ntestpaths = src/matlab2cpp test\naddopts = --doctest-modules --cov=./src\n\n[metadata]\ndescription-file = README.md\n"
  },
  {
    "path": "setup.py",
    "content": "\"\"\"Main installer.\"\"\"\nfrom setuptools import setup, find_packages\n\nsetup(\n    name=\"matlab2cpp\",\n    version=\"2.0.1\",\n    packages=find_packages(\"src\"),\n    package_dir={\"\": \"src\"},\n    entry_points={\"console_scripts\": [\"m2cpp = matlab2cpp:m2cpp\"]},\n    url='http://github.com/jonathf/matlab2cpp',\n    license='BSD',\n    author=\"Jonathan Feinberg\",\n    author_email=\"jonathan@feinberg.no\",\n    description=\"Matlab to C++ transpiler\",\n    classifiers=[\n        'Development Status :: 4 - Beta',\n        'Environment :: Console',\n        'Intended Audience :: Developers',\n        'License :: OSI Approved :: BSD License',\n        'Operating System :: OS Independent',\n        'Natural Language :: English',\n        'Programming Language :: Python',\n        'Topic :: Software Development :: Compilers',\n    ],\n    tests_require=[\"pytest\", \"pytest-runner\"],\n)\n"
  },
  {
    "path": "src/matlab2cpp/__init__.py",
    "content": "#!/usr/bin/env python\n# PYTHON_ARGCOMPLETE_OK\n\"\"\"\n\nThe toolbox is sorted into the following modules:\n\n+----------------------------------+----------------------------------------+\n| Module                           | Description                            |\n+==================================+========================================+\n| :py:mod:`~matlab2cpp.qfunctions` | Functions for performing simple        |\n|                                  | translations                           |\n+----------------------------------+----------------------------------------+\n| :py:class:`~matlab2cpp.Builder`  | Constructing a tree from Matlab code   |\n+----------------------------------+----------------------------------------+\n| :py:class:`~matlab2cpp.Node`     | Components in the tree representation  |\n|                                  | of the code                            |\n+----------------------------------+----------------------------------------+\n| :py:mod:`~matlab2cpp.collection` | The collcetion of various node         |\n+----------------------------------+----------------------------------------+\n| :py:mod:`~matlab2cpp.configure`  | Rutine for setting datatypes and       |\n|                                  | backends of the various nodes          |\n+----------------------------------+----------------------------------------+\n| :py:mod:`~matlab2cpp.rules`      | Translation rules                      |\n+----------------------------------+----------------------------------------+\n| :py:mod:`~matlab2cpp.supplement` | Functions for inserting and extraction |\n|                                  | datatypes                              |\n+----------------------------------+----------------------------------------+\n| :py:mod:`~matlab2cpp.testsuite`  | Suite for testing software             |\n+----------------------------------+----------------------------------------+\n\n\nThe simplest way to use the library is to use the quick translation functions.\nThey are available through the `matlab2cpp.qfunctions` module and mirrors the\nfunctionality offered by the `m2cpp` function.\n\"\"\"\ntry:\n    import argcomplete\nexcept ImportError:\n    argcomplete = None\n\nfrom .parser import create_parser\nfrom .qfunctions import *\n\n__version__ = \"2.0\"\n\n\ndef m2cpp(args=None):\n    \"\"\"\n    Execute main parser.\n\n    Args:\n        args (Optional[List[str]]):\n            Argument to be parsed. If omitted, use ``sys.args``.\n    \"\"\"\n    parser = create_parser()\n    if argcomplete is not None:\n        argcomplete.autocomplete(parser)\n\n    args = parser.parse_args(args)\n\n    from matlab2cpp.frontend import execute_parser\n    execute_parser(args)\n"
  },
  {
    "path": "src/matlab2cpp/collection.py",
    "content": "# encoding: utf-8\nr\"\"\"\nA full summary of all nodes.\n\n+---------------------+--------------------+----------------+------------------------------+\n| Name                | Children           | Example        | Description                  |\n+=====================+====================+================+==============================+\n| All                 |                    | `:`            | Colon operator w/o range     |\n+---------------------+--------------------+----------------+------------------------------+\n| Assign              | `Expr Expr`        | `a=b`          | Assignment one var           |\n+---------------------+--------------------+----------------+------------------------------+\n| Assigns             | `Expr Expr+`       | `[a,b]=c`      | Assignment multi vars        |\n+---------------------+--------------------+----------------+------------------------------+\n| Band                | `Expr Expr+`       | `a&b`          | Binary AND operator          |\n+---------------------+--------------------+----------------+------------------------------+\n| Bcomment            |                    | `%{ . %}`      | Block comment                |\n+---------------------+--------------------+----------------+------------------------------+\n| Block               | `Line*`            | `a`            | Code block                   |\n+---------------------+--------------------+----------------+------------------------------+\n| Bor                 | `Expr Expr+`       | `a|b`          | Binary OR operator           |\n+---------------------+--------------------+----------------+------------------------------+\n| Branch              | `If Ifse* Else?`   | `if a; end`    | If chain container           |\n+---------------------+--------------------+----------------+------------------------------+\n| Break               |                    | `break`        | Break statement              |\n+---------------------+--------------------+----------------+------------------------------+\n| Case                | `Var Block`        | `case a`       | Case part of Switch          |\n+---------------------+--------------------+----------------+------------------------------+\n| Catch               | `Block`            | `catch a`      | Catch part of Tryblock       |\n+---------------------+--------------------+----------------+------------------------------+\n| Cell                | `Expr*`            | `{a}`          | Cell array                   |\n+---------------------+--------------------+----------------+------------------------------+\n| Cget                | `Expr+`            | `a{b}(c)`      | Cell retrival                |\n+---------------------+--------------------+----------------+------------------------------+\n| Colon               | `Expr Expr Expr?`  | `a:b`          | Colon operator w range       |\n+---------------------+--------------------+----------------+------------------------------+\n| Counter             |                    |                | Struct array size            |\n+---------------------+--------------------+----------------+------------------------------+\n| Cset                | `Expr+`            | `a{b}(c)=d`    | Cell array assignment        |\n+---------------------+--------------------+----------------+------------------------------+\n| Ctranspose          | `Expr`             | `a'`           | Complex transform            |\n+---------------------+--------------------+----------------+------------------------------+\n| Cvar                | `Expr+`            | `a{b}`         | Cell variable                |\n+---------------------+--------------------+----------------+------------------------------+\n| Declares            | `Var*`             |                | Declared variable list       |\n+---------------------+--------------------+----------------+------------------------------+\n| Ecomment            |                    | `a%b`          | End-of-line comment          |\n+---------------------+--------------------+----------------+------------------------------+\n| Elementdivision     | `Expr Expr+`       | `a./b`         | Sclars division              |\n+---------------------+--------------------+----------------+------------------------------+\n| Elexp               | `Expr Expr+`       | `a.^b`         | Element-wise exponent        |\n+---------------------+--------------------+----------------+------------------------------+\n| Elif                | `Expr Block`       | `elseif a`     | Else-if part of Branch       |\n+---------------------+--------------------+----------------+------------------------------+\n| Elmul               | `Expr Expr+`       | `a.*b`         | Element-wise multiplication  |\n+---------------------+--------------------+----------------+------------------------------+\n| Else                | `Block`            | `else`         | Else part of Branch          |\n+---------------------+--------------------+----------------+------------------------------+\n| End                 |                    | `end`          | End-expression               |\n+---------------------+--------------------+----------------+------------------------------+\n| Eq                  | `Expr Expr`        | `a==b`         | Equallity sign               |\n+---------------------+--------------------+----------------+------------------------------+\n| Error               |                    |                | Error node                   |\n+---------------------+--------------------+----------------+------------------------------+\n| Exp                 | `Expr Expr+`       | `a^b`          | Exponential operator         |\n+---------------------+--------------------+----------------+------------------------------+\n| Fget                | `Expr*`            | `a.b(c)`       | Fieldarray retrival          |\n+---------------------+--------------------+----------------+------------------------------+\n| Float               |                    | `4.`           | Float-point number           |\n+---------------------+--------------------+----------------+------------------------------+\n| For                 | `Var Expr Block`   | `for a=b;end`  | For-loop container           |\n+---------------------+--------------------+----------------+------------------------------+\n| Fset                | `Expr Expr+`       | `a.b(c)=d`     | Fieldname assignment         |\n+---------------------+--------------------+----------------+------------------------------+\n| Func                | `Declares Returns` | `function f()` | Function container           |\n|                     | `Params Block`     | `end`          |                              |\n+---------------------+--------------------+----------------+------------------------------+\n| Funcs               | `[Main Func+]`     |                | Root of all functions        |\n+---------------------+--------------------+----------------+------------------------------+\n| Fvar                |                    | `a.b`          | Fieldname variable           |\n+---------------------+--------------------+----------------+------------------------------+\n| Ge                  | `Expr Expr`        | `a>=b`         | Greater-or-equal operator    |\n+---------------------+--------------------+----------------+------------------------------+\n| Get                 | `Expr*`            | `a(b)`         | Function or retrival         |\n+---------------------+--------------------+----------------+------------------------------+\n| Gt                  | `Expr Expr`        | `a>b`          | Greater operator             |\n+---------------------+--------------------+----------------+------------------------------+\n| Header              |                    |                | File header element          |\n+---------------------+--------------------+----------------+------------------------------+\n| Headers             |                    |                | Collection header lines      |\n+---------------------+--------------------+----------------+------------------------------+\n| If                  | `Expr Block`       | `if a`         | If part of Branch            |\n+---------------------+--------------------+----------------+------------------------------+\n| Imag                |                    | `i`            | Imaginary unit               |\n+---------------------+--------------------+----------------+------------------------------+\n| Include             |                    |                | Include statement            |\n+---------------------+--------------------+----------------+------------------------------+\n| Includes            |                    |                | Collection of includes       |\n+---------------------+--------------------+----------------+------------------------------+\n| Int                 |                    | `1`            | Integer value                |\n+---------------------+--------------------+----------------+------------------------------+\n| Lambda              |                    | `f=@()1`       | Lambda function expression   |\n+---------------------+--------------------+----------------+------------------------------+\n| Land                | `Expr Expr+`       | `a&&b`         | Logical AND operator         |\n+---------------------+--------------------+----------------+------------------------------+\n| Lcomment            |                    | `%a`           | Line-comment                 |\n+---------------------+--------------------+----------------+------------------------------+\n| Le                  | `Expr Expr`        | `a<=b`         | Less-or-equal operator       |\n+---------------------+--------------------+----------------+------------------------------+\n| Leftelementdivision | `Expr Expr+`       | `a.\\b`         | Left sclar division          |\n+---------------------+--------------------+----------------+------------------------------+\n| Leftmatrixdivision  | `Expr Expr+`       | `a\\b`          | Left matrix division         |\n+---------------------+--------------------+----------------+------------------------------+\n| Log                 | `[Error Warning]+` |                | Collection of Errors         |\n+---------------------+--------------------+----------------+------------------------------+\n| Lor                 | `Expr Expr`        | `a||b`         | Logical OR operator          |\n+---------------------+--------------------+----------------+------------------------------+\n| Lt                  | `Expr Expr`        | `a<b`          | Less-then operator           |\n+---------------------+--------------------+----------------+------------------------------+\n| Main                | `Declares Returns` | `function f()` | Container for                |\n|                     | `Params Block`     | `end`          | main function                |\n+---------------------+--------------------+----------------+------------------------------+\n| Matrix              | `Vector*`          | `[a]`          | Matrix container             |\n+---------------------+--------------------+----------------+------------------------------+\n| Matrixdivision      | `Expr Expr+`       | `a/b`          | Matrix division              |\n+---------------------+--------------------+----------------+------------------------------+\n| Minus               | `Expr Expr+`       | `a-b`          | Minus operator               |\n+---------------------+--------------------+----------------+------------------------------+\n| Mul                 | `Expr Expr+`       | `a*b`          | Multiplication operator      |\n+---------------------+--------------------+----------------+------------------------------+\n| Ne                  | `Expr Expr`        | `a~=b`         | Not-equal operator           |\n+---------------------+--------------------+----------------+------------------------------+\n| Neg                 | `Expr`             | `-a`           | Unary negative sign          |\n+---------------------+--------------------+----------------+------------------------------+\n| Nget                | `Expr`             | `a.(b)`        | Namefield retrival           |\n+---------------------+--------------------+----------------+------------------------------+\n| Not                 | `Expr`             | `~a`           | Not operator                 |\n+---------------------+--------------------+----------------+------------------------------+\n| Nset                | `Expr`             | `a.(b)=c`      | Namefield assignment         |\n+---------------------+--------------------+----------------+------------------------------+\n| Otherwise           | `Block`            | `otherwise`    | Otherwise part of Switch     |\n+---------------------+--------------------+----------------+------------------------------+\n| Params              | `Var*`             |                | Function parameter container |\n+---------------------+--------------------+----------------+------------------------------+\n| Parfor              | `Var Expr Block`   | `parfor a=b;end`| Parallel for-loop container |\n+---------------------+--------------------+----------------+------------------------------+\n| Plus                | `Expr Expr+`       | `a+b`          | Addition operator            |\n+---------------------+--------------------+----------------+------------------------------+\n| Pragma_for          |                    | `%%PARFOR str` | For-loop pragma              |\n+---------------------+--------------------+----------------+------------------------------+\n| Program             | `Includes Funcs`   |                | Program root                 |\n|                     | `Inlines Structs`  |                |                              |\n|                     | `Headers Log`      |                |                              |\n+---------------------+--------------------+----------------+------------------------------+\n| Project             | `Program+`         |                | Root of all programs         |\n+---------------------+--------------------+----------------+------------------------------+\n| Return              |                    | `return`       | Return statement             |\n+---------------------+--------------------+----------------+------------------------------+\n| Returns             | `Var*`             |                | Return value collection      |\n+---------------------+--------------------+----------------+------------------------------+\n| Set                 | `Expr*`            | `a(b)=c`       | Array value assignment       |\n+---------------------+--------------------+----------------+------------------------------+\n| Sget                | `Expr+`            | `a.b(c)`       | Submodule function/retrival  |\n+---------------------+--------------------+----------------+------------------------------+\n| Sset                | `Expr+`            | `a.b(c)=d`     | Submodule assignment         |\n+---------------------+--------------------+----------------+------------------------------+\n| Statement           | `Expr`             | `a`            | Stand alone statement        |\n+---------------------+--------------------+----------------+------------------------------+\n| String              |                    | `'a'`          | String representation        |\n+---------------------+--------------------+----------------+------------------------------+\n| Struct              |                    |                | Struct container             |\n+---------------------+--------------------+----------------+------------------------------+\n| Structs             |                    |                | Container for structs        |\n+---------------------+--------------------+----------------+------------------------------+\n| Switch              | `Var Case+ Other`  | `case a; end`  | Container for Switch branch  |\n+---------------------+--------------------+----------------+------------------------------+\n| Transpose           | `Expr`             | `a'`           | Transpose operator           |\n+---------------------+--------------------+----------------+------------------------------+\n| Try                 | `Block`            | `try`          | Try part of Tryblock         |\n+---------------------+--------------------+----------------+------------------------------+\n| Tryblock            | `Try Catch`        | `try; end`     | Container for try-blocks     |\n+---------------------+--------------------+----------------+------------------------------+\n| Var                 |                    | `a`            | Variable                     |\n+---------------------+--------------------+----------------+------------------------------+\n| Vector              | `Expr*`            | `[a]`          | Row-vector part of Matrix    |\n+---------------------+--------------------+----------------+------------------------------+\n| Warning             |                    |                | Element in Log               |\n+---------------------+--------------------+----------------+------------------------------+\n| While               | `Expr Block`       | `while a;end`  | While-loop container         |\n+---------------------+--------------------+----------------+------------------------------+\n\"\"\"\n\nfrom .node import Node\n\n__all__ = [\n    \"All\", \"Assign\", \"Assigns\", \"Band\", \"Bcomment\", \"Block\", \"Bor\", \"Branch\",\n    \"Break\", \"Case\", \"Catch\", \"Cell\", \"Cget\", \"Colon\",\n    \"Counter\", \"Cset\", \"Ctranspose\", \"Cvar\", \n    \"Declares\", \"Ecomment\",\n    \"Elementdivision\", \"Elexp\", \"Elif\", \"Elmul\", \"Else\", \"End\", \"Eq\", \"Error\",\n    \"Exp\", \"Expr\", \"Fget\", \"Float\", \"Parfor\", \"Pragma_for\", \"For\", \"Fset\", \"Func\", \"Funcs\", \"Fvar\", \"Ge\",\n    \"Get\", \"Gt\", \"Header\", \"Headers\", \"If\", \"Imag\", \"Include\", \"Includes\", \"Inline\",\n    \"Inlines\", \"Int\", \"Lambda\", \"Land\", \"Lcomment\", \"Le\", \"Leftelementdivision\",\n    \"Leftmatrixdivision\", \"Log\", \"Lor\", \"Lt\", \"Main\", \"Matrix\", \"Matrixdivision\",\n    \"Minus\", \"Mul\", \"Ne\", \"Neg\", \"Nget\", \"Not\", \"Nset\", \"Opr\", \"Otherwise\",\n    \"Params\", \"Paren\", \"Plus\", \"Program\", \"Project\", \"Resize\", \"Return\", \"Returns\",\n    \"Set\", \"Sget\", \"Sset\", \"Statement\", \"String\", \"Struct\", \"Structs\", \"Switch\",\n    \"Transpose\", \"Try\", \"Tryblock\", \"Var\", \"Vector\", \"Warning\", \"While\"\n]\n\nclass Project(Node):\n    def __init__(self, name=\"\", cur=0, line=0, code=\"\", **kws):\n        \"\"\"\nRoot of the node tree. Every other node should inherant from this one.\n\nThis node should not recieve `parent` argument node during construction.\n\nChildren:\n    `Program+`\n\nAll keyword arguments are passed to `matlab2cpp.Node.__init__`.\n    \"\"\"\n        assert \"parent\" not in kws\n        self.parent = self\n        self._program = self\n        Node.__init__(self, self, name=name, cur=cur,\n                line=line, code=code, **kws)\n\nclass Program(Node):\n    def __init__(self, parent, name, **kws):\n        \"\"\"\nRepresents one stand-alone script or program. Each child represents the various\naspects of script/program.\n\nChildren:\n    `Includes Funcs Inlines Structs Headers Log`\n\nAll keyword arguments are passed to `matlab2cpp.Node.__init__`.\n    \"\"\"\n        self._program = self\n        Node.__init__(self, parent, name=name, **kws)\n\nclass Includes(Node):\n    def __init__(self, parent, **kws):\n        Node.__init__(self, parent, **kws)\n\nclass Funcs(Node):\n    def __init__(self, parent, line=1, **kws):\n        Node.__init__(self, parent, line=line, **kws)\n\nclass Inlines(Node):\n    def __init__(self, parent, **kws):\n        Node.__init__(self, parent, **kws)\n\nclass Structs(Node):\n    def __init__(self, parent, **kws):\n        Node.__init__(self, parent, **kws)\n\nclass Headers(Node):\n    def __init__(self, parent, **kws):\n        Node.__init__(self, parent, **kws)\n\nclass Log(Node):\n    def __init__(self, parent, **kws):\n        Node.__init__(self, parent, **kws)\n\nclass Header(Node):\n    def __init__(self, parent, name, **kws):\n        Node.__init__(self, parent, name=name, **kws)\n\nclass Main(Node):\n    def __init__(self, parent, name=\"main\", **kws):\n        Node.__init__(self, parent, name=name, **kws)\n\nclass Error(Node):\n    def __init__(self, parent, name, value, **kws):\n        Node.__init__(self, parent, name, value=value, **kws)\n        self.prop[\"cls\"] = name[10:]\nclass Warning(Node):\n    def __init__(self, parent, name, value, **kws):\n        Node.__init__(self, parent, name, value=value, **kws)\n        self.prop[\"cls\"] = name[10:]\n\nclass Counter(Node):\n    def __init__(self, parent, name, value, **kws):\n        Node.__init__(self, parent, name,\n                value=value, **kws)\n\nclass Inline(Node):\n    def __init__(self, parent, name, **kws):\n        Node.__init__(self, parent, name, **kws)\n\nclass Include(Includes):\n    def __init__(self, parent, name, **kws):\n        Node.__init__(self, parent, name=name, **kws)\n\nclass Struct(Structs):          pass\n\nclass Func(Node):           pass\nclass Returns(Node):        pass\nclass Params(Node):         pass\nclass Declares(Node):       pass\n\nclass Block(Node):\n    def __init__(self, parent, **kws):\n        Node.__init__(self, parent, **kws)\nclass Parfor(Block):        pass\nclass For(Block):           pass\nclass While(Block):         pass\nclass Switch(Block):        pass\nclass Case(Block):          pass\nclass Otherwise(Block):     pass\nclass Branch(Block):        pass\nclass If(Block):            pass\nclass Elif(Block):          pass\nclass Else(Block):          pass\nclass Tryblock(Block):      pass\nclass Try(Block):           pass\nclass Catch(Block):         pass\nclass Statement(Block):     pass\n\nclass Assign(Node):         pass\nclass Assigns(Node):\n    def __init__(self, parent, **kws):\n        Node.__init__(self, parent, **kws)\n\nclass Expr(Node):\n    def __init__(self, parent, **kws):\n        Node.__init__(self, parent, **kws)\nclass Opr(Expr):            pass\nclass Exp(Opr):             pass\nclass Elexp(Opr):           pass\nclass Mul(Opr):             pass\nclass Minus(Opr):           pass\nclass Elmul(Opr):           pass\nclass Matrixdivision(Opr):      pass\nclass Elementdivision(Opr):     pass\nclass Leftmatrixdivision(Opr):  pass\nclass Leftelementdivision(Opr): pass\nclass Plus(Opr):            pass\nclass Colon(Opr):           pass\nclass Gt(Opr):              pass\nclass Ge(Opr):              pass\nclass Lt(Opr):              pass\nclass Le(Opr):              pass\nclass Ne(Opr):              pass\nclass Eq(Opr):              pass\nclass Band(Opr):            pass\nclass Bor(Opr):             pass\nclass Land(Opr):            pass\nclass Lor(Opr):             pass\n\nclass Matrix(Node):\n    def __init__(self, parent, **kws):\n        Node.__init__(self, parent, **kws)\nclass Vector(Matrix):       pass\n\nclass Cell(Node):\n    def __init__(self, parent, **kws):\n        Node.__init__(self, parent, **kws)\n\nclass Paren(Expr):          pass\nclass Neg(Expr):            pass\nclass Not(Expr):            pass\nclass Ctranspose(Expr):     pass\nclass Transpose(Expr):      pass\nclass All(Expr):            pass\nclass End(Expr):            pass\nclass Break(Expr):          pass\nclass Return(Expr):         pass\n\nclass Int(Node):\n    def __init__(self, parent, value, **kws):\n        Node.__init__(self, parent, value=value, **kws)\n\nclass Float(Node):\n    def __init__(self, parent, value, **kws):\n        if value[0] == \".\": value = \"0\" + value\n        Node.__init__(self, parent, value=value, **kws)\n\nclass Imag(Node):\n    def __init__(self, parent, value, **kws):\n        Node.__init__(self, parent, value=value, **kws)\n\nclass String(Node):\n    def __init__(self, parent, value, **kws):\n        value = value.replace(\"%\", \"__percent__\")\n        Node.__init__(self, parent, value=value, **kws)\n\nclass Lambda(Node):\n    def __init__(self, parent, name=\"\", **kws):\n        Node.__init__(self, parent, name=name, **kws)\n\nclass Pragma_for(Node):\n    def __init__(self, parent, value, **kws):\n        Node.__init__(self, parent, value=value, **kws)\n\nclass Lcomment(Node):\n    def __init__(self, parent, value, **kws):\n        value = value.replace(\"%\", \"__percent__\")\n        Node.__init__(self, parent, value=value, **kws)\n\nclass Bcomment(Node):\n    def __init__(self, parent, value, **kws):\n        value = value.replace(\"%\", \"__percent__\")\n        Node.__init__(self, parent, value=value, **kws)\n\nclass Ecomment(Node):\n    def __init__(self, parent, value, **kws):\n        value = value.replace(\"%\", \"__percent__\")\n        Node.__init__(self, parent, value=value, **kws)\n\nclass Var(Node):\n    def __init__(self, parent, name, **kws):\n        Node.__init__(self, parent, name=name, **kws)\nclass Get(Var):         pass\nclass Set(Var):         pass\n\nclass Fvar(Node):\n    def __init__(self, parent, name, value, **kws):\n        Node.__init__(self, parent, name=name, value=value, **kws)\n\nclass Cvar(Node):\n    def __init__(self, parent, name, **kws):\n        Node.__init__(self, parent, name, **kws)\n\nclass Cget(Node):\n    def __init__(self, parent, name, **kws):\n        Node.__init__(self, parent, name=name, **kws)\n\nclass Fget(Node):\n    def __init__(self, parent, name, value, **kws):\n        Node.__init__(self, parent, name=name, value=value, **kws)\n\nclass Sget(Node):\n    def __init__(self, parent, name, value, **kws):\n        Node.__init__(self, parent, name=name, value=value, **kws)\n\nclass Nget(Node):\n    def __init__(self, parent, name, **kws):\n        Node.__init__(self, parent, name=name, **kws)\n\nclass Cset(Node):\n    def __init__(self, parent, name, **kws):\n        Node.__init__(self, parent, name=name, **kws)\n\nclass Fset(Node):\n    def __init__(self, parent, name, value, **kws):\n        Node.__init__(self, parent, name=name, value=value, **kws)\n\nclass Sset(Node):\n    def __init__(self, parent, name, value, **kws):\n        Node.__init__(self, parent, name=name, value=value, **kws)\n\nclass Nset(Node):\n    def __init__(self, parent, name, **kws):\n        Node.__init__(self, parent, name=name, **kws)\n\nclass Resize(Node):\n    def __init__(self, parent, **kws):\n        Node.__init__(self, parent, **kws)\n\nclass Verbatim(Node):\n    def __init__(self, parent, name, value, **kws):\n        Node.__init__(self, parent, name=name, value=value, **kws)\n"
  },
  {
    "path": "src/matlab2cpp/configure/__init__.py",
    "content": "from .frontend import configure, loop\nfrom . import datatypes, backends, reserved\n"
  },
  {
    "path": "src/matlab2cpp/configure/armadillo.py",
    "content": "from ..rules import armadillo as arma\n\n\ndef vec(node):\n    if len(node) != 1:\n\n        if not len(node):\n            return\n\n        elif len(node) == 2 and node[1].cls == \"Int\" and node[1].value == \"1\":\n            pass\n\n        else:\n            return\n\n\n    arg, dim = arma.configure_arg(node[0], 0)\n\n    if dim == 0:\n        node.dim = 0\n\ndef rowvec(node):\n    if len(node) != 1:\n\n        if not len(node):\n            return\n\n        elif len(node) == 2 and node[0].cls == \"Int\" and node[0].value == \"1\":\n            node_ = node[1]\n\n        else:\n            return\n    else:\n        node_ = node[0]\n\n\n    arg, dim = arma.configure_arg(node_, 0)\n\n    if dim == 0:\n        node.dim = 0\n\ndef mat(node):\n    # Single argument\n    if len(node) == 1:\n\n        arg, dim = arma.configure_arg(node[0], 0)\n\n        # scalar begets scalar\n        if dim == 0:\n            node.dim = 0\n\n    # Double argument\n    elif len(node) == 2:\n\n        arg0, dim0 = arma.configure_arg(node[0], 0)\n        arg1, dim1 = arma.configure_arg(node[1], 1)\n\n        # unknown input\n        if -1 in (dim0, dim1):\n            return\n\n        # Configure dimensions\n        if dim0:\n            if dim1:\n                node.dim = 3#matrix\n            else:\n                node.dim = 1#colvec\n        else:\n            if dim1:\n                node.dim = 2#rowvec\n            else:\n                node.dim = 0#scalar\n\ndef cube(node):\n    # Single argument\n    if len(node) == 1:\n\n        arg, dim = arma.configure_arg(node[0], 0)\n\n        # scalar input\n        if dim == 0:\n            node.dim = 0\n\n    # Double argument\n    elif len(node) == 2:\n\n        arg0, dim0 = arma.configure_arg(node[0], 0)\n        arg1, dim1 = arma.configure_arg(node[1], 1)\n\n        # unkonwn input\n        if -1 in (dim0, dim1):\n            return\n\n        # Configure dimensions\n        if dim0:\n            if dim1:\n                node.dim = 3\n            else:\n                node.dim = 1\n        else:\n            if dim1:\n                node.dim = 2\n            else:\n                node.dim = 0\n\n    # Triple argument\n    elif len(node) == 3:\n\n        arg0, dim0 = arma.configure_arg(node[0], 0)\n        arg1, dim1 = arma.configure_arg(node[1], 1)\n        arg2, dim2 = arma.configure_arg(node[2], 2)\n\n        # unknown arguments\n        if -1 in (dim0, dim1, dim2):\n            return\n\n        # Configure dimensions\n        if dim0:\n            if dim1:\n                if dim2:\n                    node.dim = 4#cube\n                else:\n                    node.dim = 3#matrix\n            else:\n                if dim2:\n                    node.dim = 3#matrix\n                else:\n                    node.dim = 1#colvec\n\n        else:\n            if dim1:\n                if dim2:\n                    node.dim = 3#matrix\n                else:\n                    node.dim = 1#colvec\n            else:\n                if dim2:\n                    node.dim = 1#colvec\n                else:\n                    node.dim = 0#scalar\n"
  },
  {
    "path": "src/matlab2cpp/configure/backends.py",
    "content": "Project = \"program\"\nProgram = \"program\"\nIncludes = \"program\"\nFuncs = \"program\"\nInlines = \"program\"\nStructs = \"program\"\nStruct = \"program\"\nHeaders = \"program\"\nLog = \"program\"\nHeader = \"program\"\nMain = \"func_return\"\nError = \"program\"\nWarning = \"program\"\nCounter = \"structs\"\nInline = \"program\"\nInclude = \"program\"\nBlock = \"code_block\"\nParfor = \"code_block\"\nFor = \"code_block\"\nWhile = \"code_block\"\nSwitch = \"code_block\"\nCase = \"code_block\"\nOtherwise = \"code_block\"\nBranch = \"code_block\"\nIf = \"code_block\"\nElif = \"code_block\"\nElse = \"code_block\"\nTryblock = \"code_block\"\nTry = \"code_block\"\nCatch = \"code_block\"\nStatement = \"code_block\"\ndef Assigns(node):\n    backend = node[-1].backend\n    if backend in (\"func_returns\",):\n        node.backend = backend\n    elif backend != \"unknown\":\n        node.backend = \"code_block\"\nExpr = \"expression\"\nExp = \"expression\"\nElexp = \"expression\"\nMul = \"expression\"\nMinus = \"expression\"\nElmul = \"expression\"\nMatrixdivision = \"expression\"\nElementdivision = \"expression\"\nLeftmatrixdivision = \"expression\"\nLeftelementdivision = \"expression\"\nPlus = \"expression\"\nColon = \"expression\"\nGt = \"expression\"\nGe = \"expression\"\nLt = \"expression\"\nLe = \"expression\"\nNe = \"expression\"\nEq = \"expression\"\nBand = \"expression\"\nBor = \"expression\"\nLand = \"expression\"\nLor = \"expression\"\nParen = \"expression\"\nNeg = \"expression\"\nNot = \"expression\"\nCtranspose = \"expression\"\nTranspose = \"expression\"\nAll = \"expression\"\nEnd = \"expression\"\nBreak = \"expression\"\nReturn = \"expression\"\ndef Matrix(node):\n    # matrix surround struct converts it to array\n    if len(node) == 1 and len(node[0]) == 1:\n        elem = node[0][0]\n        if elem.backend != \"unknown\":\n            node.backend = elem.backend\n\n        if elem.backend != \"unknown\" and elem.backend not in (\"struct\", \"structs\"):\n            node.backend = \"matrix\"\n    else:\n        node.backend = \"matrix\"\n\nVector = \"matrix\"\nCell = \"cell\"\nInt = \"int\"\nFloat = \"double\"\nImag = \"cx_double\"\nString = \"string\"\nLambda = \"func_lambda\"\nPragma_for = \"code_block\"\nTbb_for = \"code_block\"\nLcomment = \"code_block\"\nBcomment = \"code_block\"\nEcomment = \"code_block\"\ndef Fvar(node):\n    \"\"\"\nExample:\n    >>> print(matlab2cpp.qtree(\"a.b = 4.4; c = [a.b]\", core=True, suggest=True)) #doctest: +NORMALIZE_WHITESPACE\n    1   1Block      code_block   TYPE    \n    1   1| Assign     double       double  \n    1   1| | Fvar       struct       double  a\n    1   7| | Float      double       double  \n    1  12| Assign     struct       double  \n    1  12| | Var        double       double  c\n    1  16| | Matrix     struct       double  \n    1  17| | | Vector     matrix       double  \n    1  17| | | | Fvar       struct       double  a\n    \"\"\"\n    declare = node.func[0][node.name]\n    if declare.backend in (\"struct\", \"structs\"):\n        node.backend = declare.backend\n\nCvar = \"cell\"\nCget = \"cell\"\nFget = \"structs\"\nSget = \"structs\"\nNget = \"struct\"\nCset = \"cell\"\nFset = \"structs\"\nSset = \"structs\"\nNset = \"struct\"\nResize = \"cube_common\"\nVerbatim = \"verbatim\"\n\ndef Var(node):\n    if node.type != \"TYPE\":\n        node.backend = node.type\ndef Get(node):\n    if node.type != \"TYPE\":\n        node.backend = node.type\ndef Set(node):\n    if node.type != \"TYPE\":\n        node.backend = node.type\n\ndef Func(node):\n    returns = node[1]\n    if node.name[:1] == \"_\":\n        node.backend = \"func_lambda\"\n    elif len(returns) == 1:\n        node.backend = \"func_return\"\n    else:\n        node.backend = \"func_returns\"\ndef Returns(node):\n    if node.parent.name[:1] == \"_\":\n        node.backend = \"func_lambda\"\n    elif len(node) == 1 or node.parent.cls == \"Main\":\n        node.backend = \"func_return\"\n    else:\n        node.backend = \"func_returns\"\ndef Params(node):\n    returns = node.parent[1]\n    if node.parent.name[:1] == \"_\":\n        node.backend = \"func_lambda\"\n    elif len(returns) == 1 or node.parent.cls == \"Main\":\n        node.backend = \"func_return\"\n    else:\n        node.backend = \"func_returns\"\ndef Declares(node):\n    returns = node.parent[1]\n    if node.parent.name[:1] == \"_\":\n        node.backend = \"func_lambda\"\n    elif len(returns) == 1 or node.parent.cls == \"Main\":\n        node.backend = \"func_return\"\n    else:\n        node.backend = \"func_returns\"\n\ndef Assign(node):\n    node.backend = node[-1].backend\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/configure/datatypes.py",
    "content": "\nfrom .funcs import funcs\nfrom . import armadillo, backends, frontend\n\nCounter = \"structs\"\n\ndef Var(node):\n    \"\"\"\nExample:\n    >>> print(matlab2cpp.qcpp(\"a.b = 4; c = a\"))\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    struct _A\n    {\n      int b ;\n    } ;\n    <BLANKLINE>\n    int main(int argc, char** argv)\n    {\n      _A a, c ;\n      a.b = 4 ;\n      c = a ;\n      return 0 ;\n    }\n    \"\"\"\n\n    if funcs(node):\n        return\n\n    if node.parent.cls == \"Assign\" and node.parent[0] is node:\n        #assign b = [a.val], a is a structs, suggest vec -> dim=1\n        if node.parent[1].cls == \"Matrix\" and \\\n          node.parent[1].backend == \"structs\" and len(node.parent[1][0]) == 1:\n            node.declare.suggest = (1, node.parent[1].mem)\n        #assign b = a, where a is a struct/structs.\n        #This code sets b backend and type to a's backend and type\n        elif node.parent[1].cls in (\"Var\",)\\\n                and node.parent[1].backend in (\"struct\", \"structs\"):\n\n            backend = node.parent[1].backend\n\n            node.parent[1].declare\n            if hasattr(node.parent[1], \"_declare\"):\n\n                node.declare.type = backend\n                node.declare.backend = backend\n                node.declare._declare = node.parent[1]._declare\n                node._declare = node.parent[1]._declare\n                node.backend = backend\n\n        else:\n            node.declare.suggest = node.parent[1].type\n    \n    if node.declare.type != \"TYPE\":\n        node.type = node.declare.type\n\n\ndef Get(node):\n\n    if funcs(node):\n        return\n\n    #in backends.py backend is set to datatype. If a is rowvec,\n    #i want a(2) to have backend rowvec and and datatype double\n    #This code sets backend to rowvec, and below datatype is set\n    #Thus backend is set before datatype is changed to double\n    #backends.Get(node)\n    \n    #vec\n    if node.declare.dim == 1:\n        backends.Get(node)\n        armadillo.vec(node)\n        return\n\n    #rowvec\n    if node.declare.dim == 2:\n        backends.Get(node)\n        armadillo.rowvec(node)\n        return\n\n    #mat\n    if node.declare.dim == 3:\n        backends.Get(node)\n        armadillo.mat(node)\n        return\n\n    #cube\n    if node.declare.dim == 4:\n        backends.Get(node)\n        armadillo.cube(node)\n        return\n    \n    if node.parent.cls == \"Assign\" and node.parent[0] is node:\n        node.declare.suggest = node.parent[1].type\n\n    if node.declare.type != \"TYPE\":\n        node.type = node.declare.type\n\ndef Set(node):\n\n    #in backends.py backend is set to datatype. If a is rowvec,\n    #i want a(2) to have backend rowvec and and datatype double\n    #This code sets backend to rowvec, and below datatype is set\n    #Thus backend is set before datatype is changed to double\n    #backends.Get(node)\n    \n    #vec\n    if node.declare.dim == 1:\n        backends.Get(node)\n        armadillo.vec(node)\n        return\n\n    #rowvec\n    if node.declare.dim == 2:\n        backends.Get(node)\n        armadillo.rowvec(node)\n        return\n\n    #mat\n    if node.declare.dim == 3:\n        backends.Get(node)\n        armadillo.mat(node)\n        return\n\n    #cube\n    if node.declare.dim == 4:\n        backends.Get(node)\n        armadillo.cube(node)\n        return\n    \n    if node.parent.cls == \"Assign\":\n        node.declare.suggest = node.parent[1].type\n\n    if node.declare.type != \"TYPE\":\n        node.type = node.declare.type\n        \n    \ndef Fvar(node):\n\n    if node.parent.cls == \"Assign\" and node.parent[0] is node:\n        node.declare.suggest = node.parent[1].type\n\n    if node.declare.type != \"TYPE\":\n        node.type = node.declare.type\n\ndef Fset(node):\n\n    if node.parent.cls == \"Assign\":\n        node.declare.suggest = node.parent[1].type\n\n    if node.declare.type != \"TYPE\":\n        node.type = node.declare.type\n\ndef Sset(node):\n\n    if node.parent.cls == \"Assign\":\n        node.declare.suggest = node.parent[1].type\n\n    if node.declare.type != \"TYPE\":\n        node.type = node.declare.type\n\n\ndef Assign(node):\n    if node[1].type == \"TYPE\":\n        return\n    node.type = node[1].type\n    # node[0].declare.suggest = node[1].type\n\n\ndef Vector(node):\n\n    # default to common denominator\n    node.type = [n.type for n in node]\n\n    # dimensionality in vector\n    dims = {n.dim for n in node}\n\n    # non-numerical elements in vector isn't addresed\n    if None in dims or [n for n in node if not n.num]:\n\n        # keep it simple of single elements\n        if len(node) == 1:\n            node.type = node[0].type\n        return\n\n    # single element in vector\n    if len(node) == 1:\n\n        if dims == {0}:\n            # holder value to determine if vector is in decomposed state\n            node.value = \"scalarsonly\"\n        else:\n            node.value = \"\"\n\n        node.dim = list(dims)[0]\n        return\n\n    # only colvecs\n    elif dims == {1}:\n        node.dim = 1\n        nodes = [str(n) for n in node]\n\n    # Decomposed row\n    if dims == {0}:\n        node.value = \"scalarsonly\"\n        node.dim = 2\n\n    # only rowvecs\n    elif dims == {2}:\n        node.dim = 2\n\n    # mix of scalars and rowvecs\n    elif dims == {0, 2}:\n        node.dim = 2\n\n    # mix of matrices and colvecs\n    elif dims in ({3}, {1, 3}):\n        node.dim = 3\n\ndef Matrix(node):\n\n    node.type = [n.type for n in node]\n\n    dims = {n.dim for n in node}\n\n    # single vector with no content\n    if len(node) == 1 and len(node[0]) == 0:\n        node.num = False\n        return\n\n    # everything on scalarsonly form\n    elif all([n.value for n in node]):\n        node.value = \"scalarsonly\"\n\n        # set dimensions\n        ax0, ax1 = len(node), len(node[0])\n        if ax0 > 1:\n            if ax1 > 1:\n                node.dim = 3#matrix\n            else:\n                node.dim = 1#rowvec\n        else:\n            if ax1 > 1:\n                node.dim = 2#colvec\n            else:\n                node.dim = 0#scalar\n\n    elif dims in ({0,1}, {1}):\n\n        # configure dimensions\n        if len(node[0])>1:\n            node.dim = 3#matrix\n        else:\n            node.dim = 1#colvec\n\n    # mix of rowvecs and matrices\n    elif dims in ({2}, {3}, {2,3}):\n\n        # configure dimensiosn\n        if dims == {2} and len(node)==1:\n            node.dim = 2#rowvec\n        else:\n            node.dim = 3#matrix\n\n\n\ndef Transpose(node):\n\n    node.type = node[0].type\n    if node[0].num:\n        if node[0].dim == 1:\n            node.dim = 2\n            return\n        elif node[0].dim == 2:\n            node.dim = 1\n            return\n\nCtranspose = Transpose\n\ndef For(node):\n    node[0].suggest = \"int\"\n    #node[0].suggest = \"uword\"\n    #index = node.parent.children.index(node)\n    #tbb = node.parent.children[index - 1].cls\n\n    #if tbb == \"Tbb_for\":\n    #    node[0].type = \"uword\"\n\ndef Neg(node):\n    node.type = node[0].type\n    if node[0].mem == 0:\n        node.mem = 1\n\n\ndef opr(node):\n    node.type = [n.type for n in node]\n\nPlus = opr\ndef Minus(node):\n    opr(node)\n    if node.mem == 0:\n        node.mem = 1\n\ndef Mul(node):\n    opr(node)\n    if \"TYPE\" in (n.type for n in node):\n        return\n    mem = max([n.mem for n in node])\n    if node[0].dim == 2 and node[1].dim == 1:\n        node.type = (0, mem)\n    elif node.dim == 1 and node[1].dim == 2:\n        node.type = (3, mem)\n\nElmul = opr\nParen = opr\ndef Exp(node):\n    opr(node)\n\n    if node.num and node.mem < 2:\n        node.mem = 3\n\ndef Elexp(node):\n    node.type = [n.type for n in node]\n\nEnd = \"int\"\nInt = \"int\"\nFloat = \"double\"\nString = \"string\"\nImag = \"cx_double\"\ndef division(node):\n    opr(node)\n    if node.num and node.mem < 2:\n        node.mem = 3\nMatrixdivision = division\nElementdivision =  division\nLeftmatrixdivision = division\nLeftelementdivition = division\n\nAll = \"uvec\"\n\ndef Colon(node):\n    # context: array argument (must always be uvec)\n    if node.group.cls in (\"Get\", \"Cget\", \"Nget\", \"Fget\", \"Sget\",\n                \"Set\", \"Cset\", \"Nset\", \"Fset\", \"Sset\") and \\\n                node.parent.backend not in (\"func_return\", \"func_returns\", \"reserved\", \"func_lambda\"):\n        node.type = \"uvec\"\n\n    else:\n\n        # context: matrix concatination\n        if node.group.cls in (\"Matrix\",) and node.group.num:\n            node.type = \"rowvec\"\n\n        # context: pass to function\n        elif node.parent.cls in (\"Get\", \"Cget\", \"Nget\", \"Fget\", \"Sget\",\n                \"Set\", \"Cset\", \"Nset\", \"Fset\", \"Sset\"):\n            node.type = \"rowvec\"\n\n        # context: assignment\n        elif node.group.cls in (\"Assign\",) and node.group[0].num:\n            node.type = \"rowvec\"\n\n        else:\n            node.type = \"rowvec\"\n\ndef Lambda(node):\n\n    # lambda function are created as full functions, but referenced to be\n    # written inline\n    lfunc = node.program[1][node.name]\n    ldeclares, lreturns, lparams, lblock = lfunc\n    lnames = lparams.names + ldeclares.names\n    expr = lblock[0][1]\n\n    # location for where lambda is created\n    func = node.func\n    declares, returns, params, block = func\n\n    # Lambda creates a local scope\n    # e.g. in expressions like '@(x) x*y'\n    # 'x' is in one scope and 'y' is in another.\n    # This little hack iterates the expression of the function in\n    # search for vars/calls etc. like 'y' and declares them with\n    # the right types.\n    nodes = [expr]\n    for node_ in nodes:\n        nodes.extend(node_[:])\n\n        # a variable\n        if node_.cls in [\"Var\", \"Cvar\", \"Fvar\",\n                \"Get\", \"Cget\", \"Fget\", \"Nget\"]:\n            name = node_.name\n\n            # not in lambda scope\n            if name not in lnames:\n\n                # defined as a parameter in function\n                if name in params.names:\n                    type = params[params.names.index(name)].type\n                    node_.type = type\n                    node_.declare.type = type\n\n                # declared in function\n                elif name in declares.names:\n                    type = declares[declares.names.index(name)].type\n                    node_.type = type\n                    node_.declare.type = type\n\n    frontend.configure(lfunc)\n    # declare list in lambda function\n    if ldeclares[\"_retval\"].type != \"TYPE\":\n        declares[node.name[1:]].type = \"func_lambda\"\n        node.parent.type = \"func_lambda\"\n        node.parent[0].type = \"func_lambda\"\n    node.type = \"func_lambda\"\n\n\ndef Assigns(node):\n    if node[-1].type != \"TYPE\":\n        node.type = node[-1].type\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/configure/frontend.py",
    "content": "\n\ndef configure(root, suggest=True, **kws):\n    \"\"\"\nconfigure backend\n\nSee also:\n    :py:func:`matlab2cpp.Builder.configure <Builder.configure>`\n    \"\"\"\n    from .. import tree\n\n    if isinstance(root, tree.Builder):\n        root = root.project\n\n    loop(root, suggest)\n    loop(root, suggest)\n\ndef loop(root, suggest):\n    from . import datatypes, backends, reserved\n\n    nodes = root.flatten(False, True, True)\n\n    while True:\n\n        # loop and configure\n        for node in nodes:\n\n            # reserved stuff\n            if node.cls + \"_\" + node.name in reserved.__dict__:\n                rule = reserved.__dict__[node.cls+\"_\"+node.name]\n                if isinstance(rule, str):\n                    node.type = rule\n                else:\n                    rule(node)\n\n            # Datatype stuff\n            if node.prop[\"type\"] != \"TYPE\":\n                pass\n\n            elif node.cls in datatypes.__dict__:\n                datatype = datatypes.__dict__[node.cls]\n                if isinstance(datatype, str):\n                    node.type = datatype\n                else:\n                    datatype(node)\n\n            # Backend stuff\n            if node.backend != \"unknown\":\n                pass\n\n            elif node.cls in backends.__dict__:\n                backend = backends.__dict__[node.cls]\n                if isinstance(backend, str):\n                    node.backend = backend\n                else:\n                    backend(node)\n\n        # determine if done\n        if suggest:\n\n            complete = True\n\n            for program in root.project:\n                \n                suggests = program.suggest\n                program.stypes = suggests\n                program.ftypes = suggests\n                complete = complete and not any([any(v) for v in suggests.values()])\n\n            if complete:\n                break\n\n        else:\n            break\n\n    # delete log, if any (create on translate)\n    for program in root.project:\n        program[-1].children = []\n"
  },
  {
    "path": "src/matlab2cpp/configure/funcs.py",
    "content": "import os\n\ndef funcs(node):\n\n    func = None\n\n    # lambda scope\n    if \"_\" + node.name in node.program[1]:\n        func = node.program[1][\"_\" + node.name]\n\n    # local scope\n    elif node in node.program[1]:\n        func = node.program[1][node]\n\n    # external file in same folder\n    else:\n\n        for program in node.project:\n\n            # don't use the file your in as external library\n            if program is node.program:\n                continue\n\n            if os.path.basename(program.name) == node.name+\".m\":\n                func = program[1][0]\n                break\n        else:\n            return False\n\n    node.backend = func.backend\n\n    if node.backend == \"func_return\":\n\n        node.backend = func.backend\n        node.declare.type = func[1][0].type\n        params = func[2]\n\n        for i in range(len(node)):\n            try:\n                params[i].suggest = node[i].type\n                node[i].suggest = params[i].type\n            except:\n                pass\n\n    elif node.backend == \"func_returns\":\n        node.backend = func.backend\n        params = func[2]\n\n        for j in range(len(params)):\n            try:\n                params[j].suggest = node[j].type\n                node[j].suggest = params[j].type\n            except:\n                pass\n\n        if node.parent.cls == \"Assigns\":\n            # node.parent.backend = \"func_returns\"\n\n            returns = func[1]\n            # Got out_of_bounds error, len(returns) where longer than LHS,\n            # so i changed for range to min LHS vars and returns from function\n            for j in range(min(len(node.parent), len(returns))):\n                returns[j].suggest = node.parent[j].type\n                node.parent[j].suggest = returns[j].type\n\n    elif node.backend == \"func_lambda\":\n\n        ret = func[1][0]\n        node.suggest = ret.type\n        ret.suggest = node.type\n        if node.type != \"TYPE\":\n            node.declare.type = \"func_lambda\"\n\n        params = func[2]\n        for i in range(len(node)):\n            params[i].suggest = node[i].type\n\n    return True\n\n"
  },
  {
    "path": "src/matlab2cpp/configure/reserved.py",
    "content": "Var_false = \"int\"\nVar_true = \"int\"\nVar_pi = \"double\"\nGet_linspace = \"rowvec\"\n\ndef Get_exp(node):\n    node.type = node[0].type\n\ndef Get_log(node):\n    node.type = node[0].type\n\ndef Get_log2(node):\n    node.type = node[0].type\n\ndef Get_log10(node):\n    node.type = node[0].type\n\ndef Get_power(node):\n    node.type = node[0].type\n\ndef Get_floor(node):\n    node.type = node[0].type\n\ndef Get_ceil(node):\n    node.type = node[0].type\n\ndef Get_fix(node):\n    node.type = node[0].type\n\ndef Get_round(node):\n    if len(node) == 1:\n        #int, float, double, uword\n        if node[0].dim == 0 and node[0].mem != 4:\n            node.type = \"double\"\n        #arma types\n        elif node[0].dim != 0:\n            node.type = node[0].type\n\ndef Get_cos(node):\n    node.type = node[0].type\n\ndef Get_acos(node):\n    node.type = node[0].type\n\ndef Get_cosh(node):\n    node.type = node[0].type\n\ndef Get_acosh(node):\n    node.type = node[0].type\n\ndef Get_sin(node):\n    node.type = node[0].type\n\ndef Get_asin(node):\n    node.type = node[0].type\n\ndef Get_sinh(node):\n    node.type = node[0].type\n\ndef Get_asinh(node):\n    node.type = node[0].type\n\ndef Get_sqrt(node):\n    #if len(node) > 0 ...\n    if len(node) and node[0].cls == \"Neg\":\n        node.type = \"cx_double\"\n    elif len(node):\n        node.type = node[0].type\n\ndef Get_mod(node):\n    node.type = node[0].type\n\ndef Get_abs(node):\n    if node[0].type in (\"cx_double\", \"cx_mat\"):\n        node.type = \"mat\"\n    else:\n        node.type = node[0].type\n\ndef Get_tic(node):\n    node.type = \"double\"\n\ndef Assign_tic(node):\n    node[0].declare.type = \"double\"\n    node[0].type = \"double\"\n\ndef Get_toc(node):\n    node.type = \"double\"\n\ndef Assign_toc(node):\n    node[0].declare.type = \"double\"\n    node[0].type = \"double\"\n\ndef Get_any(node):\n    if not node[0].num:\n        return\n\n    node.type = node[0].type\n\n    # colvec or rowvec\n    if node.dim in (1,2):\n        node.dim = 0\n\n    # matrix\n    elif node.dim == 3:\n\n        # axis input decides by second input\n        if len(node) == 2:\n\n            if  node[1].cls == \"Int\":\n                val = node[1].value\n                if val == \"1\":\n                    node.dim = 2\n                elif val == \"2\":\n                    node.dim = 1\n\n            # problem if arg not explicit\n            else:\n                node.num = False\n\n    # cube\n    else:\n        node.dim = 3\n\nGet_all = Get_any\n\nGet_isequal = \"int\"\n\ndef Get_size(node):\n\n    # unknown input\n    if node[0].type == \"TYPE\" or node.parent.cls == \"Assigns\":\n        return\n\n    var = str(node[0])\n\n    # multiple args\n    if len(node) > 1:\n        \n        # determine ax from second arg\n        node.type = \"uword\"\n\n    # colvec or rowvec\n    elif node[0].dim in (1,2):\n        \"\"\"\n        if node.parent.backend == \"reserved\" and\\\n          node.parent.name in (\"min\", \"max\"):\n            node.type = \"uword\"\n            return\n        if len(node) == 1:\n            node.type = \"urowvec\"\n            return\n        node.type = \"uword\"\n        \"\"\"\n        \n        node.type = \"urowvec\"\n\n        if node.parent.backend == \"reserved\" and\\\n          node.parent.name in (\"min\", \"max\"):\n            node.type = \"uword\"\n            return\n        if len(node) == 1:\n            node.type = \"urowvec\"\n            return\n\n        if node.parent.cls == \"Get\":\n            return\n\n        # inline calls moved to own line\n        if node.parent.cls not in (\"Statement\", \"Assign\"):\n            return\n\n        node.parent.backend = \"reserved\"\n        node.parent.name = \"size\"\n        \n    # matrix (returns two values)\n    elif node[0].dim == 3:\n        node.type = \"urowvec\"\n\n        if node.parent.backend == \"reserved\" and\\\n          node.parent.name in (\"min\", \"max\"):\n            node.type = \"uword\"\n            return\n\n        if node.parent.cls == \"Get\":\n            return\n\n        # inline calls moved to own line\n        if node.parent.cls not in (\"Statement\", \"Assign\"):\n            return\n\n        node.parent.backend = \"reserved\"\n        node.parent.name = \"size\"\n\n    # cube (return three values)\n    elif node[0].dim == 4:\n        node.type = \"urowvec\"\n\n        if node.parent.cls == \"Get\":\n            return\n\n        # inline calls moved to own line\n        if node.parent.cls not in (\"Statement\", \"Assign\"):\n            return\n\n        node.parent.backend = \"reserved\"\n        node.parent.name = \"size\"\n\ndef Assigns_size(node):\n\n    # suggest some types for matrix\n    if len(node)==3:\n        node[0].suggest = \"int\"\n        node[1].suggest = \"int\"\n\n    # suggest some types for cube\n    if len(node)==4:\n\n        node[0].suggest = \"int\"\n        node[1].suggest = \"int\"\n        node[2].suggest = \"int\"\n\ndef Get_length(node):\n    node.type = \"uword\"\n\ndef Get_min(node):\n\n    # everything scalar\n    if not all([n.num for n in node]) or  all([(n.dim < 1) for n in node]):\n        if any([n.mem == 4 for n in node]):\n            node.type = \"cx_mat\"\n        return\n\n    node.type = node[0].type\n\n    # single arg\n    if len(node) == 1:\n\n        # determine node dimensions\n        if node.dim == 2:\n            node.dim = 0\n        else:\n            node.dim = node.dim-1\n\n    # three args\n    if len(node) == 3:\n        if node[2].dim == 0:\n\n            # assues third arg is int and sets axis\n            val = node[2].value\n            if val == \"1\":\n                node.dim = 2\n            elif val == \"2\":\n                node.dim = 1\n            else:\n                node.num = False\n            \ndef Assigns_min(node):\n    assert len(node) == 3\n\n    var = node[2][0]\n\n    # non-numerical assignment\n    if not var.num:\n        pass\n    else:\n        node[0].suggest = (0, var.mem)\n        node[1].suggest = \"int\"\n\nGet_max = Get_min\n\ndef Assigns_max(node):\n    assert len(node) == 3\n\n    # right hand side of assignment\n    var = node[-1]\n\n    # non-numerical input\n    if not var.num:\n        pass\n    else:\n        node[0].suggest = (0, var.mem)\n        node[1].suggest = \"int\"\n\ndef Get_fliplr(node):\n    if len(node) > 0:\n        node.type = node[0].type\n\ndef Get_flipud(node):\n    if len(node) > 0:\n        node.type = node[0].type\n\ndef Get_eye(node):\n    #set eye type to cx_mat if LHS is complex type\n    if node.group.cls == \"Assign\" and node.group[0].mem == 4:\n        node.type = \"cx_mat\"\n    else:\n        node.type = \"mat\"\n    \ndef Get_diag(node):\n    if len(node) > 0:\n        if node[0].dim == 3:\n            node.type = (1, node[0].mem)\n        elif node[0].dim in (1, 2):\n            node.type = (3, node[0].mem)\n\ndef Get_tril(node):\n    if node[0].mem:\n        node.type = (3, node[0].mem)\n\ndef Get_triu(node):\n    if node[0].mem:\n        node.type = (3, node[0].mem)\n        \nVar_eye = Get_eye\n\ndef Get_trace(node):\n    node.type = node[0].type\n\ndef Get_transpose(node):\n    \"\"\"Simple transpose\n    \"\"\"\n\n    # colvec -> rowvec \n    if node[0].dim == 1:\n        node.type = (2, node[0].mem)\n\n    # rowvec -> colvec\n    elif node[0].dim == 2:\n        node.type = (1, node[0].mem)\n\n    else:\n        node.type = node[0].type\n    \ndef Get_ctranspose(node):\n    \"\"\"Complex transpose\n    \"\"\"\n\n    # colvec -> rowvec \n    if node[0].dim == 1:\n        node.type = (2, node[0].mem)\n\n    # rowvec -> colvec\n    elif node[0].dim == 2:\n        node.type = (1, node[0].mem)\n\n    else:\n        node.type = node[0].type\n\ndef Get_zeros(node):\n\n    node.type = \"uword\"\n    dim, mem = node.suggest_datatype()\n    \n    # set memory type\n    if not (mem is None):\n        node.mem = mem\n    else:\n        node.mem = 3\n\n    #if node.group.cls == \"Matrix\" and node.group.group.cls == \"Assign\" and len(node.group.group) == 2:\n    #    if node.group.group[0].mem == 4:\n    #        node.mem = 4\n\n    # reset to uword if arg of array-node\n    if node.group.cls in (\"Get\", \"Cget\", \"Fget\", \"Nget\", \"Sget\", \"Set\", \"Cset\",\n            \"Fset\", \"Nset\", \"Sset\") and node.group.num:\n        node.mem = 0\n        if len(node) == 2 and node[0].cls == \"Int\" and node[0].value == \"1\":\n            node.dim = 1\n            return\n    \n    # one argument\n    if len(node) == 1:\n        \n        # arg input is vector\n        if node[0].num and node[0].dim in (1,2):\n            pass\n\n        else:\n\n            # use suggestions or defualts\n            if dim in (1,2,3):\n                node.dim = dim\n            else:\n                node.dim = 3 # default\n\n    # double argument creates colvec/rowvec/matrix depending on context\n    elif len(node) == 2:\n\n        # use matrix, if suggested\n        if dim == 3:\n            node.dim = 3\n\n        # use colvec if first index is '1'\n        elif node[0].cls == \"Int\" and node[0].value == \"1\":\n            node.dim = 2\n\n        # use rowvec if second index is '1'\n        elif node[1].cls == \"Int\" and node[1].value == \"1\":\n            node.dim = 1\n\n        # default to matrix\n        else:\n            node.dim = 3\n\n    # triple arg create cube\n    elif len(node) == 3:\n        node.dim = 4\n\nGet_ones = Get_zeros\n\nVar_rand = \"vec\"\n\ndef Get_rand(node):\n\n    # Get type from left hand side of assignment\n    if node.group.cls == \"Assign\":\n        if node.group[0].type != \"TYPE\":\n            node.type = node.group[0].type\n            return\n\n    # one arg\n    if len(node) == 1:\n        node.type = \"vec\"\n\n    # two args\n    elif len(node) == 2:\n        node.type = \"mat\"\n\n    # three args -> cube\n    elif len(node) == 3:\n        node.type = \"cube\"\n\ndef Get_reshape(node):\n    if node[0].mem:\n        node.type = (3, node[0].mem)\n\ndef Get_nextpow2(node):\n    node.type = \"int\"\n    \ndef Get_fft(node):\n\n    node.type = node[0].type\n    if node.type != 'TYPE':\n        node.mem = 4\n    #if node.mem == 4:\n    #    node.mem = 4\n    #elif node.mem == 3:\n    #    node.mem = 4\n\ndef Get_ifft(node):\n\n    #assert(node[0].mem == 4)\n    node.type = node[0].type\n    if node.type != 'TYPE':\n        node.mem = 4\n\n    #if node.mem == 4:\n    #    node.mem = 3\n    #elif node.mem == 3:\n    #    node.mem = 3\n\n    # unknown input\n    #if not node.num:\n    #    pass\n    #else:\n    #    node.mem = 4\n\n\ndef Get_interp1(node):\n    if len(node):\n        node.type = node[0].type\n\ndef Get_sum(node):\n\n    arg = node[0]\n\n    # unknown input\n    if not arg.num or arg.dim == 0:\n        return\n\n    node.type = arg.type\n\n    # determine output dimensions\n    if arg.dim == 2:\n        dim = 0\n    elif arg.dim == 3:\n        # sum along an axis\n        if len(node) == 2 and node[1].cls == \"Int\" and node[1].value == \"2\":\n            dim = 1\n        else:\n            dim = 2\n    else:\n        if arg.dim == 3:\n            dim = 2\n        elif arg.dim == 2:\n            arg.dim == 0\n        else:\n            dim = arg.dim-1\n    node.dim = dim\n\ndef Get_cumsum(node):\n    node.type = node[0].type\n\ndef Get_conj(node):\n    node.type = node[0].type\n\ndef Get_real(node):\n    if node[0].dim:\n        node.type = (node[0].dim, 3)\n    #arg = node[0]\n    #\n    # output always real\n    #if arg.mem:\n    #    node.type = (3, arg.mem)\n\ndef Get_convmtx(node):\n    node.type = node[0].type\n\ndef Get_conv2(node):\n    node.type = [node[0].type, node[1].type]\n\ndef Get_logspace(node):\n    node.type = \"rowvec\"\n\ndef Get_find(node):\n    node.type = \"uvec\"\n\nGet_tic = \"string\"\n\nGet_toc = \"string\"\n"
  },
  {
    "path": "src/matlab2cpp/datatype.py",
    "content": "\"\"\"\nThe follwing constructor classes exists here:\n\n+------------------------------------------+---------------------------------------+\n| Class                                    | Description                           |\n+==========================================+=======================================+\n| :py:class:`~matlab2cpp.datatype.Type`    | Frontend for the datatype string      |\n+------------------------------------------+---------------------------------------+\n| :py:class:`~matlab2cpp.datatype.Dim`     | Reference to the number of dimensions |\n+------------------------------------------+---------------------------------------+\n| :py:class:`~matlab2cpp.datatype.Mem`     | Reference to the memory type          |\n+------------------------------------------+---------------------------------------+\n| :py:class:`~matlab2cpp.datatype.Num`     | Numerical value indicator             |\n+------------------------------------------+---------------------------------------+\n| :py:class:`~matlab2cpp.datatype.Suggest` | Frontend for suggested datatype       |\n+------------------------------------------+---------------------------------------+\n\"\"\"\nfrom . import supplement\n\n\ndim0 = {\"int\", \"float\", \"uword\", \"double\", \"cx_double\", \"size_t\"}\ndim1 = {\"ivec\", \"fvec\", \"uvec\", \"vec\", \"cx_vec\"}\ndim2 = {\"irowvec\", \"frowvec\", \"urowvec\", \"rowvec\", \"cx_rowvec\"}\ndim3 = {\"imat\", \"fmat\", \"umat\", \"mat\", \"cx_mat\"}\ndim4 = {\"icube\", \"fcube\", \"ucube\", \"cube\", \"cx_cube\"}\n\ndims = [dim0, dim1, dim2, dim3, dim4]\n\nmem0 = {\"uword\", \"uvec\", \"urowvec\", \"umat\", \"ucube\"}\nmem1 = {\"int\", \"ivec\", \"irowvec\", \"imat\", \"icube\"}\nmem2 = {\"float\", \"fvec\", \"frowvec\", \"fmat\", \"fcube\"}\nmem3 = {\"double\", \"vec\", \"rowvec\", \"mat\", \"cube\"}\nmem4 = {\"cx_double\", \"cx_vec\", \"cx_rowvec\", \"cx_mat\", \"cx_cube\"}\n\nmems = [mem0, mem1, mem2, mem3, mem4]\n\nothers = {\"char\", \"string\", \"TYPE\", \"func_lambda\", \"struct\", \"structs\", \"cell\",\n        \"wall_clock\", \"SPlot\"}\n\n\ndef common_loose(vals):\n    \"\"\"Common denominator among several names.\nLoose enforcment\"\"\"\n\n    if not isinstance(vals, (tuple, list)) or \\\n            isinstance(vals[0], int):\n        vals = [vals]\n    vals = list(vals)\n\n    for i in range(len(vals)):\n        if isinstance(vals[i], str):\n            continue\n        if isinstance(vals[i][0], int):\n            vals[i] = get_name(*vals[i])\n\n    vals = set(vals)\n\n    if len(vals) == 1:\n        return vals.pop()\n\n    vals.discard(\"TYPE\")\n\n    if len(vals) == 1:\n        return vals.pop()\n\n    for other in others:\n        vals.discard(other)\n\n    if len(vals) == 0:\n        return \"TYPE\"\n    elif len(vals) == 1:\n        return vals.pop()\n\n    dims_ = map(get_dim, vals)\n    if dims_:\n        dim = max(*dims_)\n    else:\n        return \"TYPE\"\n    if dim == 2 and 1 in dims_:\n        dim = 3\n\n    types = map(get_mem, vals)\n    type = max(*types)\n\n    val = get_name(dim, type)\n    return val\n\n\ndef common_strict(vals):\n    \"\"\"Common denominator among several names.\nStrict enforcment\"\"\"\n\n    if not isinstance(vals, (tuple, list)) \\\n            or isinstance(vals[0], int):\n        vals = [vals]\n\n    vals = list(vals)\n\n    for i in range(len(vals)):\n        if isinstance(vals[i], str):\n            continue\n        if isinstance(vals[i][0], int):\n            vals[i] = get_name(*vals[i])\n\n    vals = set(vals)\n\n    if len(vals) == 1:\n        return vals.pop()\n\n    for other in others:\n        if other in vals:\n            return \"TYPE\"\n\n    dims_ = map(get_dim, vals)\n    dim = max(*dims_)\n    if dim == 2 and 1 in dims_:\n        return \"TYPE\"\n\n    types = map(get_mem, vals)\n    type = max(*types)\n\n    val = get_name(dim, type)\n    return val\n\ndef pointer_split(name):\n    p = name.count(\"*\")\n    if not p:\n        return 0, name\n    return p, name[:-p]\n\n\ndef get_dim(val):\n\n    while val[-1] == \"*\":\n        val = val[:-1]\n\n    if val in dim0:     dim = 0\n    elif val in dim1:   dim = 1\n    elif val in dim2:   dim = 2\n    elif val in dim3:   dim = 3\n    elif val in dim4:   dim = 4\n    elif val in others: dim = None\n    else:\n        raise ValueError(\"Datatype '%s' not recognized\" % val)\n    return dim\n\n\ndef get_mem(val):\n\n    while val[-1] == \"*\":\n        val = val[:-1]\n\n    if val in mem0:    mem = 0\n    elif val in mem1:  mem = 1\n    elif val in mem2:  mem = 2\n    elif val in mem3:  mem = 3\n    elif val in mem4:  mem = 4\n    elif val in others: mem = None\n    else:\n        raise ValueError(\"Datatype '%s' not recognized\" % val)\n\n    return mem\n\ndef get_num(val):\n\n    while val[-1] == \"*\":\n        val = val[:-1]\n\n    if val in others:   num = False\n    else:               num = True\n\n    return num\n\n\ndef get_name(dim, mem):\n    return dims[dim].intersection(mems[mem]).pop()\n\n\ndef get_type(instance):\n\n    if instance.prop[\"type\"] == \"TYPE\":\n        instance = instance.declare\n    return instance.prop[\"type\"]\n\nclass Dim(object):\n    \"\"\"\nThe `node.dim` is a help variable for handling numerical datatype.\nIt represents the number of dimension a numerical object represents:\n\n+-------+--------------+\n| *dim* | Description  |\n+=======+==============+\n| 0     | scalar       |\n+-------+--------------+\n| 1     | (col-)vector |\n+-------+--------------+\n| 2     | row-vector   |\n+-------+--------------+\n| 3     | matrix       |\n+-------+--------------+\n| 4     | cube         |\n+-------+--------------+\n| None  | Other        |\n+-------+--------------+\n\nThe variable can be both read and set in real time:\n\n    >>> node = collection.Var(None, \"name\")\n    >>> node.type=\"float\"\n    >>> print(node.dim)\n    0\n    >>> node.dim = 3\n    >>> print(node.type)\n    fmat\n    \"\"\"\n\n    def __get__(self, instance, owner):\n        if instance is None:\n            return self\n        return get_dim(get_type(instance))\n\n    def __set__(self, instance, value):\n        mem = get_mem(get_type(instance))\n        instance.prop[\"type\"] = get_name(value, mem)\n\n\nclass Mem(object):\n    \"\"\"\nThe `node.mem` is a help variable for handling numerical datatype.\nIt represents the internal basic datatype represented in memory:\n\n+-------+-------------+\n| *mem* | Description |\n+=======+=============+\n| 0     | unsiged int |\n+-------+-------------+\n| 1     | integer     |\n+-------+-------------+\n| 2     | float       |\n+-------+-------------+\n| 3     | double      |\n+-------+-------------+\n| 4     | complex     |\n+-------+-------------+\n| None  | Other       |\n+-------+-------------+\n\nThe variable can be both read and set in real time:\n\n    >>> node = collection.Var(None, \"name\")\n    >>> node.type=\"float\"\n    >>> print(node.mem)\n    2\n    >>> node.mem = 3\n    >>> print(node.type)\n    double\n    \"\"\"\n\n    def __get__(self, instance, owner):\n        if instance is None:\n            return self\n        return get_mem(get_type(instance))\n\n    def __set__(self, instance, value):\n        dim = get_dim(get_type(instance))\n        instance.prop[\"type\"] = get_name(dim, value)\n\n\nclass Num(object):\n    \"\"\"\nThe `node.num` is a help variable for handling numerical datatype.  It is\na boolean values which is true given that the datatype is of numerical type.\n    \"\"\"\n\n    def __get__(self, instance, owner):\n        if instance is None:\n            return self\n        return get_num(get_type(instance))\n\n    def __set__(self, instance, value):\n        if not value:\n            instance.prop[\"type\"] = \"TYPE\"\n        else:\n            raise AttributeError(\"num can not be set True consistently\")\n\n\nclass Type(object):\n    \"\"\"\nDatatypes can be roughly split into two groups: **numerical** and\n**non-numerical** types.  The numerical types are as follows:\n\n+-------------+--------------+-----------+-----------+----------+-------------+\n|             | unsigned int | int       | float     | double   | complex     |\n+=============+==============+===========+===========+==========+=============+\n| scalar      | *uword*      | *int*     | *float*   | *double* | *cx_double* |\n+-------------+--------------+-----------+-----------+----------+-------------+\n| vector      | *uvec*       | *ivec*    | *fvec*    | *vec*    | *cx_vec*    |\n+-------------+--------------+-----------+-----------+----------+-------------+\n| row\\-vector | *urowvec*    | *irowvec* | *frowvec* | *rowvec* | *cx_rowvec* |\n+-------------+--------------+-----------+-----------+----------+-------------+\n| matrix      | *umat*       | *imat*    | *fmat*    | *mat*    | *cx_mat*    |\n+-------------+--------------+-----------+-----------+----------+-------------+\n| cube        | *ucube*      | *icube*   | *fcube*   | *cube*   | *cx_cube*   |\n+-------------+--------------+-----------+-----------+----------+-------------+\n\nValues along the horizontal axis represents the amount of memory reserved per\nelement, and the along the vertical axis represents the various number of\ndimensions.  The names are equivalent to the ones in the Armadillo package.\n\nThe non-numerical types are as follows:\n\n+---------------+------------------------+\n| Name          | Description            |\n+===============+========================+\n| *char*        | Single text character  |\n+---------------+------------------------+\n| *string*      | Text string            |\n+---------------+------------------------+\n| *struct*      | Struct container       |\n+---------------+------------------------+\n| *structs*     | Struct array container |\n+---------------+------------------------+\n| *func_lambda* | Anonymous function     |\n+---------------+------------------------+\n\nThe node datatype can be referenced by any node through `node.type` and can be\ninserted as placeholder through `%(type)s`.\n    \"\"\"\n\n    def __get__(self, instance, owner):\n        if instance is None:\n            return self\n        return get_type(instance)\n\n    def __set__(self, instance, value):\n        value = value or \"TYPE\"\n        if isinstance(value, str):\n            p, value = pointer_split(value)\n            instance.pointer = p\n        else:\n            value = common_strict(value)\n        instance.prop[\"type\"] = value\n\n\nclass Suggest(object):\n    \"\"\"Same as Type, but for suggested value.\n    \"\"\"\n\n    def __set__(self, instance, value):\n        if value == \"TYPE\":\n            return\n        instance.declare.prop[\"suggest\"] = value\n    def __get__(self, instance, owner):\n        return supplement.suggests.get(instance)\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/frontend.py",
    "content": "\"\"\"Execute main parser.\"\"\"\nimport time\nfrom datetime import datetime as date\nimport os\nfrom os.path import sep\nimport imp\n\nfrom . import supplement, tree, qfunctions, modify, setpaths\nfrom .__init__ import __version__\n\n\ndef execute_parser(args):\n    \"\"\"\nInitiate the interpretation and conversion process.\n\nArgs:\n    args (ArgumentParser): arguments parsed through m2cpp\n    \"\"\"\n\n    builder = tree.builder.Builder(\n        disp=args.disp,\n        comments=args.comments,\n        original=args.original,\n        enable_omp=args.enable_omp,\n        enable_tbb=args.enable_tbb,\n        reference=args.reference,\n    )\n\n    paths_from_file = []\n    #read setpath.m file and return string list of paths\n    if args.paths_file:\n        if os.path.isfile(args.paths_file):\n            paths_from_file = setpaths.multiple_folder_paths(args.paths_file)\n        else:\n            raise IOError(\"File '\" + args.paths_file + \"' not found\")\n\n    #pathOne = os.path.dirname(os.path.abspath(args.filename))\n\n    if os.path.isfile(args.filename):\n\n        paths = [os.path.abspath(os.path.dirname(args.filename))]\n        paths += paths_from_file\n\n        if args.disp:\n            print(\"building tree...\")\n\n        filenames = [os.path.abspath(args.filename)]\n\n        stack = []\n        while filenames:\n\n            filename = filenames.pop(0)\n            assert os.path.isfile(filename)\n\n            if filename in stack:\n                continue\n\n            if args.disp:\n                print(\"loading\", filename)\n\n            stack.append(filename)\n\n            f = open(filename, \"rU\")\n            code = f.read()\n            f.close()\n\n            #code = re.sub('%#', '##', code)\n\n            #Here you have to change filename to current folder for .py files\n            #local_name = pathOne + sep + os.path.basename(filename)\n            local_name = os.getcwd() + sep + os.path.basename(filename)\n\n            if os.path.isfile(local_name + \".py\") and not args.reset:\n\n                try:\n                    cfg = imp.load_source(\"cfg\", local_name + \".py\")\n\n                except:\n                    raise ImportError(\"\"\"Supplement file:\n    %s.py\n    is formated incorrectly. Change the format or convert with '-r' option to create\n    a new file.\"\"\" % local_name)\n\n                if \"verbatims\" in cfg.__dict__ and cfg.verbatims:\n                    verbatims = cfg.verbatims\n                    code = supplement.verbatim.set(verbatims, code)\n\n                builder.load(filename, code)\n                program = builder[-1]\n\n                if \"functions\" in cfg.__dict__:\n\n                    funcs = program.ftypes\n\n                    for name in funcs.keys():\n                        if name in cfg.functions:\n                            for key in cfg.functions[name].keys():\n                                funcs[name][key] = cfg.functions[name][key]\n\n                    program.ftypes = funcs\n\n                if \"structs\" in cfg.__dict__:\n\n                    structs = program.stypes\n\n                    for name in structs.keys():\n                        if name in cfg.structs:\n                            for key in cfg.structs[name].keys():\n                                structs[name][key] = cfg.structs[name][key]\n\n                    program.stypes = structs\n\n                if \"includes\" in cfg.__dict__:\n\n                    includes = program.itypes\n\n                    for key in cfg.includes:\n                        if key not in includes:\n                            includes.append(key)\n\n                    includes = [i for i in includes if supplement.includes.write_to_includes(i)]\n\n                    program.itypes = includes\n\n            else:\n                builder.load(filename, code)\n                program = builder[-1]\n\n            # add unknown variables to stack if they exists as files\n            unknowns = builder.get_unknowns(filename)\n\n            for i in range(len(unknowns)-1, -1, -1):\n                #print(i)\n                for path in paths:\n                    #print(path)\n                    if os.path.isfile(path + sep + unknowns[i] + \".m\"):\n                        unknowns[i] = unknowns[i] + \".m\"\n                    if os.path.isfile(path + sep + unknowns[i]):\n                        program.include(path + sep + unknowns[i])\n                        #filenames.append(path + sep + unknowns.pop(i))\n                        filenames.append(path + sep + unknowns[i])\n\n\n    else:\n        builder.load(\"unnamed\", args.filename)\n        program = builder[-1]\n\n    #--- work in progress ---\n    #Run this mlabwrap code\n    #Have this in a try-except block\n    #import mwrapmat\n    #wrapmat = mwrapmat.Wrapmat()\n    #wrapmat.eval_code(builder)\n    #------------------------\n\n    #--- work in progress ---\n    #Get data types from matlab\n    if args.matlab_suggest:\n        from . import matlab_types\n        builder = matlab_types.mtypes(builder, args)\n    #------------------------\n\n    if args.disp:\n        print(\"configure tree\")\n\n    builder.configure(suggest=(2*args.suggest or args.matlab_suggest))\n\n    #--- work in progress ---\n    #Modify the Abstract Syntax Tree (AST)\n    builder.project = modify.preorder_transform_AST(\n        builder.project, args.nargin,\n        suggest=(2*args.suggest or args.matlab_suggest),\n    )\n    #------------------------\n\n    if args.disp:\n        print(builder.project.summary())\n        print(\"generate translation\")\n\n    builder.project.translate(args)\n\n    #post order modify project\n    builder.project = modify.postorder_transform_AST(builder.project)\n\n    t = time.time()\n    stamp = date.fromtimestamp(t).strftime('%Y-%m-%d %H:%M:%S')\n\n    for program in builder.project:\n\n        #name = program.name\n        #if os.path.isfile(args.filename):\n        #    name = pathOne + sep + os.path.basename(name)\n            #print(name)\n        name = os.getcwd() + sep + os.path.basename(program.name)\n        #print(name)\n\n        cpp = qfunctions.qcpp(program)\n        hpp = qfunctions.qhpp(program)\n        py = qfunctions.qpy(program, prefix=True)\n        log = qfunctions.qlog(program)\n\n        if args.disp:\n            print(\"Writing files...\")\n\n        if args.reset:\n            for ext in [\".cpp\", \".hpp\", \".log\", \".py\"]:\n                if os.path.isfile(name+ext):\n                    os.remove(name+ext)\n\n        if cpp:\n            cpp = \"\"\"// Automatically translated using m2cpp %s on %s\n\n%s\"\"\" % (__version__, stamp, cpp)\n            f = open(name+\".cpp\", \"w\")\n            f.write(cpp)\n            f.close()\n\n        if hpp:\n            hpp = \"\"\"// Automatically translated using m2cpp %s on %s\n\n%s\"\"\" % (__version__, stamp, hpp)\n            f = open(name+\".hpp\", \"w\")\n            f.write(hpp)\n            f.close()\n\n        if log:\n            log = \"Automatically translated using m2cpp %s on %s\\n\\n%s\"\\\n                    % (__version__, stamp, log)\n            f = open(name+\".log\", \"w\")\n            f.write(log)\n            f.close()\n\n        if py:\n            py = \"\"\"# Automatically translated using m2cpp %s on %s\n#\n%s\"\"\" % (__version__, stamp, py)\n            f = open(name+\".py\", \"w\")\n            f.write(py)\n            f.close()\n\n        if os.path.isfile(name+\".pyc\"):\n            os.remove(name+\".pyc\")\n\n\n    program = builder[0]\n\n    if args.tree_full:\n        print(program.summary(args))\n\n    elif args.tree:\n        if program[1][0].cls == \"Main\":\n            print(program[1][0][3].summary(args))\n        else:\n            print(program[1].summary(args))\n\n    elif args.line:\n        nodes = program[1].flatten(False, False, False)\n        for node_ in nodes:\n            if node_.line == args.line and node_.cls != \"Block\":\n                print(node_.str.replace(\"__percent__\", \"%\"))\n                break\n    else:\n        print(program[1].str.replace(\"__percent__\", \"%\"))\n"
  },
  {
    "path": "src/matlab2cpp/manual/__init__.py",
    "content": "\"\"\"\nSource files for the manual.\n\nPlaced here so that doctest might pick up on them.\n\"\"\"\n\n#import usr00_introduction\nfrom . import usr01_interaction, usr02_datatype, usr03_rules, usr04_node\n"
  },
  {
    "path": "src/matlab2cpp/manual/usr00_introduction.py",
    "content": "\"\"\"\n.. _usr00:\n\nMatlab2cpp is a semi-automatic tool for converting code from Matlab to C++. matlab2cpp is written in Python and is a Python module. Installing the Matlab2cpp module, makes the module available in Python as a module and can be loaded with \"import matlab2cpp\". In addition to the module, the script \"m2cpp is copied to a folder on the system so that it can be executed by typing \"m2cpp\" in the terminal (Windows: cmd, cygwin). The \"m2cpp\" is a small script to handle the input arguments which are then used by the functionality in the module Matlab2cpp.\n\nNote that Matlab2cpp/m2cpp is not meant as a complete tool for creating runnable C++ code.\nFor example, the `eval`-function can not be supported because there is no\ngeneral way to implement it in C++.  Instead the program is aimed as a support\ntool, which aims at speed up the conversion process as much as possible for\na user that needs to convert Matlab programs by hand anyway. The software does\nthis by converting the basic structures of the Matlab-program (functions,\nbranches, loops, etc.), adds variable declarations, and for some simple code, do\na complete translation. From there manual conversions can be\ndone by hand.\n\nMatlab2cpp generate C++ code that relies on the linear algebra library Armadillo (http://arma.sourceforge.net/). So while Armadillo isn't required to generate the C++ code, Armadillo is required to compile the program.  Armadillo's API is quite similar to Matlab and cover some of Matlab's functionaliy. Matlab2cpp aims to correctly translate Matlab to the corresponding C++ Armadillo code. Currently, the code will not convert the large library collection of functions\nthat Matlab currently possesses. However, there is no reason for the code not\nto support more of these features in time.\n\n\"\"\"\n"
  },
  {
    "path": "src/matlab2cpp/manual/usr01_interaction.py",
    "content": "\"\"\"\n.. _usr01:\n\nUser interaction\n================\n\nThe simplest way to interact with the `Matlab2cpp`-toolbox is to use the\n`m2cpp` frontend.  The script automatically creates files with various\nextensions containing translations and/or meta-information.\n\n.. autoprogram:: m2cpp:parser\n    :prog: m2cpp\n\nFor the user, the flags -o, -c, -s, -S, -r, -p -omp, -tbb are the useful flags.\nThe flags -t, -T  are good for debugging because they print the structure of the \nAbstract Syntax Tree (AST). The -d flag gives useful\ninformation on the parsing of the Matlab code and insight in how the AST is built.\n\nSuggest flags, -s, -S\n---------------------\n\nRead the section :ref:`usr02_suggestion_engine` first.\nWhen using m2cpp the corresponding suggest is set with the flag -s. The suggest\nengine works well for simple cases. For more complex cases, not all the variables\nget a type suggestion and the suggested type could be wrong. \n\nThe other suggest flag -S get the datatypes by running the (Matlab) code with Matlab.\nInformation of the datatypes are written to files which can be extracted by the code \ntranslator. For this flag to work, in addition to having Matlab installed, the Matlab \nEngine API for Python has to be installed\n(see: `Install MATLAB Engine API for Python <http://se.mathworks.com/help/matlab/matlab_external/install-the-matlab-engine-for-python.html>`_).\nMatlab has to be able to run the code to extract the datatypes. So if the code\nrequire datafiles or special Matlab modules (e.g. numerical modules),\nthese have to be available for this option to work. The Matlab suggest option is not 100%,\nbut still quite good at suggesting datatypes. A downside with the using Matlab to suggest\ndatatypes, is that Matlab takes some time to start up and then run the (Matlab) code.\n\nMultiple directories, -p paths_file\n-----------------------------------\n\nIn Matlab the script and function files have to be in the same folder for the function files to be found. To call a function script located in a different folder, the folder has to be added to path. This can be done with `addpath` or `path`. In a separate file from the Matlab main and function scripts, a separate script can be written to set the path to different folders::\n\n    Dir='/path_to_folder/SeismicLab/codes/';\n    path(path, strcat(Dir,'bp_filter/'));\n    path(path, strcat(Dir,'decon'));\n    path(path, strcat(Dir,'dephasing'));\n    path(path, strcat(Dir,'fx'));\n    ...\n\nThe flag option `-p paths_file` can be set to parse such a file. Then Matlab as well as m2cpp can find function scripts that are located in other directories.\n    \n.. _parallel_flags:\n\nParallel flags, -omp, -tbb\n--------------------------\n\nThe program m2cpp can do parallelization of simple for loops (so called embarrasingly parallel).\nTo let the program know which loops the user wants to parallelize, use the pragma `%#PARFOR`\nbefore the loop (similar to the way its done in OpenMP). The flags -omp and -tbb can then\nbe used to chose if OpenMP code or TBB code will be inserted to parallelize the code. Matlab's\n`parfor` doesn't require the pragma `%#PARFOR` to parallelize. If neither -omp nor -tbb flag is\nused, no OpenMP or TBB code is inserted and we will get a sequential for loop.\nWhen compiling,  try link flags `-fopenmp` for OpenMP and `-ltbb` for TBB. OpenMP is usually available\nfor the compiler out of the box. TBB needs to be installed (see: https://www.threadingbuildingblocks.org/).\nThe TBB code makes use of lambda functions which is a C++ feature. C++11 is probably not set as\nstandard for the compiler, i.e., in the GNU compiler g++, the flag\n`-std=c++11` is required to make use of C++11 features.\n\nQuick translation functions\n---------------------------\n\nEven though `m2cpp` is sufficient for performing all code translation, many\nof the examples in this manual are done through a python interface, since some\nof the python functionality also will be discussed.  Given that `Matlab2cpp`\nis properly installed on your system, the python library is available in\nPython's path. The module is assumed imported as::\n\n    >>> import matlab2cpp\n\nQuick functions collection of frontend tools for performing code translation.\nEach of the function :py:func:`~matlab2cpp.qcpp`, :py:func:`~matlab2cpp.qhpp`,\n:py:func:`~matlab2cpp.qpy` and :py:func:`~matlab2cpp.qlog` are directly related\nto the functionality of the :program:`m2cpp` script. The name indicate the\nfile extension that the script will create.  In addition there are the three\nfunctions :py:func:`~matlab2cpp.qtree` and :py:func:`~matlab2cpp.qscript`. The\nformer represents a summary of the created node tree. The latter is a simple\ntranslation tool that is more of a one-to-one translation.\n\nFor an overview of the various quick-functions, see :ref:`dev01`.\n\nPlotting functionality\n----------------------\n\nPlotting functionality is available through a wrapper, which calls Python's matplotlib.\nIf a Matlab code with plotting calls is translated, the file `SPlot.h` is generated.\nThe C++ file that is generated also `#include` this file. To compile the generated code,\nthe Python have to be included. The code in `SPlot.h` makes of C++11 features, so compiler\noptions for C++11 may be needed as well. With the GNU compiler g++, I can compile\nthe generated code with:\n`g++ my_cpp_file.cpp -o runfile -I /usr/include/python2.7/ -lpython2.7 -larmadillo -std=c++11`\n\nAdditional flags could be -O3 (optimization) -ltbb (in case of TBB parallelization)\n\"\"\"\n"
  },
  {
    "path": "src/matlab2cpp/manual/usr02_datatype.py",
    "content": "\"\"\"\n.. _usr02:\n\nConfiguring translation\n=======================\n\nOne of the translation challenges is how each variable type is determined. In\nC++ all variables have to be explicitly declared, while in Matlab they are\ndeclared implicitly at creation.  When translating between the two languages,\nthere are many variables where the data types are unknown and impossible for\nthe Matlab2cpp software to translate.  How to translate the behavior of an\ninteger is vastly different from an float matrix.\n\nTo differentiate between types, each node have an attribute\n:py:attr:`~matlab2cpp.Node.type` which represents the node datatype.\nDatatypes can be roughly split into two groups: **numerical** and\n**non-numerical** types.  The numerical types are as follows:\n\n+---------------+--------------+---------+---------+--------+-----------+\n|               | unsigned int | integer | float   | double | complex   |\n+===============+==============+=========+=========+========+===========+\n| `scalar`      | uword        | int     | float   | double | cx_double |\n+---------------+--------------+---------+---------+--------+-----------+\n| `vector`      | uvec         | ivec    | fvec    | vec    | cx_vec    |\n+---------------+--------------+---------+---------+--------+-----------+\n| `row\\-vector` | urowvec      | irowvec | frowvec | rowvec | cx_rowvec |\n+---------------+--------------+---------+---------+--------+-----------+\n| `matrix`      | umat         | imat    | fmat    | mat    | cx_mat    |\n+---------------+--------------+---------+---------+--------+-----------+\n| `cube`        | ucube        | icube   | fcube   | cube   | cx_cube   |\n+---------------+--------------+---------+---------+--------+-----------+\n\nValues along the horizontal axis represents the amount of memory reserved per\nelement, and the along the vertical axis represents the various number of\ndimensions.  The names are equivalent to the ones in the Armadillo package.\n\nThe non-numerical types are as follows:\n\n+----------------------------------+------------------------+\n| Name                             | Description            |\n+==================================+========================+\n| `char`                           | Single text character  |\n+----------------------------------+------------------------+\n| `string`                         | Text string            |\n+----------------------------------+------------------------+\n| :ref:`struct <struct>`           | Struct container       |\n+----------------------------------+------------------------+\n| :ref:`structs <structs>`         | Struct array container |\n+----------------------------------+------------------------+\n| :ref:`func_lambda <func_lambda>` | Anonymous function     |\n+----------------------------------+------------------------+\n\nFunction scope\n--------------\n\nIf not specified otherwise, the program will not assign datatype types to any\nof variables. The user could in theory navigate the node tree and assign the\nvariables one by one using the node attributes to navigate. (See section\n:ref:`usr04` for details.) However that would be very cumbersome. Instead the\ndatatypes are define collectively inside their scope. In the case of variables\nin functions, the scope variables are the variables declaration\n:py:class:`~matlab2cpp.Declares` and function parameters\n:py:class:`~matlab2cpp.Params`. To reach the variable that serves as\na scope-wide type, the node attribute :py:attr:`~matlab2cpp.Node.declare` can\nbe used.\n\nManually interacting with the variable scope is simpler then iterating through\nthe full tree, but can in many cases still be cumbersome. To simplefy\ninteraction with datatype scopes, each program has an suppliment attribute\n:py:attr:`~matlab2cpp.Node.ftypes`. The attribute is a nested dictionary where\nthe outer shell represents the function name the variables are defined. The\ninner shell is the variables where keys are variable names and values are\ntypes. It can be used to quickly retrievieng and inserting datatypes.\nFor example::\n\n    >>> tree = matlab2cpp.build(\"function f(a)\")\n    >>> print(tree.ftypes)\n    {'f': {'a': ''}}\n    >>> tree.ftypes = {\"f\": {\"a\": \"int\"}}\n    >>> print(matlab2cpp.qscript(tree))\n    void f(int a)\n    {\n      // Empty block\n    }\n\n.. _func_lambda:\n\nAnonymous functions\n-------------------\n\nIn addition to normal function, Matlab have support for anonymous function\nthrough the name prefix ``@``.  For example::\n\n    >>> print(matlab2cpp.qscript(\"function f(); g = @(x) x^2; g(4)\"))\n    void f()\n    {\n      std::function<double(int)> g ;\n      g = [] (int x) {pow(x, 2) ; } ;\n      g(4) ;\n    }\n\nThe translator creates an ``C++11`` lambda function with equivalent\nfunctionality.  To achieve this, the translator creates an extra function in\nthe node-tree.  The name of the function is the same as assigned variable with\na ``_``-prefix (and a number postfix, if name is taken).  The information about\nthis function dictate the behaviour of the output The supplement file have the\nfollowing form::\n\n    >>> print(matlab2cpp.qpy(\"function f(); g = @(x) x^2; g(4)\"))\n    functions = {\n      \"_g\" : {\n              \"x\" : \"int\",\n      },\n      \"f\" : {\n        \"g\" : \"func_lambda\",\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n\nThe function `g` is a variable inside `f`'s function scope.  It has the datatype\n`func_lambda` to indicate that it should be handled as a function.  The\nassociated function scope `_g` contains the variables inside the definition of\nthe anonymous function.\n\n\n.. _struct:\n\nData structure\n--------------\n\nData structures in Matlab can be constructed explicitly through the\n``struct``-function.  However, they can also be constructed implicitly by\ndirect assignment.  For example will ``a.b=4`` create a ``struct`` with name\n``a`` that has one field ``b``.  When translating such a snippet, it creates\na C++-struct, such that::\n\n    >>> print(matlab2cpp.qhpp(\"function f(); a.b = 4.\", suggest=True))\n    #ifndef F_M_HPP\n    #define F_M_HPP\n    <BLANKLINE>\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    struct _A\n    {\n      double b ;\n    } ;\n    <BLANKLINE>\n    void f()\n    {\n      _A a ;\n      a.b = 4. ;\n    }\n    #endif\n\nIn the suppliment file, the local variable `a` will be assigned as a `struct`.\nIn addition, since the struct has content, the suppliment file creates a new\nsection for structs.  It will have the following form::\n\n    >>> print(matlab2cpp.qpy(\"function f(); a.b = 4.\", suggest=True))\n    functions = {\n      \"f\" : {\n        \"a\" : \"struct\",\n      },\n    }\n    structs = {\n      \"a\" : {\n        \"b\" : \"double\",\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n\nQuick retrieving and inserting struct variables can be done through the\n:py:attr:`~matlab2cpp.Node.stypes` attribute::\n\n    >>> tree = matlab2cpp.build(\"a.b = 4\")\n    >>> tree.ftypes = {\"f\": {\"a\": \"struct\"}}\n    >>> tree.stypes = {\"a\": {\"b\": \"double\"}}\n    >>> print(matlab2cpp.qcpp(tree))\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    struct _A\n    {\n      double b ;\n    } ;\n    <BLANKLINE>\n    int main(int argc, char** argv)\n    {\n      _A a ;\n      a.b = 4 ;\n      return 0 ;\n    }\n\n.. _structs:\n\nStruct tables\n-------------\n\nGiven that the data structure is indexed, e.g. ``a(1).b``, it forms a struct\ntable.  Very similar to regular :ref:`structs <struct>`, which only has one\nvalue per element.  There are a couple of differences in the translation.\nFirst, the struct is declared as an array:\n\n    >>> print(matlab2cpp.qhpp(\"function f(); a(1).b = 4.\", suggest=True))\n    #ifndef F_M_HPP\n    #define F_M_HPP\n    <BLANKLINE>\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    struct _A\n    {\n      double b ;\n    } ;\n    <BLANKLINE>\n    void f()\n    {\n      _A a[100] ;\n      a[0].b = 4. ;\n    }\n    #endif\n\nThe translation assigned reserves 100 pointers for the content of ``a``.\nObviously, there are situations where this isn't enough (or too much), and the\nnumber should be increased. So second, to adjust this number, the suppliment\nfile specifies the number of elements in the integer ``_size``:\n\n    >>> print(matlab2cpp.qpy(\"function f(); a(1).b = 4.\", suggest=True))\n    functions = {\n      \"f\" : {\n        \"a\" : \"structs\",\n      },\n    }\n    structs = {\n      \"a\" : {\n        \"_size\" : 100,\n            \"b\" : \"double\",\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n\n.. _usr02_suggestion_engine:\n\nSuggestion engine\n-----------------\n\nThe examples so far, when the functions :py:func:`~matlab2cpp.qcpp`,\n:py:func:`~matlab2cpp.qhpp` and :py:func:`~matlab2cpp.qpy` are used, the\nargument ``suggest=True`` have been used, and all variable types have been\nfilled in. Consider the following program where this is not the case::\n\n    >>> print(matlab2cpp.qhpp(\"function c=f(); a = 4; b = 4.; c = a+b\", suggest=False))\n    #ifndef F_M_HPP\n    #define F_M_HPP\n    <BLANKLINE>\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    TYPE f()\n    {\n      TYPE a, b, c ;\n      a = 4 ;\n      b = 4. ;\n      c = a+b ;\n      return c ;\n    }\n    #endif\n\nSince all variables are unknown, the program decides to fill in the dummy\nvariable ``TYPE`` for each unknown variable. Any time variables are unknown,\n``TYPE`` is used. The supplement file created by `m2cpp` or\n:py:func:`~matlab2cpp.qpy` reflects all these unknown variables as follows::\n\n    >>> print(matlab2cpp.qpy(\"function c=f(); a = 4; b = 4.; c = a+b\", suggest=False))\n    functions = {\n      \"f\" : {\n        \"a\" : \"\", # int\n        \"b\" : \"\", # double\n        \"c\" : \"\",\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n\nBy flipping the boolean to ``True``, all the variables get assigned datatypes::\n\n    >>> print(matlab2cpp.qpy(\"function c=f(); a = 4; b = 4.; c = a+b\", suggest=True))\n    functions = {\n      \"f\" : {\n        \"a\" : \"int\",\n        \"b\" : \"double\",\n        \"c\" : \"double\",\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n\nThe resulting program will have the following complete form:\n\n    >>> print(matlab2cpp.qhpp(\n    ...     \"function c=f(); a = 4; b = 4.; c = a+b\", suggest=True))\n    #ifndef F_M_HPP\n    #define F_M_HPP\n    <BLANKLINE>\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    double f()\n    {\n      double b, c ;\n      int a ;\n      a = 4 ;\n      b = 4. ;\n      c = a+b ;\n      return c ;\n    }\n    #endif\n\nNote here though that the variable ``c`` didn't have a suggestion. The\nsuggestion is an interactive process such that ``a`` and ``b`` both must be\nknown beforehand.  The variable ``a`` and ``b`` get assigned the datatypes\n``int`` and ``double`` because of the direct assignment of variable.  After\nthis, the process starts over and tries to find other variables that suggestion\ncould fill out for.  In the case of the ``c`` variable, the assignment on the\nright were and addition between ``int`` and ``double``.  To not loose\nprecision, it then chooses to keep `double`, which is passed on to the ``c``\nvariable.  In practice the suggestions can potentially fill in all datatypes\nautomatically in large programs, and often quite intelligently. For example,\nvariables get suggested across function call scope::\n\n    >>> print(matlab2cpp.qscript('function y=f(x); y=x; function g(); z=f(4)'))\n    int f(int x)\n    {\n      int y ;\n      y = x ;\n      return y ;\n    }\n    <BLANKLINE>\n    void g()\n    {\n      int z ;\n      z = f(4) ;\n    }\n\nAnd accross multiple files::\n\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder()\n    >>> builder.load(\"f.m\", \"function y=f(x); y=x\")\n    >>> builder.load(\"g.m\", \"function g(); z=f(4)\")\n    >>> builder.configure(suggest=True)\n    >>> tree_f, tree_g = builder[:]\n    >>> print(matlab2cpp.qscript(tree_f))\n    int f(int x)\n    {\n      int y ;\n      y = x ;\n      return y ;\n    }\n    >>> print(matlab2cpp.qscript(tree_g))\n    void g()\n    {\n      int z ;\n      z = f(4) ;\n    }\n\nVerbatim translations\n---------------------\n\nIn some cases, the translation can not be performed. For example, the Matlab\nfunction ``eval`` can not be properly translated. Matlab is interpreted, and\ncan easily take a string from local name space, and feed it to the interpreter.\nIn C++ however, the code must be pre-compiled. Not knowing what the string\ninput is before runtime, makes this difficult. So instead it makes more sense\nto make some custom translation by hand.\n\nSince ``matlab2cpp`` produces C++ files, it is possible to edit them after\ncreation. However, if changes are made to the Matlab-file at a later point, the\ncustom edits have to be added manually again. To resolve this, ``matlab2cpp``\nsupports verbatim translations through the suppliment file ``.py`` and through\nthe node attribute :py:attr:`~matlab2cpp.Node.vtypes`.\n:py:attr:`~matlab2cpp.node.vtype` is a dictionary where the keys are string\nfound in the orginal code, and the values are string of the replacement.\n\nPerforming a verbatim replacement has to be done before the node tree is\nconstructed. Assigning :py:attr:`~matlab2cpp.Node.vtypes` doesn't work very\nwell. Instead the replacement dictionary can be bassed as argument to\n:py:func:`~matlab2cpp.build`::\n\n    >>> tree = matlab2cpp.build('''a=1\n    ... b=2\n    ... c=3''', vtypes = {\"b\": \"_replaced_text_\"})\n    >>> print(matlab2cpp.qscript(tree))\n    a = 1 ;\n    // b=2\n    _replaced_text_\n    c = 3 ;\n\nNote that when a match is found, the whole line is replaced. No also how the\nsource code is retained a comment above the verbatim translation. The\nverbatim key can only match a single line, however the replacement might span\nmultiple lines. For example::\n\n    >>> replace_code = '''one line\n    ... two line\n    ... three line'''\n    >>> tree = matlab2cpp.build('''a=1\n    ... b=2\n    ... c=3''', vtypes={\"b\": replace_code})\n\n    >>> print(matlab2cpp.qscript(tree))\n    a = 1 ;\n    // b=2\n    one line\n    two line\n    three line\n    c = 3 ;\n\nVerbatims can also be utilized by modifying the .py file. Consider the Matlab script::\n\n    a = 1 ;\n    b = 2 ;\n    c = 3 ;\n\nUsing the m2cpp script to translate the Matlab script produces a C++ file and a .py file. By adding code to the .py file, verbatim translation can be added. This is done by using the keyword verbatims and setting it to a python dictionary. Similar to vtype, keys are strings found in the original code, and the values are string of the replacement::\n\n    functions = {\n    \"main\" : {\n    \"a\" : \"int\",\n    \"b\" : \"int\",\n    \"c\" : \"int\",\n    },\n    }\n    includes = [\n    '#include <armadillo>',\n    'using namespace arma ;',\n    ]\n    verbatims = {\"b = 2 ;\" : '''one line\n    two line\n    tree line'''\n    }\n\nIn the generated C++ file the second assignment is replaced with the verbatim translation::\n\n    int main(int argc, char** argv)\n    {\n      int a, c ;\n      a = 1 ;\n      // b = 2 ;\n      one line\n      two line\n      tree line\n      c = 3 ;\n      return 0 ;\n    }\n\"\"\"\n"
  },
  {
    "path": "src/matlab2cpp/manual/usr03_rules.py",
    "content": "\"\"\"\n.. _usr03:\n\nTranslation rules\n=================\n\nIn Matlab2cpp, the simplest form for translation is a simple string saved to\na variable.  For example::\n\n    >>> Int = \"6\"\n\nThe name :py:class:`~matlab2cpp.collection.Int` (with capital letter)\nrepresents the node the rule is applicable for integers. The right hand side\nwhen it is a string, will be used as the translation every time\n:py:class:`~matlab2cpp.collection.Int` occurs.  To illustrate this, consider\nthe following simple example, where we pass a snippet to the\n:py:func:`~matlab2cpp.qscript` function::\n\n    >>> print(matlab2cpp.qscript(\"5\"))\n    5 ;\n\nTo implement the new rule we (globally) insert the rule for all instances of\n:py:class:`~matlab2cpp.collection.Int` as follows::\n\n    >>> print(matlab2cpp.qscript(\"5\", Int=Int))\n    6 ;\n\nObviously, this type of translation is not very useful except for a very few\nexceptions. First of all, each :py:class:`~matlab2cpp.collection.Int` (and\nobviously many other nodes) contain a value. To represent this value, the\ntranslation rule uses string interpolation. This can be implemented as\nfollows::\n\n    >>> Int = \"|%(value)s|\"\n    >>> print(matlab2cpp.qscript(\"5\", Int=Int))\n    |5| ;\n\nThere are also other attributes than `value`. For example variables,\nrepresented through the node `Var` have a name, which refer to it's scope\ndefined name.  For example::\n\n    >>> Var = \"__%(name)s__\"\n    >>> print(matlab2cpp.qscript(\"a = 4\", Var=Var))\n    __a__ = 4 ;\n\nSince all the code is structured as a node tree, many of the nodes have node\nchildren. The translation is performed leaf-to-root, implying that at the time\nof translation of any node, all of it's children are already translated and\navailable in interpolation. The children are indexed by number, counting from\n0. Consider the simple example of a simple addition::\n\n    >>> print(matlab2cpp.qtree(\"2+3\", core=True)) # doctest: +NORMALIZE_WHITESPACE\n     1  1Block      code_block   TYPE\n     1  1| Statement  code_block   TYPE\n     1  1| | Plus       expression   int\n     1  1| | | Int        int          int\n     1  3| | | Int        int          int\n    >>> print(matlab2cpp.qscript(\"2+3\"))\n    2+3 ;\n\nThe node tree (at it's core) consists of\na :py:class:`~matlab2cpp.collection.Block`.\nThat code :py:class:`~matlab2cpp.collection.Block` contains\none :py:class:`~matlab2cpp.collection.Statement`. The\n:py:class:`~matlab2cpp.collection.Statement` contains the\n:py:class:`~matlab2cpp.collection.Pluss` operator, which contains the two\n:py:class:`~matlab2cpp.collection.Int`. Each :py:class:`~matlab2cpp.Node` in\nthe tree represents one token to be translated.\n\nFrom the perspective of the addition :py:class:`~matlab2cpp.collection.Plus`,\nthe two node children of class :py:class:`~matlab2cpp.collection.Int` are\navailable in translation respectivly as index 0 and 1. In interpolation we can\ndo as follows::\n\n    >>> Plus = \"%(1)s+%(0)s\"\n    >>> print(matlab2cpp.qscript(\"2+3\", Plus=Plus))\n    3+2 ;\n\nOne obvious problem with this approach is that the number of children of a node\nmight not be fixed. For example the `Plus` in \"2+3\" has two children while\n\"1+2+3\" has three. To address nodes with variable number of node children,\nalternative representation can be used. Instead of defining a string, a tuple\nof three string can be used. They represents prefix, infix and postfix between\neach node child. For example::\n\n    >>> Plus = \"\", \"+\", \"\"\n\nIt implies that there should be a \"+\" between each children listed, and nothing\nat the ends. In practice we get::\n\n    >>> print(matlab2cpp.qscript(\"2+3\", Plus=Plus))\n    2+3 ;\n    >>> print(matlab2cpp.qscript(\"1+2+3\", Plus=Plus))\n    1+2+3 ;\n\n\nAnd this is the extent of how the system uses string values. However, in\npractice, they are not used much. Instead of strings and tuples functions are\nused. They are defined with the same name the string/tuple. This function\nshould always take a single argument of type :py:class:`~matlab2cpp.Node` which\nrepresents the current node in the node tree. The function should return either\na :py:class:`~matlab2cpp.str` or :py:class:`~matlab2cpp.tuple` as described\nabove. For example, without addressing how one can use `node`, the following is\nequivalent::\n\n    >>> Plus = \"\", \"+ \", \"\"\n    >>> print(matlab2cpp.qscript(\"2+3\", Plus=Plus))\n    2+ 3 ;\n    >>> def Plus(node):\n    ...     return \"\", \" +\", \"\"\n    ...\n    >>> print(matlab2cpp.qscript(\"2+3\", Plus=Plus))\n    2 +3 ;\n\nOne application of the ``node`` argument is to use it to configure datatypes.\nAs discussed in the previous section :ref:`usr02`, the node attribute\n:py:attr:`~matlab2cpp.Node.type` contains information about datatype.\nFor example::\n\n    >>> def Var(node):\n    ...     if node.name == \"x\": node.type = \"vec\"\n    ...     if node.name == \"y\": node.type = \"rowvec\"\n    ...     return node.name\n    >>> print(matlab2cpp.qscript(\"function f(x,y)\", Var=Var))\n    void f(vec x, rowvec y)\n    {\n      // Empty block\n    }\n\nFor more details on the behavior of the :py:mod:`~matlab2cpp.node` argument, \nsee section on node :ref:`usr04`. For an extensive list of the various nodes\navailable, see developer manual :ref:`dev06`.\n\n\nRule context\n------------\n\nIn the basic translation rule described above, each node type have one\nuniversal rule. However, depending on context, various nodes should be\naddressed differently. For example the snippet `sum(x)` lend itself naturally\nto have a rule that targets the name `sum` which is part of the Matlab standard\nlibrary. Its translation should is as follows::\n\n    >>> print(matlab2cpp.qscript(\"sum(x)\"))\n    arma::sum(x) ;\n    \nHowever, if there is a line `sum = [1,2,3]` earlier in the code, then the\ntranslation for `sum(x)` become very different. `sum` is now an array, and the\ntranslation adapts::\n\n    >>> print(matlab2cpp.qscript(\"sum=[1,2,3]; sum(x)\"))\n    sword _sum [] = {1, 2, 3} ;\n    sum = irowvec(_sum, 3, false) ;\n    sum(x-1) ;\n\nTo address this in the same node will quickly become very convoluted. So\ninstead, the rules are split into various backends. This simplifies things for\neach rule that have multiple interpretations, but also ensures that code isn't\nto bloated.  For an overview of the various backend, see the developer manual\n:ref:`dev07`.\n\nReserved rules\n--------------\n\nThe example above with `sum(x)` is handled by two rules. In the second\niteration, it is a :py:mod:`~matlab2cpp.datatype` of type `irowvec` and is\ntherefore processed in the corresponding rule for `irowvec`. However, in the\nformer case, `sum` is a function from the Matlab standard library. In principle\nthere is only one rule for all function calls like this. However, since the\nstandard library is large, the rules are segmented into rules for each name. \n\nIn the rule :py:mod:`rules._reserved <matlab2cpp.rules._reserved>`, each\nfunction in the standard library (which matlab2cpp supports) is listed in the\nvariable `rules.reserved`. The context for reserved function manifest itself\ninto the rules for function calls :py:class:`~matlab2cpp.collection.Get`,\nvariables :py:class:`~matlab2cpp.collection.Var` and in some cases,\nmultivariate assignment :py:class:`~matlab2cpp.collection.Assigns`. As\ndescribed above, the rules should then have these names respectively. However\nto indicate the name, the rules also includes node names as suffix. For\nexample, the function call for `sum` is handled in the rule\n:py:func:`~matlab2cpp.rules._reserved.Get_sum`.\n\nIn practice this allows us to create specific rules for any node with names,\nwhich includes variables, function calls, functions, to name the obvious.\nFor example, if we want to change the summation function from armadillo to the\n`accumulation` from `numeric` module, it would be implemented as follows::\n\n    >>> Get_sum = \"std::accumulate(\", \", \", \")\"\n    >>> print(matlab2cpp.qscript(\"sum(x)\", Get_sum=Get_sum))\n    std::accumulate(x) ;\n\nThis rules is specific for all function calls with name `sum` and wount be\napplied for other functions::\n\n    >>> Get_sum = \"std::accumulate(\", \", \", \")\"\n    >>> print(matlab2cpp.qscript(\"min(x)\", Get_sum=Get_sum))\n    min(x) ;\n\nThere are many rules to translation rule backends in matlab2cpp. This is mainly\nbecause each datatype have a corresponding backend.\n\"\"\"\n"
  },
  {
    "path": "src/matlab2cpp/manual/usr04_node.py",
    "content": "\"\"\"\n.. _usr04:\n\nBehind the frontends\n====================\n\nCommon for all the various frontends in :py:mod:`~matlab2cpp.qfunctions` are\ntwo classes: :py:class:`~matlab2cpp.Builder` and :py:class:`~matlab2cpp.Node`.\nThe former scans Matlab code and constructs a node tree consiting of instances\nof the latter.\n\nThe Builder class\n-----------------\n\nIterating through Matlab code always starts with constructing\na :py:class:`~matlab2cpp.Builder`::\n\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder()\n\nThis is an empty shell without any content. To give it content, we supply it\nwith code::\n\n    >>> builder.load(\"file1.m\", \"a = 4\")\n\nThe function saves the code locally as `builder.code` and initiate the\n`create_program` method with index 0. The various `create_*` methods are then\ncalled and used to populate the node tree. The code is considered static,\ninstead the index, which refer to the position in the code is increased to move\nforward in the code. The various constructors uses the support modules in the\n:py:mod:`~matlab2cpp.qtree` to build a full toke tree.  The result is as\nfollows::\n\n    >>> print(builder) # doctest: +NORMALIZE_WHITESPACE\n         Project    unknown      TYPE\n         | Program    unknown      TYPE    file1.m\n         | | Includes   unknown      TYPE\n     1  1| | Funcs      unknown      TYPE    file1.m\n     1  1| | | Main       unknown      TYPE    main\n     1  1| | | | Declares   unknown      TYPE\n     1  1| | | | | Var        unknown      TYPE    a\n     1  1| | | | Returns    unknown      TYPE\n     1  1| | | | Params     unknown      TYPE\n     1  1| | | | Block      unknown      TYPE\n     1  1| | | | | Assign     unknown      TYPE\n     1  1| | | | | | Var        unknown      TYPE    a\n     1  5| | | | | | Int        unknown      TYPE\n         | | Inlines    unknown      TYPE    file1.m\n         | | Structs    unknown      TYPE    file1.m\n         | | Headers    unknown      TYPE    file1.m\n         | | Log        unknown      TYPE    file1.m\n\nIt is possible to get a detailed output of how this process is done, by turning\nthe ``disp`` flag on::\n\n    >>> builder = Builder(disp=True)\n    >>> builder.load(\"file1.m\", \"a = 4\") # doctest: +NORMALIZE_WHITESPACE\n    loading file1.m\n         Program    functions.program\n       0 Main       functions.main\n       0 Codeblock  codeblock.codeblock\n       0   Assign     assign.single       'a = 4'\n       0     Var        variables.assign    'a'\n       4     Expression expression.create   '4'\n       4     Int        misc.number         '4'\n\nThis printout lists the core Matlab translation. In the four columns the first\nis the index to the position in the Matlab code, the second is the node created,\nthe third is the file and function where the node was created, and lastly the\nfourth column is a code snippet from the Matlab code. This allows for quick\ndiagnostics about where an error in interpretation might have occurred.\n\nNote that the tree above for the most part doesn't have any backends or\ndatatypes configured.  They are all set to ``unknown`` and ``TYPE``\nrespectivly.  To configure backends and datatypes, use the\n:py:func:`~matlab2cpp.Builder.configure` method::\n\n    >>> builder.configure(suggest=True)\n    >>> print(builder) # doctest: +NORMALIZE_WHITESPACE\n         Project    program      TYPE\n         | Program    program      TYPE    file1.m\n         | | Includes   program      TYPE\n     1  1| | Funcs      program      TYPE    file1.m\n     1  1| | | Main       func_return  TYPE    main\n     1  1| | | | Declares   func_return  TYPE\n     1  1| | | | | Var        int          int     a\n     1  1| | | | Returns    func_return  TYPE\n     1  1| | | | Params     func_return  TYPE\n     1  1| | | | Block      code_block   TYPE\n     1  1| | | | | Assign     int          int\n     1  1| | | | | | Var        int          int     a\n     1  5| | | | | | Int        int          int\n         | | Inlines    program      TYPE    file1.m\n         | | Structs    program      TYPE    file1.m\n         | | Headers    program      TYPE    file1.m\n         | | Log        program      TYPE    file1.m\n\nMultiple program can be loaded into the same builder. This allows for building\nof projects that involves multiple files. For example::\n\n    >>> builder = Builder()\n    >>> builder.load(\"a.m\", \"function y=a(x); y = x+1\")\n    >>> builder.load(\"b.m\", \"b = a(2)\")\n\nThe two programs refer to each other through their names. This can the\nsuggestion engine use::\n\n    >>> print(matlab2cpp.qscript(builder[0]))\n    int a(int x)\n    {\n      int y ;\n      y = x+1 ;\n      return y ;\n    }\n    >>> print(matlab2cpp.qscript(builder[1]))\n    b = a(2) ;\n\nNote that the frontend functions (like :py:func:`~matlab2cpp.qscript`)\nconfigure the tree if needed.\n\nThe Node class\n--------------\n\nSo far the translation has been for the most part fairly simple, where the\ntranslation is reduced to either a string or a tuple of strings for weaving\nsub-nodes together. Consider the following example::\n\n    >>> def Plus(node):\n    ...     return \"\", \" +\", \"\"\n    ...\n    >>> print(matlab2cpp.qscript(\"2+3\", Plus=Plus))\n    2 +3 ;\n\nThough not used, the argument `node` represents the current node in the tree as\nthe tree is translated.  We saw this being used in the last section\n:ref:`usr03` to get and set node datatype. However, there are much more you can\nget out of the node. First, to help understand the current situation from\na coding perspective, one can use the help function\n:py:func:`~matlab2cpp.Node.summary`, which gives a quick summary of the node\nand its node children. It works the same way as the function\n:py:func:`~matlab2cpp.qtree`, but can be used mid translation. For example::\n\n    >>> def Plus(node):\n    ...     print(node.summary())\n    ...     return \"\", \" +\", \"\"\n    ...\n    >>> print(matlab2cpp.qscript(\"2+3\", Plus=Plus)) # doctest: +NORMALIZE_WHITESPACE\n     1  1Plus       expression   int\n     1  1| Int        int          int\n     1  3| Int        int          int\n    2 +3 ;\n\nThe first line represent the current node\n:py:class:`~matlab2cpp.collection.Plus`.\n\nintroduce the node tree structure and how the nodes relate to each other.\nThis will vary from program to program, so a printout of the current state is\na good startingpoint. This can either be done through the function\n:py:mod:`~matlab2cpp.qtree`, or manually as follows::\n\n    >>> builder = Builder()\n    >>> builder.load(\"unnamed\", \"function y=f(x); y=x+4\")\n    >>> builder[0].ftypes = {\"f\" : {\"x\": \"int\", \"y\": \"double\"}}\n    >>> builder.translate()\n    >>> print(builder) # doctest: +NORMALIZE_WHITESPACE\n         Project    program      TYPE\n         | Program    program      TYPE    unnamed\n         | | Includes   program      TYPE\n         | | | Include    program      TYPE    #include <armadillo>\n         | | | Include    program      TYPE    using namespace arma ;\n     1  1| | Funcs      program      TYPE    unnamed\n     1  1| | | Func       func_return  TYPE    f\n     1  1| | | | Declares   func_return  TYPE\n     1  1| | | | | Var        double       double  y\n     1  1| | | | Returns    func_return  TYPE\n     1 10| | | | | Var        double       double  y\n     1 13| | | | Params     func_return  TYPE\n     1 14| | | | | Var        int          int     x\n     1 16| | | | Block      code_block   TYPE\n     1 18| | | | | Assign     expression   int\n     1 18| | | | | | Var        double       double  y\n     1 20| | | | | | Plus       expression   int\n     1 20| | | | | | | Var        int          int     x\n     1 22| | | | | | | Int        int          int\n         | | Inlines    program      TYPE    unnamed\n         | | Structs    program      TYPE    unnamed\n         | | Headers    program      TYPE    unnamed\n         | | | Header     program      TYPE    f\n         | | Log        program      TYPE    unnamed\n\n\nThe Project is the root of the tree. To traverse the tree in direction of the\nleafs can be done using indexing::\n\n    >>> funcs = builder[0][1]\n    >>> func = funcs[0]\n    >>> assign = func[3][0]\n    >>> var_y, plus = assign\n    >>> var_x, int_4 = plus\n\nMoving upwards towards the root of the tree is done using the\n:py:attr:`~matlab2cpp.Node.parent` reference::\n\n    >>> block = assign.parent\n    >>> print(assign is var_y.parent)\n    True\n\nThe node provided in the node function is the current node for which the parser\nis trying to translate. This gives each node full control over context of which\nis is placed. For example, consider the following::\n\n    >>> print(matlab2cpp.qtree(\"x(end, end)\", core=True)) # doctest: +NORMALIZE_WHITESPACE\n     1  1Block      code_block   TYPE\n     1  1| Statement  code_block   TYPE\n     1  1| | Get        unknown      TYPE    x\n     1  3| | | End        expression   int\n     1  8| | | End        expression   int\n    >>> def End(node):\n    ...     if node is node.parent[0]:\n    ...         return node.parent.name + \".n_rows\"\n    ...     if node is node.parent[1]:\n    ...         return node.parent.name + \".n_cols\"\n    ...\n    >>> print(matlab2cpp.qscript(\"x(end, end)\", End=End))\n    x(x.n_rows, x.n_cols) ;\n\nHere the rule `End` was called twice, where the if-test produces two different\nresults. Also, information about the parent is used in the value returned.\n\nSee also:\n    :py:class:`~matlab2cpp.Builder`\n\"\"\"\n"
  },
  {
    "path": "src/matlab2cpp/manual/usr05_installation.py",
    "content": "r\"\"\"\n.. usr05:\n\nInstallation\n============\n\nRequirements:\n\n* Python 2.7.3\n* Armadillo (Not required for running, but generator\n  creates armadillo code.)\n\n\nOptional:\n\n* C++11 (Plotting and TBB require C++11)\n* Intel Threading Building Blocks (TBB)\n* Intel Math Kernel Library (MKL)\n* MATLAB Engine API for Python\n* Matplotlib (Python module required for plotting)\n* Sphinx (for compiling documentation)\n* Argcomplete (for tab-completion support)\n\nInstalling Python\n-----------------\n\n\nInstalling Armadillo\n--------------------\n\nArmadillo can be downloaded at http://arma.sourceforge.net/ . Some of the functionality of Armadillo is a kind of wrapper and relies on a math library as BLAS, OpenBLAS, LAPACK, MKL. To compute x = A\\\\b or perform fast matrix-matrix multiplication one or more of these math libraries are required. See the Armadillo webpage for details. Install the required math library before installing Armadillo.  Armadillo creates a dynamic library when it is compiled and installed. This dynamic library is configured to use one or more of the math libraries which were found when it was created. You don't need to install Armadillo and use link Armadillo to your program with the dynamic library. It is possible to give include and library path to Armadillo as well as link in one or more math libraries (BLAS, OpenBLAS, LAPACK, MKL). \n\nYou could think of this as manually specifying the linking versus linking the dynamic Armadillo library where which math library to use has already been set. Even if you install Armadillo you have the option to link Armadillo by setting include, linking path and additional flags to link the math library.\n\n\nInstalling Matlab2cpp\n---------------------\n\nMatlab2cpp is written in Python. When running the translator program the Matlab2cpp is imported as a module its functionality is used to parse and translate Matlab code to C++. Because of this Python 2.7 is a requirement. \n\nMatlab2cpp is Open-source and is available at Github (https://github.com/emc2norway/m2cpp) . With the `git` software installed the software can be downloaded to the current folder by typing::\n\n    git clone git@github.com:emc2norway/m2cpp.git\n\nin a terminal (in Windows: cmd, cygwin). Move to the downloaded code with `\"cd m2cpp\"`. Then the software can be installed by typing\n\nWindows::\n\n    python setup.py install\n\nMac/Linux::\n\n    sudo python setup.py install\n\nTo update the Matlab2cpp to a newer version on git, enter a terminal and move to the folder where you downloaded Matlab2cpp with git clone. To pull the latest version on Github type::\n\n    git pull\n\nand then re-install with the same command used to install the first time as described above. When installing the module \n\n\nInstalling optional packages\n----------------------------\n\nAmong these optional packages, TBB, MKL and configuring Matlab to suggest datatypes are probably the most intereting/useful features.\n\nBy inserting pragmas in the Matlab code, for loops can be marked by the user. The program can then either insert OpenMP or TBB code to parallelize the for loop. By putting this pragma before the for loop the user guarranties that the iterations are independent and write to different memory locations. To compile TBB code, the TBB library has to be installed. Most compilers now adays come with built in support for OpenMP, therefore no installation should be necessary.\n\nIt may not be well known, but MKL is available for free. MKL isn't necessarry as BLAS, OpenBLAS, LAPACK could be used intead.u\n\nC++ is a static language. This means that the variables have to be declared and have the specified datatype. At the moment some of variable types in the generated C++ code can be deduced from the Matlab code. Another option is to run the Matlab code with Matlab and get the datatypes Matlab used when executing the Matlab code. To make use of this option, you need a sufficiently new Matlab version installed (works on R2015b) on your computer.\n\nThe plotting functional provided by Matlab2cpp is done by a wrapper for Python's matplotlib module. This wrapper also makes use of C++11 functionality. Compiling the generated C++ code require C++11, Python and Matplotlib. \n\nIntel Threading Building Blocks (TBB)\n+++++++++++++++++++++++++++++++++++++\n\nTBB can be downloaded at https://www.threadingbuildingblocks.org/. On the linux distribution Ubuntu, TBB can be installed from the terminal with the command: `sudo apt-get install libtbb-dev`\n\n\nIntel Math Kernel Library (MKL)\n+++++++++++++++++++++++++++++++\n\nMKL can be downloaded for free at https://software.intel.com/en-us/articles/free-mkl\n\n\nMATLAB Engine API for Python\n++++++++++++++++++++++++++++\n\nFollow the instrucion at: http://se.mathworks.com/help/matlab/matlab_external/install-the-matlab-engine-for-python.html\n\nMatplotlib (Python module required for plotting)\n++++++++++++++++++++++++++++++++++++++++++++++++\n\nMatplotlib could be part of your Python installation by default. Else it can be installed with\n::\n\n    pip install matplotlib\n\nSphinx (for compiling documentation)\n++++++++++++++++++++++++++++++++++++\n\n::\n\n    pip install sphinx\n    pip install sphinxcontrib-autoprogram\n    pip install sphinxcontrib-napoleon\n    pip install sphinx-argparse\n\n\n\nArgcomplete (for tab-completion support)\n++++++++++++++++++++++++++++++++++++++++\n\n::\n\n    pip intall argcomplete\n    activate-global-python-argcomplete\n\nThis only works for Bash and would require a restart of terminal emulator.\n\n\"\"\"\n"
  },
  {
    "path": "src/matlab2cpp/matlab_types.py",
    "content": "import os\nimport shutil #copy files from current dir to m2cpp_temp\n#import re\nimport matlab2cpp.mwhos\nfrom matlab2cpp.datatype import get_mem\n\nfrom itertools import takewhile\n\ndef lstripped(s):\n    return ''.join(takewhile(str.isspace, s))\n\n#def rstripped(s):\n#    return ''.join(reversed(tuple(takewhile(str.isspace, reversed(s)))))\n\n#def stripped(s):\n#    return lstripped(s), rstripped(s)\n\ndef mtypes(builder, args):\n\n    #Current working directory\n    src_dir = os.getcwd() + os.path.sep\n\n    dst_dir = src_dir + \"m2cpp_data_type_temp\" + os.path.sep\n\n    # Delete the temporary folder which the datatype info\n    if os.path.isdir(dst_dir):\n        shutil.rmtree(dst_dir)\n    #if directory m2cpp_data_type_temp does not exist, create it\n    if not os.path.isdir(dst_dir):\n        os.mkdir(dst_dir)\n\n    #copy file in directory to m2cpp_temp\n    #If there are data files in directory, then they have to be copied, or abspath to datafiles in program\n    src_file_dir = os.path.dirname(os.path.abspath(args.filename)) + os.path.sep\n    src_files = os.listdir(os.path.dirname(os.path.abspath(args.filename)) + os.path.sep)\n\n    for file_name in src_files:\n        file_src = src_file_dir + file_name\n        if os.path.isfile(file_src):\n            if file_src[-2:] != \".m\":\n                shutil.copy(file_src, dst_dir)\n\n    #write whos_f.m to folder. Similar to matlab whos function,\n    #but writes to file\n    f = open(dst_dir + \"whos_f.m\", \"w\")\n    f.write(matlab2cpp.mwhos.code)\n    f.close()\n\n    ##Create new matlab file in m2cpp_temp\n    #Loop for each script and function .m file\n    #print(\"- Program loop start\\n\\n\")\n    for program in builder.project:\n        #get program code from matlab file\n        f = open(program.name, \"r\")\n        code = f.read()\n        f.close()\n\n        #Get name of file after splitting path, set file path \"m2cpp_temp/file\"\n        file_path = dst_dir + program.name.split(os.path.sep)[-1]\n        #print(file_path)\n\n        #Program is main script file, add whos_f at end of file\n        #program[1][0].cls is Main if script file\n        if program[1][0].cls == \"Main\":\n            #Modify the code, main file\n            file_name = (program.name.split(os.path.sep)[-1])[:-2]\n            code += \"\\nwhos_f\"\n        else:\n            #Modify the code, funtion file\n            code = function_code(program, code)\n\n        #insert whos_f before return statements\n        func_name = \"whos_f\"\n\n        lines = code.splitlines()\n        code_temp = []\n        for line in lines:\n            #lstrip line and compare with \"return\"\n            if line.lstrip()[:6] == \"return\":\n                #Insert left stripped whitespace + func_name\n                code_temp.append(lstripped(line) + func_name)\n            #Add the \"original\" code line\n            code_temp.append(line)\n\n        #Convert string list to string\n        code = \"\\n\".join(code_temp)\n        \n        #write file to m2cpp_temp/\n        #print(\"writing file: \" + file_path)\n\n        f = open(file_path, \"w\")\n        f.write(code)\n        f.close()\n    try:\n        import matlab.engine\n\n        #Set path to -p \"setpath.m\" before changing current working directory\n        if args.paths_file:\n            matlab_cmd = \"run(\\'\"+ os.path.abspath(args.paths_file).rstrip(\".m\") + \"\\')\"\n\n        cwdir = os.getcwd()\n        os.chdir(dst_dir)\n        engine = matlab.engine.start_matlab()\n\n        if args.paths_file:\n            engine.evalc(matlab_cmd, nargout=0)\n        engine.evalc(file_name, nargout=0)\n\n        os.chdir(cwdir)\n    except:\n        print(\"matlab did not load correctly, check that you have matlab engine API for python installed\")\n\n    ##Process .m.txt files to extract data types\n    #I could have this under the previous loop,\n    #but then the loop becomes so long\n    program_number = 0\n\n    for program in builder.project:\n        #reset funcs_types dictionary for each iteration\n        funcs_types = {}\n        file_path = dst_dir + program.name.split(os.path.sep)[-1] + \".txt\"\n        #print(file_path)\n        funcs_types = extract_ftypes(program, funcs_types, file_path)\n    \n        ##Copy data types to program.ftypes\n        funcs = program.ftypes\n\n        for func_key in funcs_types.keys():\n            for var_key in funcs_types[func_key].keys():\n                funcs[func_key][var_key] = funcs_types[func_key][var_key]\n        \n        #set ftypes for the current program\n        builder[program_number].ftypes = funcs\n        program_number += 1\n\n    return builder\n        \n\n\ndef extract_ftypes(program, funcs_types, file_path):\n    \n    #Check if file exists, if not return\n    if not os.path.isfile(file_path):\n        return funcs_types\n\n    #Read file\n    f = open(file_path, \"r\")\n    lines = f.read().splitlines() #change to read, and then splitlines\n    f.close()\n\n    #while line\n    j = 0\n    while j < len(lines):\n        line = lines[j]\n\n        #print(str(j) + \":\" + line)\n        #When function is found, loop over variables and\n        cols = line.split(\":\")\n        #add them to dict funcs_types\n        if cols[0] == \"#function_name\":\n            #print(line)\n            #funcs_name = cols[1].split(\",\")[0]\n\n            f_names = cols[1].split(\",\")\n\n            #funcs_name = f_names[0].lstrip() if not len(f_names) == 2 else f_names[1].lstrip()\n            funcs_name = f_names[0].lstrip() if program[1][0].cls != \"Main\" else f_names[1].lstrip()\n            \n            #skip next line\n            j += 2\n\n            #make double indexed dictionary\n            if not funcs_types.get(funcs_name):\n                funcs_types[funcs_name] = {}\n            while j < len(lines) and lines[j] != \"\":\n                cols = lines[j].split(\", \")\n\n                #cols contain: name, size, class, complex, integer\n                #extract variables to be more readable\n                var_name = cols[0]\n                \n                #print(lines[j])\n                #extract the type in string format\n                data_type = datatype_string(cols)\n\n                #print(var_name + \": \" + data_type)\n\n                #insert in dictionary\n                #check if entry in dictionary exist\n                data_type_old = funcs_types[funcs_name].get(var_name)\n\n                #complex type should stay complex type\n                if data_type_old:\n                    #get if datatype is comples, then mem_value should be 4\n                    #mem_value_old = get_mem(data_type_old)\n                    mem_value_new = get_mem(data_type)\n                    #print(\"mem_value_new: \")\n                    #print(mem_value_new)\n                    if mem_value_new == 4:\n                        funcs_types[funcs_name][var_name] = data_type\n                else:\n                    funcs_types[funcs_name][var_name] = data_type\n\n                j += 1\n                \n        j += 1\n    \n    return funcs_types\n\ndef datatype_string(cols):\n    #Convert data from cols to a string, representing the datatype\n    M, N = [int(s) for s in cols[1].split(\"x\")]\n    var_type = cols[2]\n    complex_number = int(cols[3])\n    integer = int(cols[4])\n\n    data_type = \"\"\n    if var_type == \"double\":\n        #non complex\n        if not complex_number:\n            #scalar\n            if M == 1 and N == 1:\n                if integer:\n                    data_type = \"int\"\n                else:\n                    data_type = \"double\"\n                    \n            #vec\n            if M > 1 and N == 1:\n                #data_type = \"mat\"\n                data_type = \"vec\"\n                    \n            #rowvec\n            if M == 1 and N > 1:\n                #data_type = \"mat\"\n                data_type = \"rowvec\"\n                    \n            #matrix\n            if (M > 1 and N > 1) or M == 0 or N == 0: #if empty matrix, set to mat\n                data_type = \"mat\"\n                    \n        #complex value\n        elif complex_number:\n            #scalar\n            if M == 1 and N == 1:\n                data_type = \"cx_double\"\n\n            #vec\n            if M > 1 and N == 1:\n                #data_type = \"cx_mat\"\n                data_type = \"cx_vec\"\n                \n            #rowvec\n            if M == 1 and N > 1:\n                #data_type = \"cx_mat\"\n                data_type = \"cx_rowvec\"\n                \n            #matrix\n            if M > 1 and N > 1 or M == 0 or N == 0: #if empty matrix, set to mat:\n                data_type = \"cx_mat\"\n                \n    return data_type\n    \ndef detect_string(code, k):\n\n    import string\n\n    if code[k] != \"'\":\n        syntaxerror(k, \"start of string character (')\")\n\n    if code[k-1] == \".\":\n        return False\n\n    j = k-1\n    while code[j] in \" \\t\":\n        j -= 1\n\n    if code[j] in string.letters+string.digits+\")]}_\":\n\n        # special cases\n        if code[j-3:j+1] == \"case\":\n            return True\n\n        return False\n\n    return True\n\n\ndef function_code(program, code):\n    #print(program.summary())\n\n    #count number of if, while, for, switch and number of end\n\n    #Flatten nodes, count number of nodes of type if, while for\n    #num_if = 0 #num_while = 0 #num_for = 0 #num_switch = 0\n    import re\n    iwfs_ends = 0\n    \n    nodes = program.flatten(False, True, False)\n\n    for node in nodes: \n        if node.cls in [\"If\", \"While\", \"For\", \"Switch\"]:\n            iwfs_ends += 1\n\n    #print(\"iwfs_ends: \" + str(iwfs_ends))\n    \n    #Get number of 'end' on separate lines\n    \n\n    iquote = [i for i in range(len(code)) if code[i] == '\\'']\n    istring = [i for i in iquote if detect_string(code, i)]\n    string_ends = []\n    \n    #for i in istring:\n    #    k = next(j for j in range(i + 1,len(code)) if code[j] == '\\'' and (j + 1 == len(code) or code[j + 1] != '\\''))\n    #    string_ends.append(k)\n    #    #code = code[:i + 1] + code[k:]\n\n    #if len(istring) > 0:\n    #    ncode = code[:istring[0] + 1]\n    #    for i in range(len(istring) - 1):\n    #        ncode += code[string_ends[i]:istring[i + 1] + 1]\n\n    #    #if (string_ends[-1] + 1 < len(code)):\n    #    ncode += code[string_ends[-1]:]\n    #    code = ncode\n    \n    #lines = code.splitlines()\n    #for i in range(0,len(lines)):\n    #    #lines[i] = re.sub(r'\\'(.+)\\'',\"''\", lines[i])\n    #    #lines[i] = re.sub(r'\\\"(.+)\\\"',\"''\", lines[i])\n    #    lines[i] = lines[i].split('%')[0]\n    #code = '\\n'.join(lines)\n    \n    #esplit = code.replace(';', '\\n').replace(',','\\n').split()\n    ##elines = esplit.splitlines()\n    #num_end = 0\n    #for t in esplit:\n    #    if t == \"end\":\n    #        num_end += 1\n    #for line in elines:\n    #    if line.strip() == \"end\":\n    #        num_end += 1\n        #print(line)\n\n    \n   \n    \n\n    #print(\"num_end: \" + str(num_end))\n\n\n    #insert whos_f before return and before function ..... (here)end (next fun)\n    #Comparing num_end with num_if, num_while, num_for and switch case find if\n    #functions are ending with \"end\" keyword or not.\n\n    #flag set to true if functions end with end keyword\n    #function_end = num_end > iwfs_ends\n\n    #get number of functions in .m function file\n    num_funcs = len(program[1])\n\n    #insert whos_f before end of function or before new function\n    func_name = \"whos_f\\n\"\n\n    ids = []\n\n    for func in program[1]:\n        block = func[3]\n        block_end = block.cur + len(block.code)\n        \n        if block.is_end_terminated:\n            fs = code.rfind(\"end\", block.cur, block_end)\n            ids.append(fs)\n        else:\n            ids.append(block_end)\n\n    ids.sort()\n\n    ncode = code[:ids[0]]\n\n    for i in range(len(ids) - 1):\n        ncode = ncode + func_name + code[ids[i]:ids[i+1]]\n    ncode = ncode + func_name + code[ids[-1]:]\n    code = ncode\n    #functions end with end keyword\n    #index = len(code)\n    \n    #index = len(lines)\n    ##print(code)\n    #if function_end:\n    #    #should stop when num_funcs becomes zero\n    #    while num_funcs:\n    #        #search for keyword end\n    #        #index = code.rfind(\"end\", 0, index)\n    #        index = next(i for i in range(index - 1,-1,-1) if lines[i].strip() == 'end')\n\n    #        #add function name to code\n    #        lines = lines[:index] + [func_name] + lines[index:]\n    #        #index += len(func_name)\n\n    #        #Search for previous function\n    #        if num_funcs != 1:\n    #            #index = code.rfind(\"\\nfunction\", 0, index)\n    #            index = next(i for i in range(index - 1,-1,-1) if len(lines[i].split()) > 0 and lines[i].split()[0] == 'function')\n    #        num_funcs -= 1\n    #else:\n    #    #function does not end with end keyword\n    #    while num_funcs:\n    #        #code = code[:index] + func_name + code[index:]\n    #        lines = lines[:index] + [func_name] + lines[index:]\n\n    #        if num_funcs != 1:\n    #            #index = code.rfind(\"\\nfunction\", 0, index)\n    #            index = next(i for i in range(index - 1,-1,-1) if len(lines[i].split()) > 0 and lines[i].split()[0] == 'function')\n    #        num_funcs -= 1\n        \n\n    #print(code)\n    #code = '\\n'.join(lines)\n    return code\n"
  },
  {
    "path": "src/matlab2cpp/modify.py",
    "content": "import matlab2cpp\nimport matlab2cpp.node as nmodule\n\ndef preorder_transform_AST(node, nargin = False, suggest = False):\n    # Modify the abstract syntax tree (AST), also try to overload funtions\n    # node is project node\n    project = node.project\n    nodes = nmodule.Node.flatten(project, False, False, False)\n\n    # remove the nodes for clear, close and clc so they are not included in the translation\n    nodes = remove_close_clear_clc(nodes)\n\n    # Change right hand side variable to uvec if assigned with find, b = find(a==3)\n    if suggest:\n        nodes = modify_find(nodes)\n\n    #a multiplication with a complex double results in complex double\n    #works with fx_decon_demo.m needs more testing and maybe a refactoring\n    if suggest:\n        nodes = complex_mul(nodes)\n\n    # remove nargin if args.nargin == False, Thus by default. Use -n flag to keep nargin\n    if nargin == False:\n        project = remove_nargin(project)\n\n    # add temporary variables for multiple return function\n    project = add_parameters(project)\n\n    # change data type from real to complex, if left hand side is real and right hand side is complex in assignment\n    if suggest:\n        change_to_complex(project)\n\n    return project\n\n\ndef postorder_transform_AST(node):\n    project = node.project\n\n    # move the \"using namespace arma ;\" node last in the includes list\n    project = modify_arma_last(project)\n\n    #move #define NOMINMAX to first position\n    project = modify_define_first(project)\n\n    return project\n\n\n# node is project node\ndef change_to_complex(project):\n\n    # for each program in project\n    for idx, program in enumerate(project):\n        dictionary = program.ftypes\n        new_complex_types = {}\n        new_complex_dim = {}\n\n        # for each function (in Funcs) in program\n        for func in program[1]:\n            func_name = func.name\n\n            # flatten nodes in the function\n            nodes = func.flatten(False, False, False)\n\n            #look for assignment\n            for n in nodes:\n                if n.cls in \"Assign\" and len(n) == 2:\n                    lhs, rhs = n\n                    if lhs.mem and lhs.mem != 4 and rhs.mem == 4:\n                        lhs.mem = 4\n\n                        # add variable name as key and complex type as type\n                        if (lhs.name in new_complex_dim) and (new_complex_dim[lhs.name] < lhs.dim):\n\n                            new_complex_dim[lhs.name] = lhs.dim\n\n                            lhs.type = (lhs.dim, lhs.mem)\n                            new_complex_types[lhs.name] = lhs.type\n\n                        else:\n                            new_complex_dim[lhs.name] = lhs.dim\n                            lhs.type = (lhs.dim, lhs.mem)\n                            new_complex_types[lhs.name] = lhs.type\n\n                        dictionary[func_name][lhs.name] = new_complex_types[lhs.name]\n\n        # clear the types in the program\n        nodes = program.flatten(False, False, False)\n        for idy, node in enumerate(nodes):\n            node.type = \"TYPE\"\n\n        # use dictionary to set ftypes\n        program.ftypes = dictionary\n\n    # unset the configured flag\n    project.builder.configured = False\n\n    # configure again\n    project.builder.configure(True)\n\n    #print(dictionary)\n\n\ndef complex_mul(nodes):\n    for node in nodes:\n        if node.cls == \"Assign\":\n            lhs, rhs = node\n\n            if rhs.cls == \"Mul\":\n                if rhs[0].type == \"cx_double\":\n                    declares = node.func[0]\n\n                    for var in declares:\n                        if var.name == lhs.name:\n                            var.type = \"cx_double\"\n    return nodes\n\n\n# remove the nodes for clear, close and clc so they are not included in the translation\ndef remove_close_clear_clc(nodes):\n    for n in nodes:\n        if n.backend == \"reserved\" and n.name in (\"clear\", \"close\", \"clc\"):\n            index = n.parent.parent.children.index(n.parent)\n            del n.parent.parent.children[index]\n    return nodes\n\n\n# Change right hand side variable to uvec if assigned with find, b = find(a==3)\ndef modify_find(nodes):\n    for n in nodes:\n        if n.cls == \"Assign\":\n            lhs, rhs = n\n            if rhs.name == \"find\":\n                declares = n.func[0]\n                #print(declares.cls)\n                for var in declares:\n                    if var.name == lhs.name:\n                        var.type = \"uvec\"\n    return nodes\n\n\n# move the \"using namespace arma ;\" node last in the includes list\ndef modify_define_first(project):\n    for program in project:\n        includes = program[0]\n        index = 0\n\n        for include in includes:\n            if include != includes[0] and include.name[:7] == \"#define\":\n                define_include = includes.children.pop(index)\n                includes.children.insert(0, define_include)\n\n            index += 1\n\n    return project\n\n\n# move the \"using namespace arma ;\" node last in the includes list\ndef modify_arma_last(project):\n    for program in project:\n        includes = program[0]\n        index = 0\n\n        for include in includes:\n            if include != includes[-1] and include.name == \"using namespace arma ;\":\n                #includes += [includes.pop(index)] # remove and append arma include node\n                using_arma = includes.children.pop(index)\n                includes.children.append(using_arma)\n\n            index += 1\n    return project\n\n\n# remove nargin if args.nargin == False, Thus by default. Use -n flag to keep nargin\ndef remove_nargin(project):\n    # node is project\n    for program in project:\n        # for func in funcs\n        funcs = program[1]\n        for func in funcs:\n            #print(func.summary())\n            block = func[3]\n\n            # find node.name == nargin\n            found_nargin = True\n            while found_nargin:\n                found_nargin = False\n                nodes = nmodule.Node.flatten(block, False, False, False)\n\n                # remove if node.group is branch\n                for n in nodes:\n                    if n.name == \"nargin\":\n                        # remove branch\n                        if n.group.cls in (\"Branch\", \"Switch\"):\n                            parent = n.group.parent\n                            # print(parent.summary())\n                            del parent.children[parent.children.index(n.group)]\n                            # node.group.parent.children.index(node.group)\n                            found_nargin = True\n                            break\n                        else: # node.group is not a branch\n                            found_nargin = False\n                            break\n    return project\n\n\n# add temporary variables for multiple return function\ndef add_parameters(project):\n    nodes = nmodule.Node.flatten(project, False, False, False)\n    for n in nodes:\n        if n.cls == \"Get\" and n.backend == \"func_returns\":\n            func_name = n.name\n\n            func_ret_num = 0\n            if n.parent.cls in (\"Assign\", \"Assigns\"):\n\n                for sub_node in n.parent:\n                    if sub_node.cls != \"Get\":\n                        func_ret_num += 1\n                    else:\n                        break\n            #print(n.summary())\n\n            # find the multiple return function\n            # Check if function is in the same program\n\n            # Look first for function in current file\n            funcs = n.program[1]\n            found_func = False\n            func = []\n            for f in funcs:\n                if f.name == n.name:\n                    func_found = True\n                    #programs = n.program\n                    func = f\n\n            # Look for function in external file\n            if found_func == False:\n                for program in n.project:\n                    f = program[1][0]\n                    if f.name == n.name:\n                        func = f\n                        break\n                #programs  = [p[1][0] for p in project if p[1][0]= n.program]\n\n\n            # add needed temporary variables to params\n            if func:\n                return_params = func[1]\n                # dictionary which is used as a counter\n                type_counter = {\"int\" : 0, \"float\" : 0, \"double\" : 0, \"uword\" : 0, \"cx_double\" : 0,\n                \"ivec\" : 0, \"fvec\" : 0, \"uvec\" : 0, \"vec\" : 0, \"cx_vec\" : 0,\n                \"irowvec\" : 0, \"frowvec\" : 0, \"urowvec\" : 0, \"rowvec\" : 0, \"cx_rowvec\" : 0,\n                \"imat\" : 0, \"fmat\" : 0, \"umat\" : 0, \"mat\" : 0, \"cx_mat\" : 0,\n                \"icube\" : 0, \"fcube\" : 0, \"ucube\" : 0, \"cube\" : 0, \"cx_cube\" : 0}\n\n                # add or reuse variables, also add change\n                while func_ret_num < len(return_params):\n                    if return_params[func_ret_num].type not in (\"TYPE\", \"string\"):\n                        type_counter[return_params[func_ret_num].type] += 1\n                        name = \"_tmp_\" + return_params[func_ret_num].type + \\\n                               str(type_counter[return_params[func_ret_num].type])\n\n                        # Allocate Var node. n.parent is the assign node\n                        swap_var = matlab2cpp.collection.Var(n.parent, name)\n                        swap_var.type = return_params[func_ret_num].type\n                        swap_var.backend = return_params[func_ret_num].backend\n                        swap_var.create_declare()\n\n                        # swap Var and Get (function_returns)\n                        n.parent.children[func_ret_num] = swap_var\n                        n.parent.children[-1] = n\n\n                    #index += 1\n                    func_ret_num += 1\n    return project\n"
  },
  {
    "path": "src/matlab2cpp/mwhos.py",
    "content": "code=r\"\"\"function whos_f()\n    %Static variables\n    %persistent l %cellFile counter\n    %persistent m %cellFunc counter\n    %persistent cellFile\n    %persistent cellFunc\n\n    %initialize counter k\n    %if isempty(l)\n    %    l = 1;\n    %    m = 1;\n    %end\n\n    %Get info about caller, filename\n    ST = dbstack();\n    if (length(ST) >= 2)\n        file = strcat(ST(2).file, '.txt');\n    else\n        file = 'command_window.txt';\n    end\n    \n    if (length(ST) > 2)\n        func = ['#function_name: ', ST(2).name];\n    elseif (length(ST) == 2)\n        func = ['#function_name: ' , ST(2).name, ', main'];\n    else\n        func = '#command window:';\n    end\n    \n    %should only run this function once for every function in file\n    %if(~any(ismember(file, cellFile)) || ~any(ismember(func, cellFunc)))\n        %Calls whos on caller workspace, then processes and prints the data\n        cmdstr = 'whos;';\n        my_vars = evalin('caller', cmdstr) ; \n\n        %numer of workspace variables\n        Nvars = size(my_vars, 1);\n\n        %fprintf('#name, size, class, complex, integer\\n')\n        str = sprintf('%s\\n%s', func, '#name, size, class, complex, integer');\n        for j = 1:Nvars\n            %Test if all values are integer in variable, variable comes from caller workspace\n            name = my_vars(j).name;\n            cmd = ['all(' name ' == double(uint64(' name ')));'];\n            \n            %got error with struct, so I test if it works\n            try\n                integer = evalin('caller', cmd);\n            catch\n                integer = -1;\n            end\n            \n            if (integer ~= -1)\n                %Have to call all one more time for matrixes, two for cubes\n                while (length(integer) > 1)\n                    integer = all(integer); \n                end\n\n                %Print the fields in the struct\n                %fprintf('%s,%dx%d, %s, %d, %d\\n', ...\n                %        name, my_vars(j).size, my_vars(j).class, ...\n                %        my_vars(j).complex, integer)\n                temp = sprintf('\\n%s, %dx%d, %s, %d, %d', ...\n                                name, my_vars(j).size, my_vars(j).class, ...\n                                 my_vars(j).complex, integer);\n                str = [str, temp];\n            end\n        end\n\n        %check if written to file, if not, new file, else append\n        %if (~ismember(file, cellFile))\n        %    cellFile{l} = file;\n        %    l = l + 1;\n        %    fp = fopen(file, 'w');\n        %else\n            fp = fopen(file, 'a');\n            fprintf(fp, '\\n');\n        %end\n\n        %add function to static cellarray cellFunc\n        %cellFunc{m} = func; \n        %m = m + 1;\n        \n        %write whos to file\n        fprintf(fp, '%s\\n', str);\n        fclose(fp);\n    %end\nend\n\"\"\"\n"
  },
  {
    "path": "src/matlab2cpp/mwrapmat.py",
    "content": "try:\n    import mlabraw\nexcept:\n    pass\n\nclass Wrapmat:\n    #run matlab code with mlabraw\n    def __init__(self):\n        #get matlab session\n        try:\n            self.session = mlabraw.open()\n        except Exception as e:      \n            print(\"Error: %s\" % str(e))\n        \n    def __del__(self):\n        mlabraw.close(self.session)\n    \n    def eval_code(self, builder):\n        self.builder = builder\n    \n        #should get a list of func names\n        func_names = []\n        for program in builder.project:\n            print(program.summary())\n            #flatten tree and find Func.names\n            nodes = program.flatten(False, False, False)\n            for node in nodes:\n                if node.cls == \"Func\":\n                    func_names.append(node.name)\n        \n        #print(func_names)\n        self.func_names = func_names\n        self.called_func_names = []\n        \n        #check if main\n        func = builder[0][1][0]\n        \n        if func.name == 'main':\n            code_block = func[3]\n        \n            #evaluate, recursive function\n            self._evaluate(code_block)\n            mlabraw.eval(self.session, 'whos_f')\n        else:\n            print('matlab have to run script file')\n        \n    def _evaluate(self, code_block):\n        #eval line by line in code_block\n        for node in code_block:\n            func_nodes = []\n            #multiline code -> for, while, if, case\n            #if statement\n            \n            #one line code\n            if node.cls in ('Assign', 'Assigns', 'Statement'):\n                #flatten the node, check for function: Var/Get unknown type name\n                sub_nodes = node.flatten(False, False, False)\n                \n                #check if Var/Get unknown type name -> self written function\n                for sub_node in sub_nodes:\n                    if ((sub_node.cls == 'Get' or sub_node.cls == 'Var') and \\\n                        sub_node.backend == 'unknown' and \\\n                        sub_node.type == 'TYPE' and \\\n                        sub_node.name in self.func_names):\n                        \n                        #Test if function processed before\n                        if sub_node.name not in self.called_func_names:\n                            func_nodes.append(sub_node)\n                            self.called_func_names.append(sub_node.name)\n                \n                #loop over func_nodes\n                for func_node in func_nodes:\n                    #print(func_node.name)\n                    params = []\n                    function = False\n                    \n                    #save and store variables, if entered function\n                    # node.func.name is name of caller function\n                    mlabraw.eval(self.session, 'save mconvert_' + code_block.func.name)\n                    \n                    #clear variables, set params, Get function have params\n                    mlabraw.eval(self.session, 'clear all')\n                    \n                    #find function node that is called\n                    #check current file for function -> code_block\n                    funcs = code_block.func.parent #funcs\n                    for func in funcs:\n                        if func_node.name == func.name:\n                            new_code_block = func[3]\n                            function = True\n                    \n                    #check other file for function -> code_block\n                    if not function:\n                        for program in node.project:\n                            func = program[1][0]\n                            if func_node.name == func.name:\n                                params = func[2]\n                                new_code_block = func[3]\n                                function = True\n                    \n                    #set params\n                    for var, param in zip(func_node, params):\n                        my_string = \"load (\\'mconvert_\" + code_block.func.name + \"\\', \\'\" + var.name + \"\\')\"\n                        mlabraw.eval(self.session, my_string)\n                        \n                        mlabraw.eval(self.session, param.name + ' = ' + var.name)\n\n                        if var.name != param.name:\n                            mlabraw.eval(self.session, 'clear ' + var.name)\n                    \n                    #jump into code_block of the function\n                    self._evaluate(new_code_block)\n                    \n                    mlabraw.eval(self.session, 'whos_f')\n                    #load previous variables\n                    mlabraw.eval(self.session, 'clear all')\n                    mlabraw.eval(self.session, 'load mconvert_' + code_block.func.name)\n                    \n            #eval code line\n            mlabraw.eval(self.session, node.code)\n"
  },
  {
    "path": "src/matlab2cpp/node/__init__.py",
    "content": "\"\"\"\nThe module contains the following submodules.\n\"\"\"\nfrom .frontend import Node\n\n__all__ = [\"Node\"]\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/node/backend.py",
    "content": "import logging\nimport re\nimport os\nfrom os.path import sep\n\nimport matlab2cpp\nfrom . import m2cpp\nimport matlab2cpp.pyplot\n\nfrom . import reference\n\ndef flatten(node, ordered=False, reverse=False, inverse=False):\n    \"\"\"\nBackend for the :py:func:`~matlab2cpp.Node.flatten` function.\n\nArgs:\n    node (Node): Root node to start from\n    ordered (bool): If True, make sure the nodes are hierarcically ordered.\n    reverse (bool): If True, children are itterated in reverse order.\n    inverse (bool): If True, tree is itterated in reverse order.\n\nSee also:\n    :py:func:`~matlab2cpp.Node.flatten`\n    \"\"\"\n\n    o = bool(ordered)\n    r = bool(reverse)\n    i = bool(inverse)\n\n    out = []\n\n    if o:\n\n        nodes = [node]\n        for node in nodes:\n            nodes.extend(node.children[::1-2*(r ^ i)])\n        out.extend(nodes[::1-2*i])\n\n    else:\n\n        if i:\n            def foo(node):\n                for child in node[::1-2*r]:\n                    foo(child)\n                out.append(node)\n\n        else:\n            def foo(node):\n                out.append(node)\n                for child in node[::1-2*r]:\n                    foo(child)\n\n        foo(node)\n\n    return out\n\n\ndef summary(node, opt):\n    \"\"\"\nBackend for creating summary of the node tree.\nSee :py:func:`~matlab2cpp.qtree` for behavior.\n\nArgs:\n    node (Node): Relative root of the tree\n\nReturns:\n    str: string representation of the node\n\nSee also:\n    :py:func:`~matlab2cpp.qtree`\n    \"\"\"\n    \n    nodes = flatten(node, False, False, False)\n\n    if not (opt is None) and opt.disp:\n        print(\"iterating over %d nodes\" % len(nodes))\n\n    \n    if not (opt is None) and not (opt.line is None):\n        for node in nodes:\n            if node.cls != \"Block\" and node.line == opt.line:\n                nodes = flatten(node, False, False, False)\n                break\n\n    indent = []\n    outl = []\n\n    nl = len(str(nodes[-1].line))+1\n    nc = len(str(nodes[-1].cur+1))+1\n\n    for node in nodes:\n\n        out = \"\"\n\n        if node.line:\n            nl_ = len(str(node.line))\n            out += \" \"*(nl-nl_) + str(node.line) + \" \"\n            nc_ = len(str(node.cur+1))\n            out += \" \"*(nc-nc_) + str(node.cur+1)\n        else:\n            out += \" \"*(nl+nc+1)\n\n        # indentation\n        while indent and not (node.parent is indent[-1]):\n            indent.pop()\n        out += \"| \"*(len(indent))\n        indent.append(node)\n\n        out += node.cls.ljust(11)\n        out += node.backend.ljust(13)\n        \n        # define type\n        if node.type == \"TYPE\":\n            type = node.declare.prop.get(\"suggest\", \"TYPE\")\n            if type != \"TYPE\":\n                type = \"(\" + type + \")\"\n        else:\n            type = node.type\n        out += type.ljust(8)\n        out += node.name\n\n        outl.append(out)\n\n    out = \"\\n\".join(outl)\n\n    out = re.sub(r\"(\\\\n){2,}\", \"\", out)\n\n    return out\n\n\ndef auxillary(node, type, convert):\n    \"\"\"\nBackend for the :py:func:`~matlab2cpp.Node.auxillary` function.\n\nArgs:\n    node (Node):\n        Root of the tree where split into new line will occour.\n    type (str, None):\n        If provided, auxiliary variable type will be converted\n    convert (bool):\n        If true, add an extra function call ``conv_to`` to convert datatype in\n        Armadillo.\n\nSee also:\n    :py:func:`~matlab2cpp.Node.auxiliary`\n    \"\"\"\n\n    assert node.parent.cls != \"Assign\",\\\n            \".auxiliary() must be triggered mid expression.\"\n\n    type = type or node.type\n\n    if not isinstance(type, str):\n        if isinstance(type[0], int):\n            type = matlab2cpp.datatype.get_name(*type)\n        else:\n            type = matlab2cpp.datatype.common_strict(type)\n\n    matrix_mode = False\n    if node.cls == \"Matrix\":\n        matrix_mode = True\n\n    if matrix_mode and type == \"int\" and node.group.cls in (\"Get\", \"Set\"):\n        type = \"uword\"\n\n    line = node\n    while line.parent.cls != \"Block\":\n        line = line.parent\n    block = line.parent\n\n    # Create new var\n    i = 1\n    declares = node.func[0]\n    while \"_aux_\" + type + \"_\" + str(i) in declares:\n        i += 1\n    var = \"_aux_\" + type + \"_\" + str(i)\n\n    # Create Assign\n    assign = matlab2cpp.collection.Assign(block, code=node.code)\n    assign.type = type\n    if matrix_mode:\n        assign.backend = \"matrix\"\n\n    # Return value\n    aux_var = matlab2cpp.collection.Var(assign, var)\n    aux_var.type = type\n    aux_var.backend = type\n    aux_var.create_declare()\n\n    if convert:\n        rhs = matlab2cpp.collection.Get(assign, \"_conv_to\")\n        rhs.type = type\n    else:\n        rhs = assign\n\n    swap_var = matlab2cpp.collection.Var(rhs, var)\n    swap_var.declare.type = type\n\n    # Place Assign correctly in Block\n    i = block.children.index(line)\n    block.children = block[:i] + block[-1:] + block[i:-1]\n\n    # Swap node and Var\n    index = node.parent.children.index(node)\n    node.parent.children[index] = swap_var\n    rhs.children[-1] = node\n\n    swap_var.parent, node.parent = node.parent, swap_var.parent\n\n    # generate code\n    node.translate()\n    swap_var.translate(only=True)\n    aux_var.translate(only=True)\n    if convert:\n        rhs.translate(only=True)\n    assign.translate(only=True)\n\n    if convert:\n        assert node.type != swap_var.type\n\n    return swap_var\n\n\n\ndef resize(node):\n    \"\"\"\nBackend for the :py:func:`~matlab2cpp.Node.resize` function.\n\nArgs:\n    node (Node): node to be resized\n\nSee also:\n    :py:func:`~matlab2cpp.Node.resize`\n    \"\"\"\n\n    if \"_resize\" in node.prop:\n        return\n    node[\"_resize\"] = True\n\n    type = node.type\n    node.dim = 3\n\n    line = node\n    while line.parent.cls != \"Block\":\n        line = line.parent\n\n    resize = matlab2cpp.collection.Resize(line.parent, name=node.name)\n    resize.type = type\n\n    i = line.parent.children.index(line)\n\n    ps = line.parent.children\n    line.parent.children = ps[:i] + ps[-1:] + ps[i:-1]\n\n    resize.translate(False, only=True)\n\n\ndef error(node, msg, onlyw=False):\n    \"\"\"\nAdd an error or warning to the log subtree.\n\nArgs:\n    node (Node): node where error occoured\n    msg (str): error message content\n    onlyw (bool): if true, use warning instead of error\n\nSee also:\n    :py:func:`~matlab2cpp.Node.error`\n    :py:func:`~matlab2cpp.Node.warning`\n    \"\"\"\n\n    msg = msg % node.properties()\n\n    code = node.program.code\n    cur = node.cur\n    end = cur+len(node.code)\n\n    start = cur\n    while code[start] != \"\\n\" and start != 0:\n        start -= 1\n\n    if end >= len(code):\n        end = len(code)-1\n    finish = end\n    while code[finish] != \"\\n\" and finish != len(code)-1:\n        finish += 1\n    code = code[start:finish]\n\n    pos = cur-start\n\n    name = node.cls + \":\" + str(cur)\n\n    errors = node.program[5]\n\n    if name in errors.names:\n        return\n\n    if onlyw:\n        err = matlab2cpp.collection.Warning(errors, name=name, line=node.line,\n                cur=pos, value=msg, code=code)\n    else:\n        err = matlab2cpp.collection.Error(errors, name=name, line=node.line,\n                cur=pos, value=msg, code=code)\n    err.backend=\"program\"\n\n\ndef create_declare(node):\n    \"\"\"\nBackend for the :py:func:`~matlab2cpp.Node.create_declare` function.\n\nArgs:\n    node (Node): Node to create declare from\n\nReturns:\n    Node : the (newly) declared node\n    \"\"\"\n\n    if not (node is node.declare):\n        return node\n\n    if node.cls in reference.structvars:\n        if node.cls in (\"Nget\", \"Nset\"):\n            if node[0].cls == \"String\":\n                return None\n            value = node[0].value\n        else:\n            value = node.value\n\n        structs = node.program[3]\n        assert structs.cls == \"Structs\"\n\n        if node not in structs:\n            struct = matlab2cpp.collection.Struct(structs, name=node.name)\n        else:\n            struct = structs[node]\n\n        if value in struct.names:\n            return struct[struct.names.index(value)]\n\n        declares = node.func[0]\n\n        if node.cls in (\"Sset\", \"Sget\"):\n            sname = \"_size\"\n            if sname not in struct.names:\n                matlab2cpp.collection.Counter(struct, sname, value=\"100\")\n\n            if node.name not in declares.names:\n                var = matlab2cpp.collection.Var(declares, name=node.name, value=value)\n                var.type=\"structs\"\n        else:\n            if node.name not in declares.names:\n                var = matlab2cpp.collection.Var(declares, name=node.name, value=value)\n                var.type=\"struct\"\n\n        return matlab2cpp.collection.Var(struct, name=value)\n        parent = struct\n\n    else:\n        parent = node.func[0]\n\n    if node in parent:\n        declare = parent[node]\n        declare.type = node.type\n        declare.pointer = node.pointer\n        return declare\n\n    out = matlab2cpp.collection.Var(parent, name=node.name,\n            pointer=node.pointer, value=node.value)\n    out.type = node.type\n    return out\n\n\ndef suggest_datatype(node):\n    \"\"\"\nBackend for the :py:func:`~matlab2cpp.Node.suggest_datatype` function.\n\nArgs:\n    node (Node): Node to suggest datatype for.\n\nReturns:\n    (tuple): Suggestion on the form ``(dim, mem)``\n\nSee also:\n    :py:func:`~matlab2cpp.Node.suggest_datatype`\n    \"\"\"\n\n    if node.group.cls in (\"Transpose\", \"Ctranspose\"):\n\n        dim, mem = suggest_datatype(node.group)\n        if dim == 1:\n            dim = 2\n        elif dim == 2:\n            dim = 2\n        return dim, mem\n\n    elif node.group.cls == \"Assign\":\n\n        if node.group[0].num:\n            return node.group[0].dim, node.group[0].mem\n\n    elif node.group.cls == \"Matrix\":\n\n        mems = set([])\n        if node.group.value: # decomposed\n\n            ax0, ax1 = len(node.group), len(node.group[0])\n            if ax0 > 1:\n                if ax1 > 1:\n                    dim = 3\n                else:\n                    dim = 1\n            else:\n                if ax1 > 1:\n                    dim = 2\n                else:\n                    dim = 0\n\n            for vec in node.group:\n                for elem in vec:\n                    if elem.num:\n                        mems.add(elem.mem)\n\n        # rowvec definition\n        elif len(node.group) == 1:\n\n            if len(node.group[0]) == 1:\n                return None, None\n\n            for elem in node.group[0]:\n                if elem.num:\n                    mems.add(elem.mem)\n            dim = 3\n            \n        # colvec definition\n        elif len(node.group[0]) == 1:\n\n            for vec in node.group:\n                if vec[0].num:\n                    mems.add(vec[0].mem)\n\n            dim = 3\n\n        else:\n\n            for vec in node.group:\n                for elem in vec:\n                    if elem.num:\n                        mems.add(elem.mem)\n\n            dim = 3\n\n        if len(mems) == 1:\n            return dim, mems.pop()\n\n        elif len(mems) > 1:\n            return dim, max(*mems)\n\n        else:\n            return None, None\n\n\n    return None, None\n\n\n# small hack to ensure that log isn't cleaned mid translation\nmid_translation = [0]\ndef translate(node, opt=None):\n    \"\"\"\nBackend for performing translation of subtree\n\nArgs:\n    node (Node): Root of the translation\n    opt (argparse.Namespace, optional): optional arguments from frontend\n\nSee also:\n    :py:func:`~matlab2cpp.Node.translate`\n    \"\"\"\n\n    # translate for every program\n    if node.cls == \"Project\":\n        map(translate, node)\n        return node\n\n    if mid_translation[0] == 0:\n        log = node.program[5]\n        log.children = []\n\n    mid_translation[0] += 1\n\n    nodes = flatten(node, False, True, False)\n    if not (opt is None) and opt.disp:\n        print(\"iterating %d nodes\" % len(nodes))\n\n    for node in nodes[::-1]:\n        translate_one(node, opt)\n\n    mid_translation[0] -= 1\n\n    if not mid_translation[0]:\n        logs = flatten(log, False, True, False)\n        for node in logs[::-1]:\n            translate_one(node, opt)\n    \n    return node\n\n\ndef translate_one(node, opt):\n    \"\"\"\nBackend for performing translation of single node\n\nArgs:\n    node (Node): Node to perform translation on\n    opt (argparse.Namespace, optional): optional arguments from frontend\n\nSee also:\n    :py:func:`~matlab2cpp.Node.translate`\n    \"\"\"\n    logger = logging.getLogger(__name__)\n\n    # e.g. Get_a from user\n    value = node.program.parent.kws.get(node.cls+\"_\"+node.name, None)\n\n    # e.g. Get from user\n    if value is None:\n        value = node.program.parent.kws.get(node.cls, None)\n\n    if value is None:\n\n        backend = node.backend\n        if backend == \"TYPE\":\n            backend = \"unknown\"\n\n        assert \"_\"+backend in matlab2cpp.rules.__dict__, (\n            \"No rule {}; ensure your .py file is properly set up.\".format(backend))\n        try:\n            target = matlab2cpp.rules.__dict__[\"_\"+backend]\n\n        except KeyError as err:\n            logger.warning(\n                \"'%s', File %s. Datatype defined in the .py file, might be wrong.\",\n                err.message, node.file)\n            raise\n\n        specific_name = node.cls + \"_\" + node.name\n\n        # e.g. Get_a (reserved typically)\n        if specific_name in target.__dict__:\n            value = target.__dict__[specific_name]\n\n        # e.g. Get (normal behavior)\n        elif node.cls in target.__dict__:\n            value = target.__dict__[node.cls]\n\n        else:\n            print(node.program.summary())\n            raise KeyError(\n                    \"Expected to find rule for '%s' in the file '_%s.py. Crash with file: %s, on line: %s'\" %\\\n                            (node.cls, node.backend, node.file, node.line))\n\n\n    # let rule create a translation\n    if not isinstance(value, (str, list, tuple)):\n        #print(node.code)\n        #print(\"\\n\\n\")\n        value = value(node)\n\n    # not quite right format\n    if isinstance(value, (matlab2cpp.node.frontend.Node)):\n        value = str(value)\n\n    elif value is None:\n        #print(\"\\n\\nerror:\")\n        #print(node.code)\n        #print(node.parent.code)\n\n        #print(node.parent.parent.code)\n        #print(\"\\n\")\n        raise ValueError(\n\"missing return in function %s in file %s, Matlab: Crash with file: %s, on line: %s\" %\\\n(node.cls, node.backend, node.file, node.line))\n\n    node.ret = repr(value)\n\n    # interpolate tuples/lists\n    if not isinstance(value, str):\n\n        value = list(value)\n        children = [\"%(\"+str(i)+\")s\" for i in range(len(node))]\n\n        if len(value) == 2:\n            value.insert(1, \"\")\n\n        value = value[:-1] + [value[-2]] *\\\n            (len(children)-len(value)+1) + value[-1:]\n\n        if len(children) == 0:\n            value = value[0] + value[-1]\n\n        elif len(children) == 1:\n            value = value[0] + children[0] + value[-1]\n\n        else:\n\n            out = value[0]\n            for i in range(len(children)):\n                out += children[i] + value[i+1]\n            value = out\n\n    # interpolate string\n    try:\n        value = value % node.properties()\n    except:\n\n        #print(\"..........\")\n        #print(node.code)\n        #print(\"----------\")\n        #print(\"\\n\\n\")\n        raise SyntaxError(\"interpolation in \" + node.backend + \".\" +\\\n                node.cls + \" is misbehaving\\n'\" + value + \"'\\n\" +\\\n                str(node.prop)  + \"\\nCrash with file: \" + str(node.file) + \" , on line: \" + str(node.line) +\\\n                \":\\n\" + node.code)\n\n    if node.cls in (\"Assign\", \"Assigns\", \"Statement\", \"If\", \"Elif\",\n                    \"For\", \"Parfor\", \"While\") and node.project.builder.original:\n        code_tmp = [\"// \" + line for line in node.code.splitlines()]\n        value = \"\\n\".join(code_tmp) + \"\\n\" + value\n        value = value.replace(\"%\", \"__percent__\")\n    node.str = value\n\n\n#wanted a static variable in function include below\ncreated_file = []\ndef include(node, name, **kws):\n    \"\"\"\nBackend for the :py:func:`~matlab2cpp.Node.include` function.\n\nArgs:\n    node (Node): node in program where to where the header is placed\n    name (str): name of header\n    **kws (str, optional): Optional args for header. Mostly not in use.\n\nSee also:\n    :py:func:`~matlab2cpp.Node.include`\n    \"\"\"\n\n    if os.path.isfile(name):\n\n        #name = os.path.relpath(name, os.path.dirname(node.program.name))\n        name = os.path.basename(name)\n        include_code = '#include \"%s.hpp\"' % name\n        library_code = \"\"\n\n        if node.name == name:\n            include_code = \"\"\n\n    else:\n\n        library_code = \"\"\n        if name == \"SPlot\":\n            include_code = '#include \"SPlot.h\"'\n\n            #check if file in directory\n            try:\n                #file_path = node.program[1].name\n                #index = file_path.rindex(sep)\n                #output_file_path = file_path[:index] + sep + \"SPlot.h\"\n                output_file_path = os.getcwd() + sep + \"SPlot.h\"\n\n                #if mconvert.h not found in directory, create the file\n                if not os.path.isfile(output_file_path) or \"SPlot.h\" not in created_file:\n                    f = open(output_file_path, \"w\")\n                    f.write(matlab2cpp.pyplot.code)\n                    f.close()\n                    created_file.append(\"SPlot.h\")\n            except:\n                pass\n                \n\n        elif name == \"m2cpp\":\n            include_code = '#include \"mconvert.h\"'\n\n            #check if file in directory\n            try:\n                #file_path = node.program[1].name\n                #index = file_path.rindex(sep)\n                #output_file_path = file_path[:index] + sep + \"mconvert.h\"\n                output_file_path = os.getcwd() + sep + \"mconvert.h\"\n\n                #if mconvert.h not found in directory, create the file\n                if not os.path.isfile(output_file_path) or \"mconvert.h\" not in created_file:\n                    f = open(output_file_path, \"w\")\n                    f.write(matlab2cpp.m2cpp.code)\n                    f.close()\n                    created_file.append(\"mconvert.h\")\n            except:\n                pass\n                \n        elif name == \"arma\":\n            include_code = \"#include <armadillo>\"\n        elif name == \"iostream\":\n            include_code = \"#include <iostream>\"\n        elif name == \"cstdio\":\n            include_code = \"#include <cstdio>\"\n        elif name == \"complex\":\n            include_code = \"#include <complex>\"\n        elif name == \"cmath\":\n            include_code = \"#include <cmath>\"\n        elif name == \"algorithm\":\n            include_code = \"#include <algorithm>\"\n        elif name == \"omp\":\n            include_code = \"#include <omp.h>\"\n        elif name == \"tbb\":\n            include_code = \"#include <tbb/tbb.h>\"\n        elif name == \"no_min_max\":\n            include_code = \"#define NOMINMAX\"\n        else:\n            include_code = \"\"\n\n    includes = node.program[0]\n    if include_code and include_code not in includes.names:\n        include = matlab2cpp.collection.Include(includes, include_code,\n                value=includes.value)\n        include.backend=\"program\"\n\n    #node.program[2] is inlines. I don't think inlines are used anymore\n    #if you look at variable library_code above, it is set to \"\"\n    inlines_ = node.program[2]\n    if library_code and library_code not in inlines_.names:\n        inline = matlab2cpp.collection.Inline(inlines_, library_code)\n        inline.backend=\"program\"\n\n\ndef wall_clock(node):\n    \"\"\"\nBackend for the :py:func:`~matlab2cpp.Node.wall_clock` function.\n\nArgs:\n    node (Node):\n        node in function where ``wall_clock _timer`` should be declared.\n\nSee also:\n    :py:func:`~matlab2cpp.Node.wall_clock`\n    \"\"\"\n    declares = node.func[0]\n    if \"_timer\" not in declares:\n        clock = matlab2cpp.collection.Var(declares, name=\"_timer\")\n        clock.type=\"wall_clock\"\n\n\ndef plotting(node):\n    \"\"\"\nBackend of the :py:func:`~matlab2cpp.Node.plotting` function.\n\nArgs:\n    node (Node): node in the function where plotting should be implemented.\n\nSee also:\n    :py:func:`~matlab2cpp.Node.plotting`\n    \"\"\"\n\n    declares = node.func[0]\n\n    # only do this once\n    if \"_plot\" in declares:\n        return\n\n    # add splot to header\n    node.include(\"SPlot\")\n\n    # add a variable for Splot in declare\n    var = matlab2cpp.collection.Var(declares, name=\"_plot\")\n    var.type = \"SPlot\"\n\n    # get function variable\n    func = node.func\n    \n    # get function block\n    block = func[3]\n\n    # create new statement\n    statement = matlab2cpp.collection.Statement(block, code=\"\")\n    statement.backend=\"code_block\"\n    # fill it with new Get _splot\n    get = matlab2cpp.collection.Get(statement, name=\"_splot\")\n    get.backend=\"reserved\"\n\n    # translate the new nodes\n    statement.translate()\n\n    # swap with last statement, if it is a return-statement\n    if len(block)>1 and block[-2] and block[-2][0].cls == \"Return\":\n        block.children[-1], block.children[-2] = \\\n                block.children[-2], block.children[-1]\n\n"
  },
  {
    "path": "src/matlab2cpp/node/frontend.py",
    "content": "from . import (\n    reference as ref,\n    backend,\n)\n\nfrom .. import datatype as dt, supplement as sup\n\n\nclass Node(object):\n    \"\"\"\nA representation of a node in a node tree.\n\nAttributes:\n    backend (str):\n        The currently set translation backend. Available in  the\n        string format as `%(backend)s`.\n    children (list):\n        A list of node children ordered from first to last  child. Accessible\n        using indexing  (`node[0]`, `node[1]`, ...). Alse available in the\n        string format as `%(0)s`, `%(1)s`, ...\n    cls (str):\n        A string representation of the class name. Avalable  in the string\n        format as `%(class)s`\n    code (str):\n        The code that concived this node.\n    cur (int):\n        The index to the position in the code where this  node was concived. It\n        takes the value 0 for nodes  not created from code.\n    declare (Node):\n        A reference to the node of same name where it is  defined. This would\n        be under `Declares`, `Params`  or `Struct`. Useful for setting scope\n        defined  common datatypes. Returns itself if no declared variable has\n        the same name as current node.\n    dim (int):\n        The number of dimensions in a numerical datatype.  The values 0 through\n        4 represents scalar, column  vector, row vector, matrix and cube\n        respectively.  The value is None if datatype is not numerical.\n        Interconnected with `type`.\n    file (str):\n        Name of the program. In projects, it should be the  absolute path to\n        the Matlab source file. Available  in the string format as `%(file)s`.\n    ftypes (dict):\n        Input/output function scoped datatypes.\n    func (Node):\n        A reference to Func (function) ancestor. Uses root  if not found.\n    group (Node):\n        A reference to the first ancestor where the  datatype does not\n        automatically affect nodes  upwards. A list of these nodes are listed\n        in  `matlab2cpp.reference.groups`.\n    itype (list):\n        Input/output include scope statements\n    line (int):\n        The codeline number in original code where this  node was conceived. It\n        takes the value 0 for nodes  not created from code.\n    mem (int):\n        The amount of type-space reserved per element in a numerical datatype.\n        The value 0 through 4  represents unsigned int, int, float, double and\n        complex.  The value is None if datatype is not  numerical.\n        Interconnected with `type`.\n    name (str):\n        The name of the node. Available in the string format as `%(name)s`.\n    names (list):\n        A list of the names (if any) of the nodes children.\n    num (bool):\n        A bool value that is true if and only if the datatype is numerical.\n        Interconnected with `type`.\n    parent (Node):\n        A reference to the direct node parent above the current one.\n    pointer (int):\n        A numerical value of the reference count. The value  0 imply that the\n        node refer to the actual variable, 1 is a reference to the variable,\n        2 is a reference  of references, and so on.\n    program (Node):\n        A reference to program ancestor. Uses root if not  found.\n    project (Node):\n        A reference to root node.\n    reference (Node):\n        If node is a lambda function (backend  `func_lambda`),\n        the variable is declared locally,  but it's content might be available\n        in it's own  function.  If so, the node will have a `reference`\n        attribute to that function. Use `hasattr` to  ensure it is the case.\n    ret (tuple): The raw translation of the node. Same     as (str):\n        `node.str`, but on the exact form the tranlsation  rule returned it.\n    str (str): The translation of the node. Note that the code is  translated\n        leaf to root, and parents will not be  translated before after current\n        node is translated.  Current and all ancestors will have an empty\n        string.\n    stypes (dict): Input/Output struct scoped datatypes.\n    suggest (str): A short string representation of the suggested  datatype. It\n        is used for suggesting datatype in  general, and can only be assigned,\n        not read.  Typically only the declared variables will be read,  so\n        adding a suggestion is typically done  `node.declare.type = \"...\"`.\n    type (str): A short string representation of the nodes  datatype.\n        Interconnected with `dim`, `mem` and  `num`.  Available in string\n        format as `%(type)s`\n    value (str): A free variable resereved for content. The use  varies from\n        node to node.  Available in the string  format as `%(value)s`.\n    vtypes (dict): Verbatim translation in tree (read-only)\n    \"\"\"\n    backend = ref.Property_reference(\"backend\")\n\n    cls = ref.Property_reference(\"class\")\n    code = ref.Recursive_property_reference(\"code\")\n    cur = ref.Recursive_property_reference(\"cur\")\n\n    dim = dt.Dim()\n    #file = ref.Recursive_property_reference(\"file\")\n    file = ref.File_reference()\n    line = ref.Line_reference()\n    mem = dt.Mem()\n    name = ref.Property_reference(\"name\")\n    names = ref.Names()\n    num = dt.Num()\n    pointer = ref.Property_reference(\"pointer\")\n    ret = ref.Property_reference(\"ret\")\n    str = ref.Property_reference(\"str\")\n    suggest = dt.Suggest()\n    type = dt.Type()\n    value = ref.Property_reference(\"value\")\n\n    func = ref.Func_reference()\n    program = ref.Program_reference()\n    project = ref.Project_reference()\n    group = ref.Group_reference()\n    declare = ref.Declare_reference()\n\n    ftypes = sup.Ftypes()\n    itypes = sup.Itypes()\n    stypes = sup.Stypes()\n    vtypes = sup.Vtypes()\n\n    def __init__(self, parent=None, name=\"\", value=\"\", pointer=0,\n                 line=None, cur=None, code=None):\n        \"\"\"\n        Keyword Args:\n            code (str): source code\n            cur (int): cursor position (inherited)\n            line (int): Line number (inherited)\n            name (str): Optional name of the node\n            parent (Node): Node parent in the Node tree\n            pointer (int): is reference to object (not currently used)\n            str (str): Translation content\n            value (str): Default node content placeholder\n        \"\"\"\n        self.children = []\n        self.prop = {\"type\":\"TYPE\", \"suggest\":\"TYPE\",\n                \"value\":value, \"str\":\"\", \"name\":name,\n                \"pointer\":pointer, \"backend\":\"unknown\",\n                \"line\":line, \"cur\":cur, \"code\":code,\n                \"ret\":\"\",\n                \"class\":self.__class__.__name__}\n\n        # Parental relationship\n        self.parent = parent\n\n        if self is self.parent or (not hasattr(parent, \"children\")):\n            pass\n        else:\n            parent.children.append(self)\n\n\n    def summary(self, args=None):\n        \"\"\"\nGenerate a summary of the tree structure with some meta-information.\n\nReturns:\n    str: Summary of the node tree\n\nSee also:\n    `matlab2cpp.qtree`\n        \"\"\"\n        return backend.summary(self, args)\n\n\n    def translate(self, opt=None, only=False):\n        \"\"\"Generate code translation\n\nArgs:\n    opt (argparse.Namespace, optional): Extra arguments provided by argparse\n    only (bool): If true, translate current node only.\n        \"\"\"\n\n        # configure if not configured\n        if not self.project.builder.configured:\n            self.project.builder.configure()\n\n        if only:\n            backend.translate_one(self, opt)\n        else:\n            backend.translate(self, opt)\n\n\n    def properties(self):\n        \"\"\"\nRetrieve local node properties.\n\nThe following properties are included:\n+-------------+-------------------------------------+-----------------------------+\n| Name        | Attribute                           | Description                 |\n+=============+=====================================+=============================+\n| ``backend`` | :py:attr:`~matlab2cpp.Node.backend` | Name of translation backend |\n+-------------+-------------------------------------+-----------------------------+\n| ``class``   | :py:attr:`~matlab2cpp.Node.cls`     | Node class name             |\n+-------------+-------------------------------------+-----------------------------+\n| ``code``    | :py:attr:`~matlab2cpp.Node.code`    | Matlab code equivalent      |\n+-------------+-------------------------------------+-----------------------------+\n| ``cur``     | :py:attr:`~matlab2cpp.Node.cur`     | Position in Matlab code     |\n+-------------+-------------------------------------+-----------------------------+\n| ``line``    | :py:attr:`~matlab2cpp.Node.line`    | Line number in Matlab code  |\n+-------------+-------------------------------------+-----------------------------+\n| ``name``    | :py:attr:`~matlab2cpp.Node.name`    | Node name                   |\n+-------------+-------------------------------------+-----------------------------+\n| ``pointer`` | :py:attr:`~matlab2cpp.Node.pointer` | Pointer reference object    |\n+-------------+-------------------------------------+-----------------------------+\n| ``str``     | :py:attr:`~matlab2cpp.Node.str`     | Node translation            |\n+-------------+-------------------------------------+-----------------------------+\n| ``suggest`` | :py:attr:`~matlab2cpp.Node.suggest` | Suggested datatype          |\n+-------------+-------------------------------------+-----------------------------+\n| ``type``    | :py:attr:`~matlab2cpp.Node.type`    | Node datatype               |\n+-------------+-------------------------------------+-----------------------------+\n| ``value``   | :py:attr:`~matlab2cpp.Node.value`   | Node value                  |\n+-------------+-------------------------------------+-----------------------------+\n\nIn addition will number keys (in string format) represents the node\nchildren's ``node.str`` in order.\n\nReturns:\n    dict: dictionary with all properties and references to other assosiated\n    nodes.\n\nExample:\n    >>> var = matlab2cpp.collection.Var(None, name=\"A\", value=\"B\", line=1, cur=0, code=\"C\")\n    >>> props = var.properties()\n    >>> for key in sorted(props):\n    ...     print(\"{:<8}: {!r}\".format(key, props[key]))\n    backend : 'unknown'\n    class   : 'Var'\n    code    : 'C'\n    cur     : 0\n    line    : 1\n    name    : 'A'\n    pointer : 0\n    ret     : ''\n    str     : ''\n    suggest : 'TYPE'\n    type    : 'TYPE'\n    value   : 'B'\n        \"\"\"\n\n        prop = self.prop.copy()\n        for key in self.prop:\n            if prop[key] is None and hasattr(self, key):\n                prop[key] = getattr(self, key)\n\n        I = len(self.children)\n        for i in range(I):\n            prop[str(i)] = prop[\"-\"+str(I-i)] = self[i].prop[\"str\"]\n        return prop\n\n\n\n    def auxiliary(self, type=None, convert=False):\n        \"\"\"\nCreate a auxiliary variable and rearange nodes to but current node on its own\nline before.\n\nArgs:\n    type (str, None):\n        If provided, auxiliary variable type will be converted\n    convert (bool):\n        If true, add an extra function call ``conv_to`` to convert datatype in\n        Armadillo.\n\nExample:\n    Many statements that works inline in Matlab, must be done on multiple lines in\n    C++. Take for example the statement ``[1,2]+3``. In C++, the rowvec ``[1,2]``\n    must first be initialized and converted into ``rowvec`` before arithmetics can\n    be used::\n\n    >>> print(matlab2cpp.qscript(\"[1,2]+3\"))\n    sword __aux_irowvec_1 [] = {1, 2} ;\n    _aux_irowvec_1 = irowvec(__aux_irowvec_1, 2, false) ;\n    _aux_irowvec_1+3 ;\n\n    The difference in tree structure is as follows:\n\n    >>> print(matlab2cpp.qtree(\"[1,2]\", core=True)) # doctest: +NORMALIZE_WHITESPACE\n     1  1Block      code_block   TYPE\n     1  1| Statement  code_block   TYPE\n     1  1| | Matrix     matrix       irowvec\n     1  2| | | Vector     matrix       irowvec\n     1  2| | | | Int        int          int\n     1  4| | | | Int        int          int\n    >>> print(matlab2cpp.qtree(\"[1,2]+3\", core=True)) # doctest: +NORMALIZE_WHITESPACE\n     1  1Block      code_block   TYPE\n     1  1| Assign     matrix       int\n     1  1| | Var        irowvec      irowvec _aux_irowvec_1\n     1  1| | Matrix     matrix       irowvec\n     1  2| | | Vector     matrix       irowvec\n     1  2| | | | Int        int          int\n     1  4| | | | Int        int          int\n     1  1| Statement  code_block   TYPE\n     1  1| | Plus       expression   irowvec\n     1  1| | | Var        unknown      irowvec _aux_irowvec_1\n     1  7| | | Int        int          int\n        \"\"\"\n        return backend.auxillary(self, type, convert)\n\n\n    def resize(self):\n        \"\"\"\nResize function.\n\nVery similar to the function :py:func:`~matlab2cpp.Node.auxiliary`, but\nspecific for reshaping cubes into slices.\n\nMight need to be rewritten.\n        \"\"\"\n        backend.resize(self)\n\n    def include(self, name, **kws):\n        \"\"\"\nInclude library in the header of the file.\n\nThese include::\n\n+--------------+--------------------------+\n| Name         | Description              |\n+==============+==========================+\n| ``SPlot``    | Local SPlot library      |\n+--------------+--------------------------+\n| ``m2cpp``    | Local M2cpp library      |\n+--------------+--------------------------+\n| ``arma``     | Global Armadillo library |\n+--------------+--------------------------+\n| ``iostream`` | Global iostream library  |\n+--------------+--------------------------+\n\nArgs:\n    name (str): Name of header to include\n    **kws (str, optional): Optional args for header. Mostly not in use.\n    \"\"\"\n        backend.include(self, name, **kws)\n\n    def warning(self, msg):\n        \"\"\"\nAdd a warning to the log file.\n\nArgs:\n    msg (str): Content of the warning\n\nSee also:\n    :py:func:`~matlab2cpp.Node.error`\n    \"\"\"\n        backend.error(self, msg, True)\n\n    def error(self, msg):\n        \"\"\"\nAdd an error to the log file.\n\nArgs:\n    msg (str): Content of the error\n\nExample:\n    >>> print(matlab2cpp.qlog(\"  a\"))\n    Error in class Var on line 1:\n      a\n      ^\n    unknown data type\n    \"\"\"\n        backend.error(self, msg, False)\n\n    def create_declare(self):\n        \"\"\"\nInvestigate if the current node is declared (either in Params, Declares or in\nStructs), and create such a node if non exists in Declares.\n\nThe declared variable's datatype will be the same as current node.\n\nReturns:\n    Node : the (newly) declared node\n        \"\"\"\n        backend.create_declare(self)\n\n    def suggest_datatype(self):\n        \"\"\"\nTry to figure out from context, what the datatype should be for current node.\n\nReturns:\n    (tuple): Suggestion on the form ``(dim, mem)``\n        \"\"\"\n        return backend.suggest_datatype(self)\n\n    def wall_clock(self):\n        \"\"\"\nPrepare for the use of ``tic`` and ``toc`` functionality in code.\n\nDoes nothing if called before.\n        \"\"\"\n        return backend.wall_clock(self)\n\n    def __getitem__(self, index):\n        \"\"\"\nRetrieve node child.\n\nArgs:\n    index (int): Get node child by positional order\n    index (str): Get first instance with `node.name==index`\n    index (Node): Get first instance with `node.name==index.name`\n    index (slice): Get sublist of `node.children`\n\nExamples:\n\n    >>> node = collection.Var(None, \"a\")\n    >>> node[\"b\"]\n    Traceback (most recent call last):\n        ...\n    IndexError: node child \"b\" not found\n    >>> node[0]\n    Traceback (most recent call last):\n        ...\n    IndexError: index of Var out of range (0)\n    >>> node[()]\n    Traceback (most recent call last):\n        ...\n    TypeError: index of Var must be in (int, str, slice, Node), not tuple\n        \"\"\"\n        i = index # shorter\n        if isinstance(i, Node):\n            i = i.name\n\n        if isinstance(i, str):\n            if i not in self.names:\n                raise IndexError(\"node child \\\"%s\\\" not found\" % i)\n            i = self.names.index(i)\n\n        if isinstance(i, int):\n\n            if len(self) <= i:\n                raise IndexError(\n                        \"index of %s out of range (%d)\" % (self.cls, i))\n            return self.children[i]\n\n        if isinstance(i, slice):\n            return self.children[i]\n\n        raise TypeError(\n                \"index of %s must be in (int, str, slice, Node), not %s\" \\\n                % (self.cls, i.__class__.__name__))\n\n\n    def __contains__(self, i):\n        \"\"\"\nTest if (Node with) name ``i`` is contained in code.\n        \"\"\"\n\n        if isinstance(i, str):\n            return i in self.names\n        return i.name in self.names\n\n    def __setitem__(self, key, val):\n        self.prop[key] = val\n\n    def __len__(self):\n        return len(self.children)\n\n    def __str__(self):\n        return self.prop[\"str\"]\n\n    def __add__(self, val):\n        return str(self)+str(val)\n\n    def __radd__(self, val):\n        return str(val)+str(val)\n\n    def __iter__(self):\n        return self.children.__iter__()\n\n    def append(self, node):\n        node.children.append(node)\n\n    def pop(self, index):\n        return self.children.pop(index)\n\n    def flatten(self, ordered=False, reverse=False, inverse=False):\n        r\"\"\"\nReturn a list of all nodes\n\n| Structure:\n|   A\n|   | B\n|   | | D\n|   | | E\n|   | C\n|   | | F\n|   | | G\n|\n| Sorted [o]rdered, [r]everse and [i]nverse:\n|\n| ori\n| ___ : A B D E C F G\n| o__ : A B C D E F G\n| _r_ : A C G F B E D\n| __i : D E B F G C A\n| or_ : A C B G F E D\n| o_i : D E F G B C A\n| _ri : E D B G F C A\n| ori : G F E D C B A\n\nArgs:\n    node (Node): Root node to start from\n    ordered (bool): If True, make sure the nodes are hierarcically ordered.\n    reverse (bool): If True, children are itterated in reverse order.\n    inverse (bool): If True, tree is itterated in reverse order.\n\nReturn:\n    list: All nodes in a flatten list.\n        \"\"\"\n        return backend.flatten(self, ordered, reverse, inverse)\n\n    def plotting(self):\n        \"\"\"\nPrepare the code for plotting functionality.\n        \"\"\"\n        return backend.plotting(self)\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/node/m2cpp.py",
    "content": "code = r\"\"\"#ifndef MCONVERT_H\n#define MCONVERT_H\n\n#include <armadillo>\nusing namespace arma;\n\nnamespace m2cpp {\n\n    template<typename eT>\n    inline arma::Col<eT> scol(eT a) {\n        return arma::Col<eT>(&a, 1, true);\n    }\n\n    template<typename eT>\n    inline arma::Row<eT> srow(eT a) {\n        return arma::Row<eT>(&a, 1, true);\n    }\n\n    template<typename eT>\n    inline arma::Mat<eT> smat(eT a) {\n        return arma::Mat<eT>(&a, 1, 1, true);\n    }\n\n\n    inline arma::uvec span(int a, int b) {\n        arma::uvec s;\n        int n = b - a;\n        if (n < 0) return s;\n        s.set_size(n + 1);\n        for (int ii = 0; ii <= n; ii++)\n            s(ii) = ii + a;\n        return s;\n    }\n\n    template <typename T>\n    inline T span(int a, int b) {\n        T s;\n        int n = b - a;\n        if (n < 0) return s;\n        s.set_size(n + 1);\n        for (int ii = 0; ii <= n; ii++)\n            s(ii) = ii + a;\n        return s;\n    }\n\n    inline arma::uvec span(int a, int step, int b)\n    {\n        arma::uvec s;\n        int n = (b - a + step) / step;\n        if (n < 0)\n        {\n            return s;\n        }\n        s.set_size(n);\n\n        for (int ii = 0; ii < n; ii++)\n        {\n            s(ii) = step * ii + a;\n        }\n\n        return s;\n    }\n\n    template <typename T>\n    inline T span(int a, int step, int b)\n    {\n        T s;\n        int n = (b - a + step) / step;\n        if (n < 0)\n        {\n            return s;\n        }\n        s.set_size(n);\n\n        for (int ii = 0; ii < n; ii++)\n        {\n            s(ii) = step * ii + a;\n        }\n\n        return s;\n    }\n\n\n    template <typename T>\n    inline arma::cx_mat fft(arma::Mat<typename T::elem_type> X, int dim)\n    {\n        if (dim == 1)\n            return arma::fft(X);\n        else\n            return arma::strans(arma::fft(arma::strans(X)));\n\n    }\n\n    template <typename T>\n    inline arma::cx_mat fft(arma::Mat<typename T::elem_type> X, int n, int dim)\n    {\n        if (dim == 1)\n            return arma::fft(X, n);\n        else\n            return arma::strans(arma::fft(arma::strans(X), n));\n\n    }\n\n\n    inline arma::cx_mat ifft(arma::cx_mat X, int dim)\n    {\n        if (dim == 1)\n            X = arma::ifft(X);\n        else\n            X = arma::strans(arma::ifft(arma::strans(X)));\n        return X;\n    }\n\n    inline arma::cx_mat ifft(arma::cx_mat X, int n, int dim)\n    {\n        if (dim == 1)\n            X = arma::ifft(X, n);\n        else\n            X = arma::strans(arma::ifft(arma::strans(X), n));\n        return X;\n    }\n    \n\n    //template<typename eT>\n    inline rowvec fspan(double a, double step, double b) {\n        //arma::Col<eT> s;\n        rowvec s;\n        int n = (int) ((b - a) / step);\n        if (n < 0) return s;\n\n        //s.set_size(n + 1);\n        s.set_size(n+1);\n        for (int ii = 0; ii <= n; ii++)\n            s(ii) = step * ii + a;\n        return s;\n    }\n\n    inline int nextpow2(int n) {\n        n = abs(n);\n        int p = 0;\n        int tmp = 1;\n        while (tmp < n)\n        {\n            tmp *= 2;\n            p++;\n        }\n        return p;\n    }\n\n    template<typename T1>\n    inline T1 square(T1 a) {\n        return a*a;\n    }\n\n    template<typename T1, typename T2>\n    inline  arma::Mat<typename T1::elem_type> hankel(const T1& c_, const T2& r_) {\n\n        typedef typename T1::elem_type eT;\n\n        int nc = r_.n_elem;\n        int nr = c_.n_elem;\n\n        const arma::Col<eT> c((eT*)c_.memptr(), nr, 0);\n        const arma::Row<eT> r((eT*)r_.memptr(), nc, 0);\n\n        if (r[0] != c[0]) {\n            //(\"hankel: differing diagonal element. Using the column one\");\n        }\n\n        arma::Mat<typename T1::elem_type> retval(nr, nc);\n\n        for (int i = 1; i <= std::min(nr, nc); i++) {\n            retval.submat(1 - 1, i - 1, nr - i + 1 - 1, i - 1) = c.rows(i - 1, nr\n                                                                        - 1);\n        }\n        int tmp = 1;\n        if (nc <= nr) {\n            tmp = nr - nc + 2;\n        }\n\n        for (int i = nr; i >= tmp; i--) {\n            retval.submat(i - 1, 2 + nr - i - 1, i - 1, nc - 1) = r.cols(2\n                                                                         - 1, nc - nr + i - 1);\n        }\n        return retval;\n    }\n\n    template<typename T1>\n    inline arma::uword length(const T1& A) {\n        return A.n_elem;\n    }\n\n    /*\n    template<typename T>\n    inline arma::Mat <typename T::elem_type> convmtx(const T& v, int m) {\n\n        arma::Mat<typename T::elem_type> out = zeros(v.n_elem + m - 1, m);\n        arma::Col<typename T::elem_type> aux((typename T::elem_type*)v.memptr(), v.n_elem);\n\n        for (int ii = 0; ii < m; ii++) {\n            out.submat(ii, ii, ii + v.n_elem - 1, ii) = v;\n        }\n\n        if (v.n_rows == 1)\n            out = out.t();\n        return out;\n    }\n    */\n\n    template<typename T>\n    inline arma::Mat <typename T::elem_type> convmtx(const T& v, int m) {\n\n        arma::Mat<typename T::elem_type> out = zeros<arma::Mat<typename T::elem_type> >(v.n_elem + m - 1, m);\n        arma::Col<typename T::elem_type> aux((typename T::elem_type*)v.memptr(), v.n_elem);\n\n        if (v.n_rows == 1)\n        {\n            for (int ii = 0; ii < m; ii++) {\n                out.submat(ii, ii, ii + v.n_elem - 1, ii) = aux;\n            }\n        }\n        else\n        {\n            for (int ii = 0; ii < m; ii++) {\n                out.submat(ii, ii, ii + v.n_elem - 1, ii) = v;\n            }\n        }\n\n        if (v.n_rows == 1)\n            out = out.t();\n        return out;\n    }\n\n    template <typename eT>\n    inline typename arma::enable_if2< arma::is_real<typename eT::elem_type>::value, typename arma::Mat<typename eT::elem_type> >::result\n    conv2(const arma::Mat<typename eT::elem_type>& A, const arma::Mat<typename eT::elem_type>& B) {\n        uword n = A.n_rows + B.n_rows - 1;\n        uword m = A.n_rows + B.n_rows - 1;\n\n        arma::Mat<typename eT::elem_type> out = arma::real(arma::ifft2(fft2(A, n, m) % fft2(B, n, m)));\n        return out;\n    }\n\n    template <typename eT, typename fT>\n    inline typename arma::enable_if2 < arma::is_complex<typename eT::elem_type>::value || arma::is_complex<typename fT::elem_type>::value,\n                                       arma::Mat<typename std::complex< typename arma::get_pod_type<eT>::result > > >::result\n        conv2(const arma::Mat<typename eT::elem_type>& A, const arma::Mat<typename fT::elem_type>& B) {\n        uword n = A.n_rows + B.n_rows - 1;\n        uword m = A.n_rows + B.n_rows - 1;\n\n        arma::Mat<typename eT::elem_type> out = arma::ifft2(fft2(A, n, m) % fft2(B, n, m));\n        return out;\n    }\n\n    template <typename eT>\n    inline eT fix(const eT a) {\n       return a > eT(0) ? floor(a) : ceil(a);\n    }\n\n    template<typename T>\n    inline void intersect(arma::Col<typename T::elem_type>& C, arma::uvec& ia, arma::uvec& ib, const T& a, const T& b) {\n\n       typedef typename T::elem_type eT;\n\n       arma::uvec sa = arma::sort_index(a);\n       arma::uvec sb = arma::sort_index(b);\n\n       std::vector<eT> C_;\n       std::vector<arma::uword> ia_, ib_;\n\n       int na = int(a.n_elem);\n       int nb = int(b.n_elem);\n       int ja = 0, jb = 0;\n\n       for (;;) {\n\n          arma::uword sja = sa(ja);\n          arma::uword sjb = sb(jb);\n\n          eT ca = a(sja);\n          eT cb = b(sjb);\n\n          if (ca > cb) {\n             ja++;\n          }\n          else if (cb > ca) {\n             jb++;\n          }\n          else {\n             C_.push_back(ca);\n             ia_.push_back(sja);\n             ib_.push_back(sjb);\n             while (++ja < na && a(sa(ja)) == ca) {}\n             while (++jb < nb && b(sb(jb)) == cb) {}\n             if (ja == na || jb == nb)\n                break;\n          }\n\n       }\n\n       ia = arma::uvec(ia_) + 1;\n       ib = arma::uvec(ib_) + 1;\n       C = arma::Col<eT>(C_);\n    }\n\n    template<typename T>\n    inline void intersect(arma::Col<typename T::elem_type>& C, const T& a, const T& b) {\n       arma::uvec dum0, dum1;\n       intersect(C, dum0, dum1, a, b);\n    }\n\n    template<typename Tr, typename T>\n    inline void unique_rows_core(Tr& C, Tr& a_sorted, arma::uvec& ia, const T& a) {\n\n       typedef typename T::elem_type eT;\n\n       int ic_cur = 0;\n\n       auto cmp = [&a, &ic_cur](const int k, const int l) -> bool {\n          return a(k, ic_cur) < a(l, ic_cur);\n       };\n\n       int nr = int(a.n_rows);\n       int nc = int(a.n_cols);\n\n       arma::Col<eT> ac0(const_cast<eT*>(a.colptr(0)), nr, false);\n       arma::uvec ord = arma::sort_index(a.col(0));\n       std::vector<arma::uword> ia0, ia1;\n\n       std::vector<arma::uword>* ia_ = &ia0;\n       std::vector<arma::uword>* ia_prev_ = &ia1;\n\n       ia_->push_back(0);\n       for (int ii = 1; ii < nr; ii++) {\n          if (a(ord(ii), 0) != a(ord(ii - 1))) {\n             ia_->push_back(ii);\n          }\n       }\n       ia_->push_back(nr);\n\n       for (int ic = 1; ic < nc; ic++) {\n\n          ic_cur = ic;\n          int ir = 0, ir_prev = 0;\n          std::swap(ia_prev_, ia_);\n          int na = int(ia_prev_->size());\n          ia_->clear();\n\n          for (int ii = 0; ii < na - 1; ii++) {\n             ia_->push_back((*ia_prev_)[ii]);\n             int l = (*ia_prev_)[ii], u = (*ia_prev_)[ii + 1];\n             std::sort(&ord(l), &(ord(u - 1)) + 1, cmp);\n             for (int jj = l + 1; jj < u; jj++) {\n                if (a(ord(jj - 1), ic) != a(ord(jj), ic)) {\n                   ia_->push_back(jj);\n                }\n             }\n          }\n\n          ia_->push_back(nr);\n\n       }\n\n       ia = arma::uvec(*ia_);\n       int na = int(ia.n_elem);\n       C.set_size(na - 1, a.n_cols);\n\n       for (int ii = 0; ii < na - 1; ii++) {\n          C.row(ii) = a.row(ord(ia(ii)));\n       }\n\n       a_sorted.set_size(nr, nc);\n       for (int ir = 0; ir < nr; ir++) {\n          a_sorted.row(ir) = a.row(ord(ir));\n       }\n    }\n\n    template<typename T>\n    inline T sortrows(const T& a) {\n\n       typedef typename T::elem_type eT;\n       arma::uvec dum0;\n       arma::Mat<eT> dum1;\n       arma::Mat<eT> ret;\n       unique_rows_core(dum1, ret, dum0, a);\n       return ret;\n    }\n\n    template<typename T>\n    inline void unique_rows(T& C, const T& a) {\n\n       arma::uvec dum;\n       unique_rows(C, dum, a);\n\n    }\n\n    template<typename T>\n    inline T unique_rows(const T& a) {\n       T ret;\n       unique_rows(ret, a);\n       return ret;\n    }\n\n    template<typename T>\n    inline int isempty(const T& a) {\n        return a.n_elem == 0;\n    }\n\n    template<typename T>\n    inline void unique(T& a, const T& b, const char* m) {\n        T tmp;\n        const T& in = b;\n        if (&a == &b) {\n           tmp = b;\n           in = tmp;\n        }\n\n        if (strcmp(m, \"rows\") == 0) {\n           unique_rows(a, tmp);\n        }\n        else {\n           fprintf(stderr, \"m2pp::unique(): Unrecognized option %s\\n\", m);\n        }\n    }\n\n    static arma::wall_clock timer_;\n\n    inline double tic() {\n       timer_.tic();\n       return timer_.toc();\n    }\n\n    inline double toc() {\n       return timer_.toc();\n    }\n\n    inline double toc(double start) {\n       return timer_.toc() - start;\n    }\n}\n\n\n#endif\n\n\n\"\"\"\n"
  },
  {
    "path": "src/matlab2cpp/node/reference.py",
    "content": "\"\"\"\nEach node has a set of attributes that allows for quick access to properties and\nother node of interest.  For example, if `node` has a name, it can be referred\nto by `node.name`.  Another example is to access the parent node by\n`node.parent`.\n\nNote that, if a reference does not exist, the node itself will be returned.\n\"\"\"\n\ngroups = [\n    \"Assign\", \"Assigns\", \"Branch\", \"For\", \"Func\", \"Main\",\n    \"Set\", \"Cset\", \"Fset\", \"Nset\", \"Sset\",\n    \"Get\", \"Cget\", \"Fget\", \"Nget\", \"Sget\",\n    \"Statement\", \"Switch\", \"Tryblock\", \"Matrix\",\n    \"While\", \"Block\", \"Node\", \"Transpose\", \"Ctranspose\",\n]\n\nnondeclares = (\"Program\", \"Project\", \"Include\", \"Includes\", \"Struct\", \"Structs\")\nstructvars = (\"Fvar\", \"Fget\", \"Fset\", \"Nget\", \"Nset\", \"Sget\", \"Sset\")\n\nclass Property_reference(object):\n    \"general property node\"\n\n    def __init__(self, name, default=None):\n        self.name = name\n\n    def __get__(self, instance, owner):\n        return instance.prop[self.name]\n\n    def __set__(self, instance, value):\n        instance.prop[self.name] = value\n\nclass Recursive_property_reference(object):\n    \"recursive property node\"\n\n    def __init__(self, name):\n        self.name = name\n\n    def __get__(self, instance, owner):\n\n        a = instance.prop[self.name]\n        if not (a is None):\n            return a\n\n        assert not (instance is instance.parent)\n\n        a = Recursive_property_reference.__get__(self, instance.parent, owner)\n        instance.prop[self.name] = a\n\n        return a\n\n    def __set__(self, instance, value):\n        instance.prop[self.name] = value\n\nclass File_reference(object):\n    def __get__(self, instance, owner):\n        if hasattr(instance, \"_file\"):\n            return instance._file\n\n        if instance.cls == \"Program\":\n            file_name = instance.name\n        else:\n            file_name = instance.program.name\n\n        instance._file = file_name\n        return file_name\n\n\nclass Line_reference(object):\n\n    def __get__(self, instance, owner):\n        if hasattr(instance, \"_line\"):\n            return instance._line\n\n        if instance.cls == \"Project\":\n            line = 0\n\n        elif instance.cls == \"Funcs\":\n            line = 1\n\n        else:\n            pline = instance.parent.line\n            pcur = instance.parent.cur\n            cur = instance.cur\n\n            if pcur == cur:\n                line = pline\n            else:\n                line = pline + instance.program.code.count(\"\\n\", pcur, cur)\n\n        instance._line = line\n        return line\n\n\nclass Group_reference(object):\n\n    def __get__(self, instance, owner):\n\n        if hasattr(instance, \"_group\"):\n            return instance._group\n\n        if instance.parent.cls in groups:\n            group = instance.parent\n\n        else:\n            group = instance.parent.group\n        \n        instance._group = group\n        return group\n\n\nclass Func_reference(object):\n\n    def __get__(self, instance, owner):\n\n        if hasattr(instance, \"_func\"):\n            return instance._func\n\n        if instance.cls in (\"Func\", \"Main\", \"Program\"):\n            func = instance\n        else:\n            func = instance.parent.func\n\n        instance._func = func\n        return func\n\nclass Program_reference(object):\n    def __get__(self, instance, owner):\n\n        if hasattr(instance, \"_program\"):\n            return instance._program\n\n        if instance.cls == \"Program\":\n            program = instance\n        else:\n            program = instance.parent.program\n\n        instance._program = program\n        return program\n\nclass Project_reference(object):\n    def __get__(self, instance, owner):\n\n        if hasattr(instance, \"_project\"):\n            return instance._project\n\n        if instance.cls == \"Project\":\n            project = instance\n        else:\n            project = instance.parent.project\n\n        instance._project = project\n        return project\n\n\nclass Names(object):\n    def __get__(self, instance, owner):\n        return [i.prop[\"name\"] for i in instance.children]\n\n\nclass Declare_reference(object):\n\n    def __get__(self, instance, owner):\n\n        if hasattr(instance, \"_declare\"):\n            return instance._declare\n\n        if instance.cls in nondeclares:\n            return instance\n\n        if instance.cls in structvars or\\\n                instance.backend in (\"structs\", \"struct\"):\n\n            if instance.cls in (\"Nget\", \"Nset\"):\n                if instance[0].cls == \"String\":\n                    value = instance[0][\"value\"]\n                else:\n                    return instance\n\n            else:\n                value = instance.value\n\n            if instance not in instance.program[3]:\n                return instance\n\n            struct = instance.program[3][instance]\n\n            if value not in struct.names:\n                return instance\n\n            out = struct[struct.names.index(value)]\n            instance._declare = out\n            return out\n\n        elif instance.parent.cls in \"Struct\":\n            return instance\n\n        else:\n\n            if instance in instance.func[0]:\n                out = instance.func[0][instance]\n                instance._declare = out\n                return out\n\n            if instance in instance.func[2]:\n                out = instance.func[2][instance]\n                instance._declare = out\n                return out\n\n\n        return instance\n\n"
  },
  {
    "path": "src/matlab2cpp/parser.py",
    "content": "\"\"\"Create parser for m2cpp.\"\"\"\nimport argparse\nfrom textwrap import dedent\nimport glob\nimport matlab2cpp\n\n\nHELP_DESCRIPTION = \"\"\"\\\n*** Matlab2cpp ***\n\nThe toolbox frontend of the Matlab2cpp library.  Use this to try to do automatic\nand semi-automatic translation from Matlab source file to C++.  The program\nwill create files with the same name as the input, but with various extra\nextensions.  Scripts will receive the extension `.cpp`, headers and modules\n`.hpp`.  A file containing data type and header information will be stored in\na `.py` file. Any errors will be stored in `.log`.\n\"\"\"\n\n\ndef matlab_file_completer(prefix, **kws):\n    \"\"\"Complete files with matlab extensions.\"\"\"\n    return glob.glob(\"{}*.m\".format(prefix))\n\n\ndef create_parser():\n    \"\"\"Create argument parser.\"\"\"\n    parser = argparse.ArgumentParser(\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        description=dedent(HELP_DESCRIPTION))\n\n    parser.add_argument(\n        \"filename\", help=\"File containing valid Matlab code.\"\n    ).completer = matlab_file_completer\n\n    parser.add_argument(\n        \"-o\", '--original', action=\"store_true\", help=(\n            \"Include original Matlab code line as comment before the \"\n            \"C++ translation of the code line\"),\n    )\n\n    parser.add_argument(\n        \"-c\", '--comments', action=\"store_true\", help=(\n            \"Include Matlab comments in the generated C++ files.\"),\n    )\n    parser.add_argument(\n        \"-s\", '--suggest', action=\"store_true\", help=(\n            \"Automatically populate the `<filename>.py` file with datatype \"\n            \"with suggestions if possible.\"),\n    )\n    parser.add_argument(\n        \"-S\", '--matlab-suggest', action=\"store_true\", help=(\n            \"Creates a folder m2cpp_temp. In the folder the matlab file(s) to \"\n            \"be translated are also put. These matlab file(s) are slightly \"\n            \"modified so that they output data-type information of the \"\n            \"variables to file(s). This output can then be used to set the \"\n            \"datatypes for the translation.\"),\n    )\n    parser.add_argument(\n        \"-r\", '--reset', action=\"store_true\", help=(\n            \"Ignore the content of `<filename>.py` and make a fresh translation.\"),\n    )\n    parser.add_argument(\n        \"-t\", '--tree', action=\"store_true\", help=(\n            \"Print the underlying node tree. Each line in the output \"\n            \"represents a node and is formated as follows: \\n\\n\"\n            \"`<codeline> <position> <class> <backend> <datatype> <name> <translation>`\\n\\n\"\n            \"The indentation represents the tree structure.\"),\n    )\n\n    parser.add_argument(\n        \"-T\", \"--tree-full\", action=\"store_true\", help=(\n            \"Same as -t, but the full node tree, but include meta-nodes.\"),\n    )\n    parser.add_argument(\n        \"-d\", '--disp', action=\"store_true\", help=(\n            \"Print out the progress of the translation process.\"),\n    )\n    parser.add_argument(\n        \"-p\", \"--paths_file\", type=str, dest=\"paths_file\", help=(\n            \"Flag and paths_file (-p path_to_pathsfile). m2cpp will look for \"\n            \"matlab files in the location specified in the paths_file\"),\n    )\n    parser.add_argument(\n        \"-omp\", '--enable-omp', action=\"store_true\", help=(\n            \"OpenMP code is inserted for Parfor and loops marked with the \"\n            \"pragma %%#PARFOR (in Matlab code) when this flag is set.\"),\n    )\n    parser.add_argument(\n        \"-tbb\", '--enable-tbb', action=\"store_true\", help=(\n            \"TBB code is inserted for Parfor and loops marked with the \"\n            \"pragma %%#PARFOR (in Matlab code) when this flag is set.\"),\n    )\n    parser.add_argument(\n        \"-ref\", '--reference', action=\"store_true\", help=(\n            'For the generated C++ code, function input parameters are '\n            '\"copied by value\" as default. With this flag some input '\n            'parameters in the generated code can be const references. '\n            'There can be some performance advantage of using const '\n            'references instead of \"copied by value\". Note that Matlab '\n            '\"copies by value\". The Matlab code you try to translate to '\n            'C++ code could try read as well as write to this input variable. '\n            \"The code generator doesn't perform an analysis to detect this \"\n            'and then \"copy by value\" for this variable.'),\n    )\n    parser.add_argument(\n        \"-l\", '--line', type=int, dest=\"line\", help=(\n            \"Only display code related to code line number `<line>`.\"),\n    )\n    parser.add_argument(\n        \"-n\", '--nargin', action=\"store_true\", help=(\n            \"Don't remove if and switch branches which use nargin variable.\"),\n    )\n\n    return parser\n"
  },
  {
    "path": "src/matlab2cpp/pyplot.py",
    "content": "code = r\"\"\"\n/*\n * SPlot.h\n *\n *  Created on: 19. aug. 2010\n *      Author: nordmoen\n */\n\n#ifndef SPLOT_H_\n#define SPLOT_H_\n\n#include <iostream>\n//DGRIM #include \"matlib.hpp\"\n#include <Python.h>\n#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION\n#include <numpy/arrayobject.h>\n#include <map>\n//DGRIM #include \"armadillo/armadillo\"\n\nclass PyEngine\n{\n\tstatic void _initialize() {\n\t\tstatic bool initialized = false;\n\t\tif (!initialized) {\n\t\t\tPy_SetProgramName((char*)\"splot\");\n\t\t\tPy_Initialize();\n\t\t\t_import_array();\n\t\t\tinitialized = true;\n\t\t}\n\t}\n\n public:\n\n\t// Wrapper class which takes both row/col vectors, as well as initializer lists\n\ttemplate <class T>\n\tclass arma_vec\n\t{\n\tpublic:\n\t\tconst std::vector<T> v;\n\t\tarma_vec() : v() {}\n\t\tarma_vec(const std::initializer_list<T> &c) : v(c) {}\n\t\tarma_vec(const std::vector<T> &vec) : v(vec) {}\n\t\tarma_vec(const arma::Col<T> &vec) : v(vec.begin(), vec.end()) {}\n\t\tarma_vec(const arma::Row<T> &vec) : v(vec.begin(), vec.end()) {}\n\t\tarma_vec(const arma::subview_col<T> &vec) : arma_vec(arma::Col<T>{vec}) {}\n\t\tarma_vec(const arma::subview_row<T> &vec) : arma_vec(arma::Row<T>{vec}) {}\n\t\ttemplate <class U>\n\t\t\tarma_vec(const arma::eOp<arma::Col<T>, U> &vec) : arma_vec(arma::Col<T>{vec}) {}\n\t\ttemplate <class U>\n\t\t\tarma_vec(const arma::eOp<arma::Row<T>, U> &vec) : arma_vec(arma::Row<T>{vec}) {}\n\t};\n\n\t// Wrapper class to limit arma::Mat implicit conversions (from string, for example).\n\t// For parameter-passing use only, since it borrows reference in some cases.\n\ttemplate <class T>\n\tclass arma_mat\n\t{\n\t\tconst arma::Mat<T> _m;\n\tpublic:\n\t\tconst arma::Mat<T> &m;\n\t\tarma_mat(const arma::Mat<T> &mat) : m(mat) {}\n\t\tarma_mat(const arma::subview<T> &view) : _m(view), m(_m) {}\n\t\ttemplate <class U>\n\t\t\tarma_mat(const arma::eOp<arma::Mat<T>, U> &op) : _m(op), m(_m) {}\n\t};\n\n\tclass py_obj\n\t{\n\t\tfriend class PyEngine;\n\t\tPyObject *obj;\n\n\t\ttemplate <class T> static int npy_typenum();\n\t\ttemplate <class NPY_T, class InputIt>\n\t\tstatic PyObject *create(const std::initializer_list<size_t> &in_dims, const InputIt &data, int flags=0)\n\t\t{\n\t\t\tstd::vector<npy_intp> dims;\n\t\t\tfor (auto it=in_dims.begin(); it!=in_dims.end(); ++it)\n\t\t\t\tdims.push_back((npy_intp)*it);\n\t\t\tPyObject *obj = PyArray_NewFromDescr(&PyArray_Type, PyArray_DescrFromType(npy_typenum<NPY_T>()),\n\t\t\t\t\t\t\t\t\t\t\t\t dims.size(), (npy_intp*)dims.data(), /*strides*/nullptr,\n\t\t\t\t\t\t\t\t\t\t\t\t /*data*/nullptr, flags, /*obj*/nullptr);\n\t\t\tstd::copy_n(data, PyArray_Size(obj), (NPY_T*)PyArray_DATA((PyArrayObject*)obj));\n\t\t\treturn obj;\n\t\t}\n\n\t    explicit py_obj(PyObject *o, bool steal_reference) : obj(o)\n\t\t{\n\t\t\tif (!steal_reference)\n\t\t\t\tPy_XINCREF(obj);\n\t\t}\n\n\tpublic:\n\n\t\t/* Basic constructors */\n\n\t    py_obj() : obj(nullptr) {}\n\t\tpy_obj(const py_obj &other) : obj(other.obj)\n\t\t{\n\t\t\tPy_XINCREF(obj);\n\t\t}\n\n\t    py_obj(const void *); // Trigger link error, to avoid implicit cast to bool\n\n\t\t/* Construct from primitive types, strings */\n\n\t\tpy_obj(bool const& b) : obj(PyBool_FromLong(b)) {}\n\t\tpy_obj(int const& i) : obj(PyInt_FromLong(i)) {}\n\t\tpy_obj(double const& d) : obj(PyFloat_FromDouble(d)) {}\n\t\tpy_obj(const char* const& s) : obj(PyString_FromString(s)) {}\n\t\tpy_obj(std::string const& s) : obj(PyString_FromString(s.c_str())) {}\n\n\t\t/* Construct from various sequences of double/float/int type */\n\n\t    py_obj(std::initializer_list<double> c) : obj(create<double>({c.size()}, c.begin())) {}\n\t    py_obj(std::vector<double> const& vec) : obj(create<double>({vec.size()}, vec.begin())) {}\n\t\tpy_obj(arma_vec<double> const& vec) : py_obj(vec.v) {}\n\t    py_obj(arma_mat<double> const& mat) : obj(create<double>({mat.m.n_rows, mat.m.n_cols}, mat.m.begin(), NPY_ARRAY_F_CONTIGUOUS)) {}\n\n\t    py_obj(std::initializer_list<float> c) : obj(create<float>({c.size()}, c.begin())) {}\n\t    py_obj(std::vector<float> const& vec) : obj(create<float>({vec.size()}, vec.begin())) {}\n\t\tpy_obj(arma_vec<float> const& vec) : py_obj(vec.v) {}\n\t\tpy_obj(arma_mat<float> const& mat) : obj(create<float>({mat.m.n_rows, mat.m.n_cols}, mat.m.begin(), NPY_ARRAY_F_CONTIGUOUS)) {}\n\n\t    py_obj(std::initializer_list<arma::cx_double> c) : obj(create<arma::cx_double>({c.size()}, c.begin())) {}\n\t    py_obj(std::vector<arma::cx_double> const& vec) : obj(create<arma::cx_double>({vec.size()}, vec.begin())) {}\n\t\tpy_obj(arma_vec<arma::cx_double> const& vec) : py_obj(vec.v) {}\n\t\tpy_obj(arma_mat<arma::cx_double> const& mat) : obj(create<arma::cx_double>({mat.m.n_rows, mat.m.n_cols}, mat.m.begin(), NPY_ARRAY_F_CONTIGUOUS)) {}\n\n\t    py_obj(std::initializer_list<arma::cx_float> c) : obj(create<arma::cx_float>({c.size()}, c.begin())) {}\n\t    py_obj(std::vector<arma::cx_float> const& vec) : obj(create<arma::cx_float>({vec.size()}, vec.begin())) {}\n\t\tpy_obj(arma_vec<arma::cx_float> const& vec) : py_obj(vec.v) {}\n\t\tpy_obj(arma_mat<arma::cx_float> const& mat) : obj(create<arma::cx_float>({mat.m.n_rows, mat.m.n_cols}, mat.m.begin(), NPY_ARRAY_F_CONTIGUOUS)) {}\n\n\t    py_obj(std::initializer_list<arma::sword> c) : obj(create<arma::sword>({c.size()}, c.begin())) {}\n\t    py_obj(std::vector<arma::sword> const& vec) : obj(create<arma::sword>({vec.size()}, vec.begin())) {}\n\t\tpy_obj(arma_vec<arma::sword> const& vec) : py_obj(vec.v) {}\n\t\tpy_obj(arma_mat<arma::sword> const& mat) : obj(create<arma::sword>({mat.m.n_rows, mat.m.n_cols}, mat.m.begin(), NPY_ARRAY_F_CONTIGUOUS)) {}\n\n\t    py_obj(std::initializer_list<arma::uword> c) : obj(create<arma::uword>({c.size()}, c.begin())) {}\n\t    py_obj(std::vector<arma::uword> const& vec) : obj(create<arma::uword>({vec.size()}, vec.begin())) {}\n\t\tpy_obj(arma_vec<arma::uword> const& vec) : py_obj(vec.v) {}\n\t\tpy_obj(arma_mat<arma::uword> const& mat) : obj(create<arma::uword>({mat.m.n_rows, mat.m.n_cols}, mat.m.begin(), NPY_ARRAY_F_CONTIGUOUS)) {}\n\n\t\t/* Destructor */\n\n\t\t~py_obj()\n\t\t{\n\t\t\tPy_XDECREF(obj);\n\t\t}\n\n\t\t/* Assignment and equality operators */\n\n\t\tpy_obj &operator=(const py_obj &other)\n\t\t{\n\t\t\tPy_XDECREF(obj);\n\t\t\tobj = other.obj;\n\t\t\tPy_XINCREF(obj);\n\t\t\treturn *this;\n\t\t}\n\n\t\tbool operator==(const py_obj &other) const\n\t\t{\n\t\t\treturn obj==other.obj;\n\t\t}\n\n\t\tbool valid() const\n\t\t{\n\t\t\treturn (obj!=nullptr);\n\t\t}\n\n\tprivate:\n\n\t\t/* Cast to PyObject */\n\n\t\toperator PyObject*()\n\t\t{\n\t\t\treturn obj;\n\t\t}\n\t};\n\n\tstatic py_obj None()\n\t{\n\t\treturn py_obj(Py_None, false);\n\t}\n\n\ttypedef std::vector<py_obj> args_t;\n\ttypedef std::map<const char*, py_obj> kwargs_t;\n\n protected:\n\n\tPyObject *main_module;\n\n\tpy_obj py_call_object(py_obj object, const char *func, const args_t &args={}, const kwargs_t &kwargs={})\n\t{\n\t\tpy_obj pyFunc(PyObject_GetAttrString(object, func), true);\n\t\tif (!pyFunc.valid()) {\n\t\t\tstd::cerr << \"No such method: \" << func << std::endl;\n\t\t\treturn py_obj(nullptr, true);\n\t\t}\n\n\t\tpy_obj pyArgs(PyTuple_New(args.size()), true);\n\t\tfor (size_t i=0; i<args.size(); i++) {\n\t\t\tPy_INCREF(args[i].obj);\n\t\t\tPyTuple_SetItem(pyArgs.obj, i, args[i].obj); // Steals reference\n\t\t}\n\n\t\tpy_obj pyKwArgs(PyDict_New(), true);\n\t\tfor (const auto &item : kwargs)\n\t\t\tPyDict_SetItem(pyKwArgs.obj, py_obj(item.first).obj, item.second.obj);\n\n\t\tpy_obj ret(PyObject_Call(pyFunc.obj, pyArgs.obj, pyKwArgs.obj), true);\n\t\tif (!ret.obj)\n\t\t{\n\t\t\tPyErr_Print();\n\t\t}\n\t\treturn ret;\n\t}\n\n\tpy_obj py_call(const char *func, const args_t &args={}, const kwargs_t &kwargs={})\n\t{\n\t\treturn py_call_object(py_obj(main_module, false), func, args, kwargs);\n\t}\n\n\tpy_obj error(const char *msg)\n\t{\n\t\tstd::cerr << msg << std::endl;\n\t\treturn py_obj(nullptr, false);\n\t}\n\n public:\n\tPyEngine()\n\t{\n\t\t_initialize();\n\t\tmain_module = PyImport_AddModule(\"__main__\");\n\t}\n\n\tvirtual ~PyEngine()\n\t{\n\t}\n\n\tbool py_code(const char *str, const kwargs_t &data={})\n\t{\n\t\tfor (auto item : data)\n\t\t{\n\t\t\tpy_put_variable(item.first, item.second);\n\t\t}\n\t\tif (PyRun_SimpleString(str) != 0)\n\t\t{\n\t\t\tstd::cerr << \"Error from Python interpreter:\" << std::endl;\n\t\t\tPyErr_Print();\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tvoid py_put_variable(const char *name, const py_obj &val)\n\t{\n\t\tPy_INCREF(val.obj);\n\t\tPyModule_AddObject(main_module, name, val.obj); // Steals reference\n\t}\n\n\tpy_obj py_get_variable(const char *name)\n\t{\n\t\treturn py_obj(PyDict_GetItemString(main_module, name), false); // Borrowed reference\n\t}\n\n\tpy_obj py_get_module(const char *name)\n\t{\n\t\treturn py_obj(PyImport_AddModule(name), false); // Borrowed reference\n\t}\n};\n\n\nclass SPlot : public PyEngine\n{\n public:\n\tSPlot()\n\t\t: PyEngine()\n\t{\n\t\tstd::string splot_py;\n\t\tstd::ifstream in(\"splot.py\");\n\t\tif (in.fail())\n\t\t{\n\t\t\t// May be copied to separate file \"splot.py\" in current directory\n\t\t\tsplot_py = R\"(\nfrom __future__ import division\n\nimport matplotlib as mpl\nqt_backend = None\ntry:\n    from PyQt4 import QtCore, QtGui, QtGui as QtWidgets\n    qt_backend = 4\nexcept ImportError:\n    try:\n        from PyQt5 import QtCore, QtGui, QtWidgets\n        qt_backend = 5\n    except ImportError:\n        pass\nif qt_backend:\n    try:\n        mpl.use('qt%dagg'%qt_backend)\n    except:\n        pass\n\nfrom pylab import *\nimport numpy as np\n\npylab_show = show\ndef show(interactive):\n    if qt_backend:\n        pylab_show(block=False)\n        if interactive:\n            QtWidgets.QApplication.instance().exec_()\n    else:\n        pylab_show(block=interactive)\n\ndef wigb(a, scale=1.0, x=None, z=None, amx=None, xshift=0.0, **kwargs):\n    kwargs.setdefault('color', 'black')\n    kwargs.setdefault('linewidth', 0.2)\n\n    n,m = a.shape\n\n    if amx is None or amx==0:\n        #amx = np.mean(np.max(np.abs(a), axis=1))\n        amx = np.max(np.max(np.abs(a), axis=1))\n\n    if x is None or len(x)==0:\n        x = np.arange(m)\n    if z is None or len(z)==0:\n        z = np.arange(n)\n\n    dx = np.median(np.abs(x[1:]-x[:-1]))\n    dz = z[1]-z[0]\n    a *= scale*dx/amx\n\n    #set display ranges\n    (xmin,xmax) = np.min(x), np.max(x)\n    (zmin,zmax) = np.min(z), np.max(z)\n    xlim(xmin-2*dx, xmax+2*dx)\n    ylim(zmin-dz, zmax+dz)\n    gca().invert_yaxis()\n\n    transData = gca().transData\n    plots = []\n    for i,xi in enumerate(x):\n        trace = a[:,i]\n        if trace.any(): # skip zero traces\n            plot_lines = plot(xi+trace, z, **kwargs)\n            plot_fill = fill_betweenx(z, xi-dx, xi+trace, **kwargs)\n            plots.append((plot_lines,plot_fill))\n\n            # Create clipping path for fill (instead of calculating zero-crossings)\n            x0 = xi+xshift\n            x1 = xi+dx if i+1<len(x) else xi+np.max(trace)\n            #x1 = xi+np.max(trace)\n            path = mpl.path.Path([(x0,zmin), (x0,zmax), (x1,zmax), (x1,zmin), (x0,zmin)])\n            plot_fill.set_clip_path(path, transData)\n\n    return plots\n\n\nif not qt_backend:\n    def table(*args, **kwargs):\n        print 'Failed to import Qt, no table support. Please install pyqt4 or pyqt5.'\nelse:\n    class TableModel(QtCore.QAbstractTableModel):\n        def __init__(self, mat):\n            QtCore.QAbstractTableModel.__init__(self)\n            self.mat = mat\n\n        def data(self, index, role):\n            if role == QtCore.Qt.DisplayRole:\n                value = self.mat[index.row(), index.column()]\n                return '{: f}'.format(value)\n            return None\n\n        def rowCount(self, index):\n            return self.mat.shape[0]\n\n        def columnCount(self, index):\n            return self.mat.shape[1]\n\n        def headerData(self, section, orientation, role):\n            if role == QtCore.Qt.DisplayRole:\n                return str(section+1)\n            return None\n\n    class TableView(QtWidgets.QTableView):\n        _views = {} # references to live windows, to prevent early deletion\n\n        def __init__(self):\n            QtWidgets.QTableView.__init__(self)\n            if qt_backend == 4:\n                self.horizontalHeader().setResizeMode(QtWidgets.QHeaderView.Fixed)\n                self.verticalHeader().setResizeMode(QtWidgets.QHeaderView.Fixed)\n            else:\n                self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Fixed)\n                self.verticalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Fixed)\n            self.pt = self.font().pointSize()\n            self.chars = 9\n\n            if qt_backend == 4:\n                self.connect(QtWidgets.QShortcut(QtWidgets.QKeySequence.ZoomIn, self), QtCore.SIGNAL('activated()'), self.zoom_in)\n                self.connect(QtWidgets.QShortcut(QtWidgets.QKeySequence.ZoomOut, self), QtCore.SIGNAL('activated()'), self.zoom_out)\n                self.connect(QtWidgets.QShortcut(QtWidgets.QKeySequence.Close, self), QtCore.SIGNAL('activated()'), self.close)\n            else:\n                QtWidgets.QShortcut(QtGui.QKeySequence.ZoomIn, self).activated.connect(self.zoom_in)\n                QtWidgets.QShortcut(QtGui.QKeySequence.ZoomOut, self).activated.connect(self.zoom_out)\n                QtWidgets.QShortcut(QtGui.QKeySequence.Close, self).activated.connect(self.close)\n\n            TableView._views[self] = self\n\n        def _getMonospaceFont(self):\n            font = QtGui.QFont('monospace')\n            if font.fixedPitch(): return font\n            font.setStyleHint(QtGui.QFont.Monospace)\n            if font.fixedPitch(): return font\n            font.setStyleHint(QtGui.QFont.TypeWriter)\n            if font.fixedPitch(): return font\n            font.setFamily('courier')\n            if font.fixedPitch(): return font\n            font.setKerning(False)\n            font.setFixedPitch(True)\n            return font\n\n        def setMonospaceFont(self):\n            self.setFont(self._getMonospaceFont())\n\n        def setFontSize(self, pt):\n            font = self.font()\n            font.setPointSize(pt)\n            self.setFont(font)\n            self.pt = pt\n\n            metrics = QtGui.QFontMetrics(font)\n            padding = 1.5\n            width = 2*padding + self.chars*metrics.width('X')\n            width = width*1.3\n            height = metrics.height() + 4*padding\n\n            header = self.verticalHeader()\n            header.setFont(font)\n            for i in range(header.length()):\n                header.resizeSection(i, height)\n\n            header = self.horizontalHeader()\n            header.setFont(font)\n            for i in range(header.length()):\n                header.resizeSection(i, width)\n\n        def zoom_in(self):\n            self.setFontSize(self.pt + 1)\n\n        def zoom_out(self):\n            if self.pt > 1:\n                self.setFontSize(self.pt - 1)\n\n        def wheelEvent(self, event):\n            if event.modifiers() == QtCore.Qt.ControlModifier:\n                delta = event.delta() if qt_backend==4 else event.angleDelta().y()\n                if delta > 1:\n                    self.zoom_in()\n                else:\n                    self.zoom_out()\n            else:\n                QtWidgets.QTableView.wheelEvent(self, event)\n\n        def closeEvent(self, event):\n            del TableView._views[self]\n            QtWidgets.QTableView.closeEvent(self, event)\n\n\n    def table(mat, title=None):\n        if QtWidgets.QApplication.instance() is None:\n            import sys\n            table.app = QtWidgets.QApplication(sys.argv)\n        table.seq += 1\n        if title is None:\n            title = 'Table %d '%table.seq\n        title += ' (%dx%d %s)'%(mat.shape+(mat.dtype.name,))\n\n        model = TableModel(mat)\n        view = TableView()\n        view.setMonospaceFont()\n        if np.iscomplexobj(mat):\n            view.chars *= 2\n        view.setAttribute(QtCore.Qt.WA_DeleteOnClose)\n        view.setModel(model)\n        view.setFontSize(8)\n        view.resize(600, 400)\n        view.setWindowTitle(title)\n        view.show()\n    table.seq = 0\n)\";\n\t\t} else {\n\t\t\tsplot_py = static_cast<std::stringstream&>(std::stringstream() << in.rdbuf()).str();\n\t\t}\n\t\tpy_code(splot_py.c_str());\n\t}\n\n\tpy_obj figure(const py_obj &figno)\n\t{\n\t\treturn py_call(\"figure\", {figno});\n\t}\n\n\tpy_obj hold(bool onoff)\n\t{\n\t\treturn py_call(\"hold\", {onoff});\n\t}\n\n\tpy_obj clf()\n\t{\n\t\treturn py_call(\"clf\");\n\t}\n\n\tpy_obj cla()\n\t{\n\t\treturn py_call(\"cla\");\n\t}\n\n\tpy_obj show(bool block=true)\n\t{\n\t\treturn py_call(\"show\", {block});\n\t}\n\n\tpy_obj xlabel(const char *label)\n\t{\n\t\treturn py_call(\"xlabel\", {label});\n\t}\n\n\tpy_obj ylabel(const char *label)\n\t{\n\t\treturn py_call(\"ylabel\", {label});\n\t}\n\n\tpy_obj title(const char *title)\n\t{\n\t\treturn py_call(\"title\", {title});\n\t}\n\n\tpy_obj plot(const arma_vec<double> &x, const arma_vec<double> &y, const kwargs_t &kwargs)\n\t{\n\t\treturn py_call(\"plot\", {x, y}, kwargs);\n\t}\n\n\tpy_obj plot(const arma_vec<double> &x, const arma_vec<double> &y, const std::string& spec={})\n\t{\n\t\treturn py_call(\"plot\", {x, y, spec});\n\t}\n\n\tpy_obj plot(const arma_vec<double> &x1, const arma_vec<double> &y1,\n\t\t\t\tconst arma_vec<double> &x2, const arma_vec<double> &y2, const std::string& spec2={})\n\t{\n\t\treturn py_call(\"plot\", {x1, y1, std::string(), x2, y2, spec2});\n\t}\n\n\tpy_obj plot(const arma_vec<double> &x1, const arma_vec<double> &y1, const std::string& spec1,\n\t\t\t\tconst arma_vec<double> &x2, const arma_vec<double> &y2, const std::string& spec2={})\n\t{\n\t\treturn py_call(\"plot\", {x1, y1, spec1, x2, y2, spec2});\n\t}\n\n\tpy_obj imshow(const arma_mat<double> &A, const kwargs_t &kwargs={})\n\t{\n\t\tkwargs_t new_kwargs(kwargs);\n\t\tnew_kwargs.emplace(\"aspect\", \"auto\");\n\t\tnew_kwargs.emplace(\"interpolation\", \"nearest\");\n\t\t//new_kwargs.emplace(\"clim\", py_obj({A.min(), A.max()}));\n\t\treturn py_call(\"imshow\", {A}, new_kwargs);\n\t}\n\n\tpy_obj imagesc(const arma_mat<double> &A, const kwargs_t &kwargs={})\n\t{\n\t\treturn imshow(A, kwargs);\n\t}\n\n\tpy_obj imagesc(const arma_vec<double> &x, const arma_vec<double> &y, const arma_mat<double> &A, const kwargs_t &kwargs={})\n\t{\n\t\tif (x.v.empty() && y.v.empty())\n\t\t\treturn imagesc(A, kwargs);\n\t\tif ((x.v.size() != 2 && x.v.size() != A.m.n_cols) || (y.v.size() != 2 && y.v.size() != A.m.n_rows))\n\t\t\treturn error(\"imagesc: length of x/y bounds must be 2 or matrix dimensions\");\n\n\t\tkwargs_t new_kwargs(kwargs);\n\t\tnew_kwargs[\"extent\"] = {x.v[0], x.v[x.v.size()-1], y.v[0], y.v[y.v.size()-1]};\n\t\treturn imagesc(A, new_kwargs);\n\t}\n\n\tpy_obj imagesc(const arma_mat<double> &A, const arma_vec<double> &clims, const kwargs_t &kwargs={})\n\t{\n\t\treturn imagesc(arma_vec<double>(), arma_vec<double>(), A, clims, kwargs);\n\t}\n\n\tpy_obj imagesc(const arma_vec<double> &x, const arma_vec<double> &y, const arma_mat<double> &A, const arma_vec<double> &clims, const kwargs_t &kwargs={})\n\t{\n\t\tif (clims.v.empty())\n\t\t\treturn imagesc(x, y, A, kwargs);\n\n\t\tif (clims.v.size() != 2)\n\t\t\treturn error(\"imagesc: length of c bounds must be 2\");\n\n\t\tkwargs_t new_kwargs(kwargs);\n\t\tnew_kwargs[\"clim\"] = clims;\n\t\treturn imagesc(x, y, A, new_kwargs);\n\t}\n\n\tpy_obj wigb(const arma_mat<double> &A, double scale=1.0, const arma_vec<double> &x={}, const arma_vec<double> &z={}, double amx=0.0, const kwargs_t &kwargs={})\n\t{\n\t\treturn py_call(\"wigb\", {A, scale, x, z, amx}, kwargs);\n\t}\n\n\tpy_obj colorbar()\n\t{\n\t\treturn py_call(\"colorbar\");\n\t}\n\n\tpy_obj colorbar(py_obj mappable)\n\t{\n\t\treturn py_call(\"colorbar\", {mappable});\n\t}\n\n\tpy_obj colorbar(py_obj mappable, py_obj ax)\n\t{\n\t\treturn py_call(\"colorbar\", {mappable, ax});\n\t}\n\n\tpy_obj xlim(double xmin, double xmax)\n\t{\n\t\treturn py_call(\"xlim\", {xmin, xmax});\n\t}\n\n\tpy_obj ylim(double ymin, double ymax)\n\t{\n\t\treturn py_call(\"ylim\", {ymin, ymax});\n\t}\n\n\tpy_obj caxis(double cmin, double cmax)\n\t{\n\t\treturn py_call(\"clim\", {cmin, cmax});\n\t}\n\n\tpy_obj axis(double xmin, double xmax, double ymin, double ymax)\n\t{\n\t\treturn py_call(\"axis\", {{xmin, xmax, ymin, ymax}});\n\t}\n\n\tpy_obj grid(const kwargs_t &kwargs={})\n\t{\n\t\treturn py_call(\"grid\", {}, kwargs);\n\t}\n\n\tpy_obj subplot(int xyi, const kwargs_t &kwargs={})\n\t{\n\t\treturn py_call(\"subplot\", {xyi}, kwargs);\n\t}\n\n\tpy_obj subplot(int x, int y, int i, const kwargs_t &kwargs={})\n\t{\n\t\treturn py_call(\"subplot\", {x, y, i}, kwargs);\n\t}\n\n\tpy_obj colormap(py_obj fig, const std::string &name, int levels=64)\n\t{\n\t\tconst size_t start = name.find('(');\n\t\tif (start != std::string::npos)\n\t\t{\n\t\t\tconst size_t end = name.find(')');\n\t\t\tif (end != std::string::npos && end>start)\n\t\t\t{\n\t\t\t\tconst std::string name_part(name.substr(start));\n\t\t\t\tconst int levels_part = atoi(name.substr(start+1, end).c_str());\n\t\t\t\treturn colormap(fig, name_part, levels_part);\n\t\t\t}\n\t\t}\n\t\tpy_obj cmap = py_call(\"get_cmap\", {(name==\"default\" ? \"jet\" : name), levels});\n\t\treturn py_call_object(fig, \"set_cmap\", {cmap});\n\t}\n\n\tpy_obj colormap(const std::string &name, int levels=64)\n\t{\n\t\treturn colormap(py_call(\"gci\"), name, levels);\n\t}\n\n\tpy_obj colormap(const py_obj &fig, const arma_mat<double> &segments)\n\t{\n\t\tpy_obj cmap = py_call_object(py_get_module(\"matplotlib.colors\"), \"ListedColormap\", {segments});\n\t\treturn py_call_object(fig, \"set_cmap\", {cmap});\n\t}\n\n\tpy_obj colormap(const arma_mat<double> &segments)\n\t{\n\t\treturn colormap(py_call(\"gci\"), segments);\n\t}\n\n\tvoid table(const arma_mat<double> &mat, const py_obj &title=None())\n\t{\n\t\tpy_call(\"table\", {mat, title});\n\t}\n\n\tvoid table(const arma_mat<arma::cx_double> &mat, const py_obj &title=None())\n\t{\n\t\tpy_call(\"table\", {mat, title});\n\t}\n\n};\n\ntemplate <> int PyEngine::py_obj::npy_typenum<double>() { return NPY_DOUBLE; }\ntemplate <> int PyEngine::py_obj::npy_typenum<float>() { return NPY_FLOAT; }\ntemplate <> int PyEngine::py_obj::npy_typenum<int>() { return NPY_INT32; }\ntemplate <> int PyEngine::py_obj::npy_typenum<unsigned int>() { return NPY_UINT32; }\ntemplate <> int PyEngine::py_obj::npy_typenum<long long>() { return NPY_INT64; }\ntemplate <> int PyEngine::py_obj::npy_typenum<unsigned long long>() { return NPY_UINT64; }\ntemplate <> int PyEngine::py_obj::npy_typenum<arma::cx_float>() { return NPY_COMPLEX64; }\ntemplate <> int PyEngine::py_obj::npy_typenum<arma::cx_double>() { return NPY_COMPLEX128; }\n\n#endif /* SPLOT_H_ */\n\"\"\"\n"
  },
  {
    "path": "src/matlab2cpp/qfunctions.py",
    "content": "\n\"\"\"\nFor simplest use of the module, these function works as an alternative frontend\nto the ``mconvert`` script.\n\n+--------------------------------+-----------------------------------------+\n| Function                       | Description                             |\n+================================+=========================================+\n| :py:func:`~matlab2cpp.build`   | Build token tree representation of code |\n+--------------------------------+-----------------------------------------+\n| :py:func:`~matlab2cpp.qcpp`    | Create content of `.cpp` file           |\n+--------------------------------+-----------------------------------------+\n| :py:func:`~matlab2cpp.qhpp`    | Create content of `.hpp` file           |\n+--------------------------------+-----------------------------------------+\n| :py:func:`~matlab2cpp.qpy`     | Create content of supplement `.py` file |\n+--------------------------------+-----------------------------------------+\n| :py:func:`~matlab2cpp.qlog`    | Create content of `.log` file           |\n+--------------------------------+-----------------------------------------+\n| :py:func:`~matlab2cpp.qscript` | Create script translation               |\n+--------------------------------+-----------------------------------------+\n| :py:func:`~matlab2cpp.qtree`   | Create summary of node tree             |\n+--------------------------------+-----------------------------------------+\n\"\"\"\n\n__all__ = [\"build\", \"qcpp\", \"qhpp\", \"qpy\", \"qlog\", \"qtree\", \"qscript\"]\n\n\ndef build(\n        code,\n        disp=False,\n        retall=False,\n        suggest=True,\n        comments=True,\n        vtypes=None,\n        **kws\n):\n    \"\"\"\nBuild a token tree out of Matlab code.  This function is used by the other\nquick-functions as the first step in code translation.\n\nThe function also handles syntax errors in the Matlab code.  It will highlight\nthe line it crashed on and explain as far as it can why it crashed.\n\nArgs:\n    code (str): Code to be interpreted\n    disp (bool): If true, print out diagnostic information while interpreting.\n    retall (bool): If true, return full token tree instead of only code related.\n    suggest (bool): If true, suggestion engine will be used to fill in datatypes.\n    comments (bool): If true, comments will be striped away from the solution.\n    vtypes (dict): Verbatim translations added to tree before process.\n    **kws: Additional arguments passed to :py:obj:`~matlab2cpp.Builder`.\n\nReturns:\n    Builder,Node: The tree constructor if `retall` is true, else the root node for code.\n\nExample::\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = matlab2cpp.build(\"a=4\", retall=True)\n    >>> print(isinstance(builder, Builder))\n    True\n    >>> node = matlab2cpp.build(\"a=4\", retall=False)\n    >>> print(isinstance(node, collection.Node))\n    True\n    >>> print(matlab2cpp.build(\"a**b\"))\n    Traceback (most recent call last):\n        ...\n    SyntaxError: File: unamed, line 1 in Matlab code:\n    a**b\n      ^\n    Expected: expression start\n\nSee also:\n    :py:func:`~matlab2cpp.qtree`,\n    :py:class:`~matlab2cpp.Builder`,\n    :py:class:`~matlab2cpp.Node`\n\n    \"\"\"\n    from . import supplement, tree\n\n    code = code + \"\\n\\n\\n\\n\"\n\n    if vtypes:\n        code = supplement.verbatim.set(vtypes, code)\n\n    builder = tree.builder.Builder(disp=disp, comments=comments, **kws)\n    builder.load(\"unamed\", code)\n    builder.configure(2*suggest)\n\n    if retall:\n        return builder\n\n    if builder[0][1][0].name == \"main\":\n        out = builder[0][1][0][3]\n        return out\n\n    return builder[0][1]\n\n\ndef qcpp(code, suggest=True, **kws):\n    \"\"\"\nQuick code translation of matlab script to C++ executable. For Matlab modules,\ncode that only consists of functions, will be placed in the\n:py:func:`~matlab2cpp.qhpp`. In most cases, the two functions must be used\ntogether to create valid runnable code.\n\nArgs:\n    code (str, Node, Builder): A string or tree representation of Matlab code.\n    suggest (bool): If true, use the suggest engine to guess data types.\n    **kws: Additional arguments passed to :py:obj:`~matlab2cpp.Builder`.\n\nReturns:\n    str: Best estimate of script. If code is a module, return an empty string.\n\nExample::\n    >>> code = \"a = 4; b = 5.; c = 'abc'\"\n    >>> print(matlab2cpp.qcpp(code, suggest=False))\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    int main(int argc, char** argv)\n    {\n      TYPE a, b, c ;\n      a = 4 ;\n      b = 5. ;\n      c = \"abc\" ;\n      return 0 ;\n    }\n    >>> print(matlab2cpp.qcpp(code, suggest=True))\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    int main(int argc, char** argv)\n    {\n      double b ;\n      int a ;\n      std::string c ;\n      a = 4 ;\n      b = 5. ;\n      c = \"abc\" ;\n      return 0 ;\n    }\n    >>> build = matlab2cpp.build(code, retall=True)\n    >>> print(matlab2cpp.qcpp(build) == matlab2cpp.qcpp(code))\n    True\n\nSee also:\n    :py:func:`~matlab2cpp.qscript`,\n    :py:func:`~matlab2cpp.qhpp`,\n    :py:obj:`~matlab2cpp.Builder`\n    \"\"\"\n    from . import tree\n\n    if isinstance(code, str):\n        tree_ = build(code, suggest=suggest, retall=True, **kws)[0]\n\n    else:\n        tree_ = code\n        if isinstance(tree_, tree.builder.Builder):\n            tree_ = tree_[0]\n\n    tree_ = tree_.program\n\n    if not tree_.str:\n        tree_.translate()\n\n    includes, funcs, inlines, structs, headers, log = tree_.program\n\n    out = \"\"\n\n    if funcs and funcs[0].name == \"main\":\n\n        if includes.str:\n            out += includes.str + \"\\n\\n\"\n\n        if len(headers) > 1:\n            out += headers.str + \"\\n\\n\"\n\n        if structs.str:\n            out += structs.str + \"\\n\\n\"\n\n        if funcs.str:\n            out += funcs.str + \"\\n\\n\"\n\n        out = out.replace(\"__percent__\", \"%\")\n\n        out =  out[:-2]\n\n        from .rules._program import add_indenting, number_fix, strip\n        out = strip(out)\n        out = number_fix(out)\n        out = add_indenting(out)\n\n    return out\n\n\ndef qhpp(code, suggest=False):\n    \"\"\"\nQuick module translation of Matlab module to C++ library. If the code is\na script, executable part of the code will be placed in\n:py:func:`~matlab2cpp.qcpp`.\n\nArgs:\n    code (str, Node, Builder): A string or tree representation of Matlab code.\n    suggest (bool): If true, use the suggest engine to guess data types.\n    **kws: Additional arguments passed to :py:obj:`~matlab2cpp.Builder`.\n\nReturns:\n    str: C++ code of module.\n\nExample::\n    >>> code = \"function y=f(x); y=x+1; end; function g(); f(4)\"\n    >>> print(matlab2cpp.qhpp(code))\n    #ifndef F_M_HPP\n    #define F_M_HPP\n    <BLANKLINE>\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    TYPE f(TYPE x) ;\n    void g() ;\n    <BLANKLINE>\n    TYPE f(TYPE x)\n    {\n      TYPE y ;\n      y = x+1 ;\n      return y ;\n    }\n    <BLANKLINE>\n    void g()\n    {\n      f(4) ;\n    }\n    #endif\n    >>> print(matlab2cpp.qhpp(code, suggest=True))\n    #ifndef F_M_HPP\n    #define F_M_HPP\n    <BLANKLINE>\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    int f(int x) ;\n    void g() ;\n    <BLANKLINE>\n    int f(int x)\n    {\n      int y ;\n      y = x+1 ;\n      return y ;\n    }\n    <BLANKLINE>\n    void g()\n    {\n      f(4) ;\n    }\n    #endif\n\nSee also:\n    :py:func:`~matlab2cpp.qcpp`,\n    :py:class:`~matlab2cpp.Builder`\n    \"\"\"\n    from . import tree\n\n    if isinstance(code, str):\n        tree_ = build(code, suggest=suggest, retall=True)[0]\n\n    else:\n        tree_ = code\n        if isinstance(tree_, tree.builder.Builder):\n            tree_ = tree_[0]\n\n    tree_ = tree_.program\n\n    if not tree_.str:\n        tree_.translate()\n\n    includes, funcs, inlines, structs, headers, log = tree_\n\n    out = \"\"\n\n    if funcs and funcs[0].name == \"main\":\n        return out\n\n    if funcs and funcs[0].name != \"main\":\n        name = funcs[0].name + \"_M_HPP\"\n        name = name.upper()\n        name.replace(\".\", \"_\")\n        out = \"#ifndef \" + name + \"\\n#define \" + name + \"\\n\\n\"\n\n    if includes.str:\n        out += includes.str + \"\\n\\n\"\n\n    if len(headers) > 1:\n        out += headers.str + \"\\n\\n\"\n\n    if structs.str:\n        out += structs.str + \"\\n\\n\"\n\n    if funcs.str:\n        out += funcs.str + \"\\n\\n\"\n\n    out = out[:-2]\n\n    if funcs and funcs[0].name != \"main\":\n        out += \"\\n#endif\"\n\n    out = out.replace(\"__percent__\", \"%\")\n    from .rules._program import add_indenting, number_fix, strip\n    out = strip(out)\n    out = number_fix(out)\n    out = add_indenting(out)\n\n    return out\n\n\ndef qpy(code, suggest=True, prefix=False):\n    \"\"\"\nCreate annotation string for the supplement file containing datatypes for the\nvarious variables in various scopes.\n\nArgs:\n    code (str, Builder, Node): Representation of the node tree.\n    suggest (bool): Use the suggestion engine if appropriate.\n    prefix (bool): include a helpful comment in the beginning of the string.\n\nReturns:\n\tstr: Supplement string\n\nExample::\n    >>> code = \"a = 4; b = 5.; c = 'abc'\"\n    >>> print(matlab2cpp.qpy(code, suggest=False))\n    functions = {\n      \"main\" : {\n        \"a\" : \"\", # int\n        \"b\" : \"\", # double\n        \"c\" : \"\", # string\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n    >>> print(matlab2cpp.qpy(code, suggest=True))\n    functions = {\n      \"main\" : {\n        \"a\" : \"int\",\n        \"b\" : \"double\",\n        \"c\" : \"string\",\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n      'using namespace arma ;',\n    ]\n\nSee also:\n    :py:mod:`~matlab2cpp.supplement`,\n    :py:mod:`~matlab2cpp.datatype`\n    \"\"\"\n    from . import supplement, tree\n\n    if isinstance(code, str):\n        tree_ = build(code, suggest=suggest, retall=True)[0]\n        tree_.translate()\n\n    else:\n        tree_ = code\n        if isinstance(tree_, tree.builder.Builder):\n            tree_ = tree_[0]\n        if tree_.cls != \"Program\":\n            raise KeyError(\n        \"Argument code should be code string, Builder or Program-node\")\n\n    ftypes = supplement.functions.get(tree_)\n    stypes = supplement.structs.get(tree_)\n    itypes = supplement.includes.get(tree_)\n    itypes = [i for i in itypes if supplement.includes.write_to_includes(i)]\n\n    vtypes = supplement.verbatim.get(tree_)\n    suggestions = supplement.suggests.get(tree_)\n\n    #print(\"ITYPASDASDA\")\n    #itypes = [\"#include \\\"\" + itype.split(os.path.sep)[-1] if \".hpp\" in itype else itype for itype in itypes]\n    #print(itypes)\n    #print(\".........;;;;;;;;-----\")\n    #itypes = [itype.split(os.path.sep)[-1] if \".hpp\" in itype else itype for itype in itypes]\n\n    out = supplement.str_variables(ftypes, stypes, itypes, suggestions, prefix, vtypes)\n    out = out.replace(\"__percent__\", \"%\")\n\n    return out\n\n\ndef qlog(code, suggest=False, **kws):\n    \"\"\"\nRetrieve all errors and warnings generated through the code translation and\nsummarize them into a string. Each entry uses four lines. For example: ::\n\n    Error in class Var on line 1:\n    function f(x)\n               ^\n    unknown data type\n\nFirst line indicate at what node and line-number the error occured. The second\nand third prints the Matlab-code line in question with an indicator to where the\ncode failed. The last line is the error or warning message generated.\n\nArgs:\n    code (str, Builder, Node): Representation of the node tree.\n    suggest (bool): Use suggestion engine where appropriate.\n    **kws: Additional arguments passed to :py:obj:`~matlab2cpp.Builder`.\n\nReturns:\n\tstr: A string representation of the log\n\nExample::\n    >>> print(matlab2cpp.qlog(\"function f(x); x=4\"))\n    Error in class Var on line 1:\n    function f(x); x=4\n               ^\n    unknown data type\n    <BLANKLINE>\n    Error in class Var on line 1:\n    function f(x); x=4\n                   ^\n    unknown data type\n\nSee alse:\n    :py:func:`~matlab2cpp.Node.error`,\n    :py:func:`~matlab2cpp.Node.warning`\n    \"\"\"\n    from . import tree\n\n    if isinstance(code, str):\n        tree_ = build(code, suggest=suggest, retall=True)[0]\n\n    else:\n        tree_ = code\n        if isinstance(tree_, tree.builder.Builder):\n            tree_ = tree_[0]\n        if tree_.cls != \"Program\":\n            raise KeyError(\n        \"Argument code should be code string, Builder or Program-node\")\n\n    tree_.translate()\n    out = tree_[5].str\n    out = out.replace(\"__percent__\", \"%\")\n\n    return out\n\ndef qtree(code, suggest=False, core=False):\n    \"\"\"\nSummarize the node tree with relevant information, where each line represents\na node.  Each line will typically look as follows::\n\n      1  10 | | | Var        unknown      TYPE    y\n\nThe line can be interpreted as follows:\n\n+--------+-------------------------------+------------------------------------+\n| Column | Description                   | Object                             |\n+========+===============================+====================================+\n| 1      | Matlab code line number       | :py:obj:`~matlab2cpp.Node.line`    |\n+--------+-------------------------------+------------------------------------+\n| 2      | Matlab code cursor number     | :py:obj:`~matlab2cpp.Node.cur`     |\n+--------+-------------------------------+------------------------------------+\n| 3      | The node categorization type  | :py:class:`~matlab2cpp.Node.cls`   |\n+--------+-------------------------------+------------------------------------+\n| 4      | The rule used for translation | :py:obj:`~matlab2cpp.Node.backend` |\n+--------+-------------------------------+------------------------------------+\n| 5      | The data type of the node     | :py:mod:`~matlab2cpp.Node.type`    |\n+--------+-------------------------------+------------------------------------+\n| 6      | Name of the node (if any)     | :py:obj:`~matlab2cpp.Node.name`    |\n+--------+-------------------------------+------------------------------------+\n\nThe vertical bars represents branches. The right most bar on each line points\nupwards towards its node parent.\n\nArgs:\n    code (str, Builder, Node): Representation of the node tree.\n    suggest (bool): Use suggestion engine where appropriate.\n    core (bool): Unly display nodes generated from Matlab code directly.\n    **kws: Additional arguments passed to :py:obj:`~matlab2cpp.Builder`.\n\nReturns:\n    str: A summary of the node tree.\n\nExample::\n    >>> print(matlab2cpp.qtree(\"function y=f(x); y=x+4\"))  # doctest: +NORMALIZE_WHITESPACE\n          Program    program      TYPE    unamed\n          | Includes   program      TYPE\n          | | Include    program      TYPE    #include <armadillo>\n          | | Include    program      TYPE    using namespace arma ;\n     1   1| Funcs      program      TYPE    unamed\n     1   1| | Func       func_return  TYPE    f\n     1   1| | | Declares   func_return  TYPE\n     1   1| | | | Var        unknown      TYPE    y\n     1   1| | | Returns    func_return  TYPE\n     1  10| | | | Var        unknown      TYPE    y\n     1  13| | | Params     func_return  TYPE\n     1  14| | | | Var        unknown      TYPE    x\n     1  16| | | Block      code_block   TYPE\n     1  18| | | | Assign     expression   TYPE\n     1  18| | | | | Var        unknown      TYPE    y\n     1  20| | | | | Plus       expression   TYPE\n     1  20| | | | | | Var        unknown      TYPE    x\n     1  22| | | | | | Int        int          int\n          | Inlines    program      TYPE    unamed\n          | Structs    program      TYPE    unamed\n          | Headers    program      TYPE    unamed\n          | | Header     program      TYPE    f\n          | Log        program      TYPE    unamed\n          | | Error      program      TYPE    Var:0\n          | | Error      program      TYPE    Var:9\n          | | Error      program      TYPE    Var:13\n          | | Error      program      TYPE    Var:17\n          | | Error      program      TYPE    Var:19\n          | | Error      program      TYPE    Plus:19\n\nSee also:\n    :py:mod:`matlab2cpp.tree`,\n    :py:mod:`matlab2cpp.node`\n    \"\"\"\n    from . import tree\n\n    if isinstance(code, str):\n        tree_ = build(code, suggest=suggest, retall=True)[0]\n        tree_.translate()\n\n    else:\n        tree_ = code\n        if isinstance(tree_, tree.builder.Builder):\n            tree_ = tree_[0]\n\n    if core:\n        if tree_.cls == \"Program\":\n            if tree_[1] and tree_[1][0].name == \"main\":\n                tree_ = tree_[1][0][-1]\n            else:\n                tree_ = tree_[1]\n\n    return tree_.summary()\n\n\ndef qscript(code, suggest=True, ftypes={}, **kws):\n    \"\"\"\nPerform a full translation (like :py:func:`~matlab2cpp.qcpp` and\n:py:func:`~matlab2cpp.qhpp`), but only focus on the object of interest.\nIf for example code is provided, then only the code part of the translation will\nbe include, without any wrappers. It will be as close to a one-to-one\ntranslation as you can get.  If a node tree is provided, current node position\nwill be source of translation.\n\nArgs:\n    code (str, Builder, Node): Representation of the node tree.\n    suggest (bool): Use suggestion engine where appropriate.\n    **kws: Additional arguments passed to :py:obj:`~matlab2cpp.Builder`.\n\nReturns:\n\tstr: A code translation in C++.\n\nExample:\n    >>> print(matlab2cpp.qscript(\"a = 4\"))\n    a = 4 ;\n    \"\"\"\n    from . import tree\n\n    if isinstance(code, str):\n        tree_ = build(code, suggest=suggest, retall=True, **kws)[0]\n    else:\n        tree_ = code\n        if isinstance(tree_, tree.builder.Builder):\n            tree_ = tree_[0]\n\n    if ftypes:\n        tree_.ftypes = ftypes\n\n    tree_.translate()\n\n    out = \"\"\n    if tree_.cls == \"Program\":\n        if tree_[1] and tree_[1][0].name == \"main\":\n            out = tree_[1][0][-1].str\n        else:\n            out = tree_[1].str\n    else:\n        out = tree_.str\n\n\n    out = out.replace(\"__percent__\", \"%\")\n    from .rules._program import add_indenting, number_fix, strip\n    out = strip(out)\n    out = number_fix(out)\n    out = add_indenting(out)\n\n    return out\n"
  },
  {
    "path": "src/matlab2cpp/rules/__init__.py",
    "content": "\"\"\"\n.. _rules:\n\nDatatype driven rules have the same name as datatypes reference in\n:py:mod:`~matlab2cpp.datatype`. They are as follows:\n\n+-----------+----------------------------------------+------------------+\n| Datatype  | Rule                                   | Description      |\n+===========+========================================+==================+\n| cell      | :py:mod:`~matlab2cpp.rules._cell`      | Cell structure   |\n+-----------+----------------------------------------+------------------+\n| char      | :py:mod:`~matlab2cpp.rules._char`      | Word character   |\n+-----------+----------------------------------------+------------------+\n| cube      | :py:mod:`~matlab2cpp.rules._cube`      | Armadillo cube   |\n+-----------+----------------------------------------+------------------+\n| cx_cube   | :py:mod:`~matlab2cpp.rules._cx_cube`   | Armadillo cube   |\n+-----------+----------------------------------------+------------------+\n| cx_double | :py:mod:`~matlab2cpp.rules._cx_double` | Scalar complex   |\n+-----------+----------------------------------------+------------------+\n| cx_mat    | :py:mod:`~matlab2cpp.rules._cx_mat`    | Armadillo matrix |\n+-----------+----------------------------------------+------------------+\n| cx_rowvec | :py:mod:`~matlab2cpp.rules._cx_rowvec` | Armadillo rowvec |\n+-----------+----------------------------------------+------------------+\n| cx_vec    | :py:mod:`~matlab2cpp.rules._cx_vec`    | Armadillo colvec |\n+-----------+----------------------------------------+------------------+\n| double    | :py:mod:`~matlab2cpp.rules._double`    | Scalar double    |\n+-----------+----------------------------------------+------------------+\n| fcube     | :py:mod:`~matlab2cpp.rules._fcube`     | Armadillo cube   |\n+-----------+----------------------------------------+------------------+\n| float     | :py:mod:`~matlab2cpp.rules._float`     | Scalar float     |\n+-----------+----------------------------------------+------------------+\n| fmat      | :py:mod:`~matlab2cpp.rules._fmat`      | Armadillo matrix |\n+-----------+----------------------------------------+------------------+\n| frowvec   | :py:mod:`~matlab2cpp.rules._frowvec`   | Armadillo rowvec |\n+-----------+----------------------------------------+------------------+\n| fvec      | :py:mod:`~matlab2cpp.rules._fvec`      | Armadillo colvec |\n+-----------+----------------------------------------+------------------+\n| icube     | :py:mod:`~matlab2cpp.rules._icube`     | Armadillo cube   |\n+-----------+----------------------------------------+------------------+\n| imat      | :py:mod:`~matlab2cpp.rules._imat`      | Armadillo matrix |\n+-----------+----------------------------------------+------------------+\n| int       | :py:mod:`~matlab2cpp.rules._int`       | Scalar integer   |\n+-----------+----------------------------------------+------------------+\n| irowvec   | :py:mod:`~matlab2cpp.rules._irowvec`   | Armadillo rowvec |\n+-----------+----------------------------------------+------------------+\n| ivec      | :py:mod:`~matlab2cpp.rules._ivec`      | Armadillo colvec |\n+-----------+----------------------------------------+------------------+\n| mat       | :py:mod:`~matlab2cpp.rules._mat`       | Armadillo matrix |\n+-----------+----------------------------------------+------------------+\n| rowvec    | :py:mod:`~matlab2cpp.rules._rowvec`    | Armadillo rowvec |\n+-----------+----------------------------------------+------------------+\n| string    | :py:mod:`~matlab2cpp.rules._string`    | Character string |\n+-----------+----------------------------------------+------------------+\n| struct    | :py:mod:`~matlab2cpp.rules._struct`    | Struct           |\n+-----------+----------------------------------------+------------------+\n| structs   | :py:mod:`~matlab2cpp.rules._structs`   | Array of structs |\n+-----------+----------------------------------------+------------------+\n| ucube     | :py:mod:`~matlab2cpp.rules._ucube`     | Armadillo cube   |\n+-----------+----------------------------------------+------------------+\n| umat      | :py:mod:`~matlab2cpp.rules._umat`      | Armadillo matrix |\n+-----------+----------------------------------------+------------------+\n| urowvec   | :py:mod:`~matlab2cpp.rules._urowvec`   | Armadillo rowvec |\n+-----------+----------------------------------------+------------------+\n| uvec      | :py:mod:`~matlab2cpp.rules._uvec`      | Armadillo colvec |\n+-----------+----------------------------------------+------------------+\n| uword     | :py:mod:`~matlab2cpp.rules._uword`     | Scalar uword     |\n+-----------+----------------------------------------+------------------+\n| vec       | :py:mod:`~matlab2cpp.rules._vec`       | Armadillo colvec |\n+-----------+----------------------------------------+------------------+\n\nThese basic types are then glued together through the following:\n\n+-------------------------------------------+---------------------------------------+\n| Rule                                      | Description                           |\n+===========================================+=======================================+\n| :py:mod:`~matlab2cpp.rules._code_block`   | Branches, loops etc.                  |\n+-------------------------------------------+---------------------------------------+\n| :py:mod:`~matlab2cpp.rules._expression`   | Operators and special characters      |\n+-------------------------------------------+---------------------------------------+\n| :py:mod:`~matlab2cpp.rules._func_lambda`  | Anonymous functions                   |\n+-------------------------------------------+---------------------------------------+\n| :py:mod:`~matlab2cpp.rules._func_return`  | Functions with one return value       |\n+-------------------------------------------+---------------------------------------+\n| :py:mod:`~matlab2cpp.rules._func_returns` | Functions with multiple return values |\n+-------------------------------------------+---------------------------------------+\n| :py:mod:`~matlab2cpp.rules._matrix`       | Matrix constructor                    |\n+-------------------------------------------+---------------------------------------+\n| :py:mod:`~matlab2cpp.rules._program`      | Program postprocessing                |\n+-------------------------------------------+---------------------------------------+\n| :py:mod:`~matlab2cpp.rules._reserved`     | Reserved names from Matlab library    |\n+-------------------------------------------+---------------------------------------+\n| :py:mod:`~matlab2cpp.rules._unknown`      | Structures with unknown origin        |\n+-------------------------------------------+---------------------------------------+\n| :py:mod:`~matlab2cpp.rules._verbatim`     | Special verbatim translations         |\n+-------------------------------------------+---------------------------------------+\n\"\"\"\n\nimport glob\nimport os\n\nimport matlab2cpp\nsep = os.path.sep\n\nfor name in glob.glob(os.path.dirname(__file__)+os.path.sep+\"*.py\"):\n\n    name = name.split(sep)[-1]\n    if name != \"__init__\":\n        exec(\"from . import %s\" % name[:-3])\n\nfrom ._reserved import reserved\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/rules/_cell.py",
    "content": "from .variables import *\n\ndef Cell(node):\n\n    # cells must stand on own line\n    if node.parent.cls not in (\"Assign\", \"Assigns\"):\n        node.auxiliary(\"cell\")\n\n    return \"{\", \",\", \"}\"\n\ndef Assign(node):\n\n    if node.name == 'varargin':\n        out = \"%(0)s = va_arg(varargin, \" + node[0].type + \") ;\"\n    else:\n        out = \"%(0)s.clear() ;\"\n\n        # append to cell, one by one\n        for elem in node[1]:\n            out = out + \"\\n%(0)s.push_back(\" + str(elem) + \") ;\"\n\n    return out\n"
  },
  {
    "path": "src/matlab2cpp/rules/_char.py",
    "content": "from .assign import Assign\nfrom .variables import *\n\n"
  },
  {
    "path": "src/matlab2cpp/rules/_code_block.py",
    "content": "\"\"\"\nThis module contains all the codeblock related nodes.\nEach node can then here be nested on top of each other.\nThey are static in the sense that there only exists one copy, unaffected by type\nand have the backend fixd to `code_block`.\n\"\"\"\nimport os\n\nimport matlab2cpp\nfrom . import parallel\n\n\ndef Statement(node):\n    \"\"\"\nStand-alone codeline without assignment etc.\n\nArgs:\n    node (Statement): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Expression\n\n    Expression:\n        Right hand side of expression\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"'text'\"))\n    \"text\" ;\n    >>> print(matlab2cpp.qscript(\"123\"))\n    123 ;\n    >>> print(matlab2cpp.qscript(\"[1,2]\"))\n    {1, 2} ;\n    >>> print(matlab2cpp.qscript(\"a\"))\n    a ;\n    >>> print(matlab2cpp.qscript(\"f()\"))\n    f() ;\n    \"\"\"\n    return \"%(0)s ;\"\n\n\ndef While(node):\n    \"\"\"\nWhile-loop\n\nArgs:\n    node (While): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Expression Block\n\n    Expression:\n        Loop condition\n    Block:\n        Loop content\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"while 1, f()\"))\n    while (1)\n    {\n      f() ;\n    }\n    \"\"\"\n    node.error(\"While-loops are currently not supported.\")\n    return \"while (%(0)s)\\n{\\n%(1)s\\n}\"\n\ndef Branch(node):\n    \"\"\"\nRoot of if/then/else branch\n\nArgs:\n    node (Branch): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    If Elif* Else?\n\n    If:\n        If block\n    Elif:\n        Elseif block\n    Else:\n        Else block\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"if a, b; elseif c, d; else e\"))\n    if (a)\n    {\n      b ;\n    }\n    else if (c)\n    {\n      d ;\n    }\n    else\n    {\n      e ;\n    }\n    \"\"\"\n    return \"\", \"\\n\", \"\"\n\ndef If(node):\n    \"\"\"\nIf in if/then/else branch\n\n\nArgs:\n    node (If): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Expression Block\n\n    Expression:\n        Branch condition\n    Block:\n        Code to be evaluated give condition\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"if a, b\"))\n    if (a)\n    {\n      b ;\n    }\n    >>> print(matlab2cpp.qscript(\"if a, end\"))\n    if (a)\n    {\n      // Empty block\n    }\n    \"\"\"\n    return \"\"\"if (%(0)s)\n{\n%(1)s\n}\"\"\"\n\n\ndef Elif(node):\n    \"\"\"\nElseif in if/then/else branch\n\nArgs:\n    node (Elif): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Expression Block\n\n    Expression:\n        Branch condition\n    Block:\n        Code to be evaluated give condition\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"if a, b; elseif c, d\"))\n    if (a)\n    {\n      b ;\n    }\n    else if (c)\n    {\n      d ;\n    }\n    >>> print(matlab2cpp.qscript(\"if a, b; elseif c, end\"))\n    if (a)\n    {\n      b ;\n    }\n    else if (c)\n    {\n      // Empty block\n    }\n    \"\"\"\n    return \"\"\"else if (%(0)s)\n{\n%(1)s\n}\"\"\"\n\n\ndef Else(node):\n    \"\"\"\nElse in if/then/else branch\n\nArgs:\n    node (Else): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Block\n\n    Block:\n        Code to be evaluated give condition\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"if a, b; else c\"))\n    if (a)\n    {\n      b ;\n    }\n    else\n    {\n      c ;\n    }\n    >>> print(matlab2cpp.qscript(\"if a, b; else; end\"))\n    if (a)\n    {\n      b ;\n    }\n    else\n    {\n      // Empty block\n    }\n    \"\"\"\n    return \"\"\"else\n{\n%(0)s\n}\"\"\"\n\n\ndef Switch(node):\n    \"\"\"\nRoot of switch/case branch\n\nArgs:\n    node (Switch): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Expression Case+ Otherwise?\n\n    Expression:\n        Test-expression\n    Case:\n        Case-block\n    Otherwise:\n        Otherwise-block\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"a=1; switch a; case b; c; otherwise; d\"))\n    a = 1 ;\n    if (b == a)\n    {\n      c ;\n    }\n    else\n    {\n      d ;\n    }\n    \"\"\"\n    if node[0].cls == \"Var\":\n        out = \"\"\n\n    # create switch variable\n    else:\n        node.type = node[0].type\n        out = \"%(type)s _var_%(type)s = %(0)s ;\\n\"\n    return out + \"\\n\".join(map(str, node[1:]))\n\ndef Case(node):\n    \"\"\"\nCase in switch/case\n\nArgs:\n    node (Case): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Expression Block\n\n    Expression:\n        Condition\n    Block:\n        Code to be evaluated give condition\n\nExample:\n    >>> print(matlab2cpp.qscript(\"switch 1; case b; c\"))\n    int _var_int = 1 ;\n    if (b == _var_int)\n    {\n      c ;\n    }\n    >>> print(matlab2cpp.qscript(\"a=1; switch a; case b; c;\"))\n    a = 1 ;\n    if (b == a)\n    {\n      c ;\n    }\n    \"\"\"\n\n    # first in row\n    if node is node.parent[1]:\n        out = \"if (%(0)s == \"\n    else:\n        out = \"else if (%(0)s == \"\n\n    # define name\n    if node.parent[0].cls == \"Var\":\n        out = out + node.parent[0].name\n\n    else:\n        node.type = node.parent[0].type\n        out += \"_var_%(type)s\"\n\n    out = out + \")\\n{\\n%(1)s\\n}\"\n    return out\n\n\ndef Otherwise(node):\n    \"\"\"\nOtherwise in switch/case\n\nArgs:\n    node (Otherwise): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Block\n\n    Block:\n        Code to be evaluated give condition\n\nExample:\n    >>> print(matlab2cpp.qscript(\"switch 1; case a; b; otherwise; c\"))\n    int _var_int = 1 ;\n    if (a == _var_int)\n    {\n      b ;\n    }\n    else\n    {\n      c ;\n    }\n    \"\"\"\n    return \"else\\n{\\n%(0)s\\n}\"\n\ndef Tryblock(node):\n    \"\"\"\nRoot of try/catch\n\nArgs:\n    node (Tryblock): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Try Catch+\n\n    Try:\n        Try-block\n    Catch:\n        Catch-block\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"try; a; catch; b\"))\n    try\n    {\n      a ;\n    }\n    catch (...)\n    {\n      b ;\n    }\n    \"\"\"\n    node.error(\"Try-statement are currently not supported.\")\n    return \"\", \"\\n\", \"\"\n\n\ndef Try(node):\n    \"\"\"Try\n\nArgs:\n    node (Try): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Block\n\n    Block : Try content\n    \"\"\"\n    return \"try\\n{\\n\", \"\", \"\\n}\"\n\n\ndef Catch(node):\n    \"\"\"\nCatch-block in Try/Catch\n\nArgs:\n    node (Catch): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Block\n\n    Block : Catch content\n    \"\"\"\n    \n    name = node.name\n\n    if not name:\n        return \"catch (...)\\n{\\n\", \"\", \"\\n}\"\n\n    if name[0] != \"@\":\n        return \"catch (\"+node.type()+\" \"+name+\")\\n{\\n\", \"\", \"\\n}\"\n\n    return \"catch (...)\\n{\\n\", \"\", \"\\n}\"\n\n\ndef Block(node):\n    \"\"\"\nCodeblock\n\nArgs:\n    node (Block): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Codeline*\n\n    Codeline : Sub-block, statement or assigments\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"a; if b; c; end; d\"))\n    a ;\n    if (b)\n    {\n      c ;\n    }\n    d ;\n    \"\"\"\n    if not len(node):\n        return \"// Empty block\"\n\n    out = str(node[0])\n    for child in node[1:]:\n        if child.cls == \"Ecomment\":\n            out = out + \" \" + str(child)\n        else:\n            out = out + \"\\n\" + str(child)\n\n    return out\n\ndef Assigns(node):\n    \"\"\"\nMultiple assignment\n\nArgs:\n    node (Assigns): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Lhs Lhs+ Expression\n\n    Lhs:\n        Left hand side of assignment\n    Expression:\n        Right hand side of assignment\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"[a,b,c] = d\"))\n    [a, b, c] = d ;\n    >>> print(matlab2cpp.qscript(\"[a,b,c] = [1,2,3]\"))\n    sword __aux_irowvec_1 [] = {1, 2, 3} ;\n    _aux_irowvec_1 = irowvec(__aux_irowvec_1, 3, false) ;\n    a = _aux_irowvec_1(0) ;\n    b = _aux_irowvec_1(1) ;\n    c = _aux_irowvec_1(2) ;\n    \"\"\"\n\n    # left-hand-side not a variable -> create auxillary variable that is\n    if node[-1].cls != \"Var\":\n        node[-1].auxiliary()\n\n    # split into multiple lines\n    out = \"\"\n    for i in range(len(node[:-1])):\n        i = str(i)\n        out += \"%(\" +i+ \")s = \" +str(node[-1])+ \"(\" +i+ \") ;\\n\"\n    out = out[:-1]\n\n    return out\n\ndef Parfor(node):\n    \"\"\"\nParfor-loop\n\nArgs:\n    node (For): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Var Expression Block\n\n    Var:\n        Variable running the loop\n    Expression:\n        Container for loop (special handle for Colon)\n    Block:\n        Content to loop over\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"parfor i=1:10; a\"))\n    for (i=1; i<=10; i++)\n    {\n      a ;\n    }\n    >>> print(matlab2cpp.qscript(\"parfor i=1:2:10; a\"))\n    for (i=1; i<=10; i+=2)\n    {\n      a ;\n    }\n    >>> print(matlab2cpp.qscript(\"parfor i=a; b\"))\n    for (int _i=0; _i<length(a); _i++)\n    {\n      i = a[_i] ;\n      b ;\n    }\n    \"\"\"\n    var, range = node[:2]\n    omp = node.project.builder.enable_omp\n    tbb = node.project.builder.enable_tbb\n\n    if range.cls == \"Colon\":\n\n        # <start>:<stop>\n        if len(range) == 2:\n            start, stop = range\n            step = \"1\"\n        \n        # <start>:<step>:<stop>\n        elif len(range) == 3:\n            start, step, stop = range\n        start, step, stop = map(str, [start, step, stop])\n\n        # return\n        if omp:\n            node.include(\"omp\")\n\n            out = parallel.omp(node, start, stop, step)\n\n        elif tbb:\n            node.include(\"tbb\")\n\n            #windows\n            if os.name == 'nt':\n                node.include(\"no_min_max\")\n\n            out = parallel.tbb(node, start, stop, step)\n\n            return out\n\n        else:\n            out = \"for (%(0)s=\" + start + \\\n                  \"; %(0)s<=\" + stop + \"; %(0)s\"\n\n        # special case for '+= 1'\n        if step == \"1\":\n            out += \"++\"\n        else:\n            out += \"+=\" + step\n\n        out += \")\\n{\\n%(2)s\\n}\"\n\n        #if tbb:\n        #    out += \"\\n});\"\n\n        return out\n\n    # default\n    return \"\"\"for (int _%(0)s=0; _%(0)s<length(%(1)s); _%(0)s++)\n{\n%(0)s = %(1)s[_%(0)s] ;\n%(2)s\n}\"\"\"\n\ndef For(node):\n    \"\"\"\nFor-loop\n\nArgs:\n    node (For): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nChildren:\n    Var Expression Block\n\n    Var:\n        Variable running the loop\n    Expression:\n        Container for loop (special handle for Colon)\n    Block:\n        Content to loop over\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"for i=1:10; a\"))\n    for (i=1; i<=10; i++)\n    {\n      a ;\n    }\n    >>> print(matlab2cpp.qscript(\"for i=1:2:10; a\"))\n    for (i=1; i<=10; i+=2)\n    {\n      a ;\n    }\n    >>> print(matlab2cpp.qscript(\"for i=a; b\"))\n    for (int _i=0; _i<length(a); _i++)\n    {\n      i = a[_i] ;\n      b ;\n    }\n    \"\"\"\n    var, range = node[:2]\n    omp = node.project.builder.enable_omp\n    tbb = node.project.builder.enable_tbb\n\n    index = node.parent.children.index(node)\n    parallel_loop = node.parent.children[index - 1].cls in [\"Pragma_for\", \"Tbb_for\"]\n\n    if range.cls == \"Colon\":\n        # <start>:<stop>\n        if len(range) == 2:\n            start, stop = range\n            step = \"1\"\n\n        # <start>:<step>:<stop>\n        elif len(range) == 3:\n            start, step, stop = range\n        start, step, stop = map(str, [start, step, stop])\n\n        if omp and parallel_loop:\n            node.include(\"omp\")\n\n            out = parallel.omp(node, start, stop, step)\n\n        elif tbb and parallel_loop:\n            node.include(\"tbb\")\n\n            #windows\n            if os.name == 'nt':\n                node.include(\"no_min_max\")\n\n            out = parallel.tbb(node, start, stop, step)\n\n            return out\n\n        else:\n            out = \"for (%(0)s=\" + start + \\\n                  \"; %(0)s<=\" + stop + \"; %(0)s\"\n\n        # special case for '+= 1'\n        if step == \"1\":\n            out += \"++\"\n        else:\n            out += \"+=\" + step\n\n        out += \")\\n{\\n%(2)s\\n}\"\n\n        return out\n\n    # i = [1, 2, 3, 4]\n    if len(node) == 3:\n        if node[1].dim in [1, 2]:\n            return \"\"\"for (auto %(0)s : %(1)s)\n{\n%(2)s\n}\n\"\"\"\n    # default\n    return \"\"\"for (int _%(0)s=0; _%(0)s<length(%(1)s); _%(0)s++)\n{\n%(0)s = %(1)s[_%(0)s] ;\n%(2)s\n}\"\"\"\n\ndef Pragma_for(node):\n    #node.include(\"omp\")\n    #return node\n    #return \"//__percent__%(value)s\"\n    return \"\"\n\ndef Bcomment(node):\n    \"\"\"\nBlock comment\n\nArgs:\n    node (Bcomment): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"function f(); %{ comment %}\"))\n    void f()\n    {\n      /* comment */\n    }\n    \"\"\"\n    return \"/*%(value)s*/\"\n\n\ndef Lcomment(node):\n    \"\"\"\nLine comment\n\nArgs:\n    node (Lcomment): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"function f(); % comment\"))\n    void f()\n    {\n      // comment\n    }\n    \"\"\"\n    return \"//%(value)s\"\n\n\ndef Ecomment(node):\n    \"\"\"\nEnd comment\n\nArgs:\n    node (Ecomment): Current position in node-tree\n\nReturn:\n    str : Translation of current node.\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"a % comment\"))\n    a ; // comment\n    \"\"\"\n    return \"//%(value)s\"\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/rules/_cube.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .cube import Get, Set, Resize\n\nDeclare = \"cube = %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_cx_cube.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .cube import Get, Set, Resize\n\nDeclare = \"cx_cube = %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_cx_double.py",
    "content": "from .assign import Assign\nfrom .variables import *\n\nDeclare = \"cx_double %(name)s ;\"\nImag = \"cx_double(0, %(value)s)\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_cx_mat.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .mat import Get, Set\n\nDeclare = \"cx_mat %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_cx_rowvec.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .rowvec import Get, Set\n\nDeclare = \"cx_rowvec %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_cx_vec.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .vec import Get, Set\n\nDeclare = \"cx_vec %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_double.py",
    "content": "from .assign import Assign\nfrom .variables import *\n\nDeclare = \"double %(name)s ;\"\nFloat = \"%(value)s\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_expression.py",
    "content": "import matlab2cpp\nfrom .assign import Assign\n\ndef Paren(node):\n    \"\"\"Parenthesis surounding expression.\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"(1+2)*(3-4)\"))\n    (1+2)*(3-4) ;\n    \"\"\"\n    node.type = node[0].type\n    return \"(%(0)s)\"\n\ndef End(node):\n    \"\"\"The 'end' statement indicating not end of block, but end-of-range.\n    \nExamples:\n    >>> print(matlab2cpp.qscript(\"x = zeros(2,2,2); x(end, end, end)\"))\n    x = arma::zeros<cube>(2, 2, 2) ;\n    x(x.n_rows-1, x.n_cols-1, x.n_slices-1) ;\n    \"\"\"\n\n    # find context for what end refers to\n    pnode = node\n    while pnode.parent.cls not in \\\n            (\"Get\", \"Cget\", \"Nget\", \"Fget\", \"Sget\",\n            \"Set\", \"Cset\", \"Nset\", \"Fset\", \"Sset\", \"Block\"):\n        pnode = pnode.parent\n\n    # end statement only makes sense in certain contexts\n    if pnode.cls == \"Block\":\n        node.error(\"Superfluous end-statement\")\n        return \"end\"\n\n    index = pnode.parent.children.index(pnode)\n    name = pnode = pnode.parent.name\n\n    if len(node.group) == 1:\n        if node.group.dim == 1:\n            return name + \".n_rows\"\n        if node.group.dim == 2:\n            return name + \".n_cols\"\n    \n    # what end is referring to\n    if index == 0:\n        return name + \".n_rows\"\n    elif index == 1:\n        return name + \".n_cols\"\n    elif index == 2:\n        return name + \".n_slices\"\n    else:\n        node.error(\"end statement in arg>3\")\n\n\nBreak = \"break\"\n\ndef Return(node):\n    \"\"\"Return statement\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"function f(); return\"))\n    void f()\n    {\n      return ;\n    }\n    >>> print(matlab2cpp.qscript(\"function y=f(); return; y=1\"))\n    int f()\n    {\n      int y ;\n      return y ;\n      y = 1 ;\n      return y ;\n    }\n    >>> print(matlab2cpp.qscript(\"function [y,z]=f(); return; y=1; z=2\"))\n    void f(int& y, int& z)\n    {\n      return ;\n      y = 1 ;\n      z = 2 ;\n    }\n\n    \"\"\"\n    func = node.func\n    if func.backend == \"func_returns\":\n        return \"return\"\n\n    if func.backend == \"func_lambda\":\n        return \"return _retval\"\n\n    return_value = func[1][0].name\n    return \"return \" + return_value\n\n\n# simple operators\ndef Mul(node):\n    \"\"\"(Matrix-)multiplication\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"a = [1,2,3]; b = [4;5;6]; c = a*b\"))\n    sword _a [] = {1, 2, 3} ;\n    a = irowvec(_a, 3, false) ;\n    sword _b [] = {4, 5, 6} ;\n    b = ivec(_b, 3, false) ;\n    c = arma::as_scalar(a*b) ;\n    \"\"\"\n\n    c_flag = False\n\n    if not node[0].num:\n        return \"\", \"*\", \"\"\n\n    if len(node) == 2 and node.dim == 0:\n        if node[0].backend == \"reserved\" and node[0].name == \"i\" and node[1].mem < 4:\n            node.value = node[1].value\n            return \"cx_double(0, %(1)s)\"\n        elif node[1].backend == \"reserved\" and node[1].name == \"i\" and node[0].mem < 4:\n            node.value = node[0].value\n            return \"cx_double(0, %(0)s)\"\n\n    dim = node[0].dim\n    #mem = max(node[0].mem, 2)\n    mem = 0\n    for n in node:\n        mem = max(mem, n.mem)\n\n    if node.mem == 4 and node[0].dim == 0 and node[0].mem != 4:\n        out = \"cx_double(%(0)s)\"\n    else:\n        out = \"%(0)s\"\n    index = 1\n    for child in node[1:]:\n        sVal = str(index)\n        index += 1\n\n        # not numerical\n        if not child.num:\n            return \"\", \"*\", \"\"\n\n        if dim == 0:\n            dim = child.dim\n            if node.mem == 4 and child.dim == 0 and child.mem != 4:\n                c_flag = True\n\n        if dim == 1:\n            if child.dim == 0:\n                #pass\n                dim = 1\n            elif child.dim == 1:\n                child.error(\"multiplication shape mismatch, colvec*colvec\")\n            elif child.dim == 2:\n                #pass\n                dim = 3\n            elif child.dim == 3:\n                child.error(\"multiplication shape mismatch, colvec*matrix\")\n            elif child.dim == 4:\n                child.error(\"multiplication shape mismatch, colvec*cube\")\n\n        elif dim == 2:\n            if child.dim == 0:\n                #pass\n                dim = 2\n            elif child.dim == 1:\n\n                out =  \"arma::as_scalar(\" + out + \"*\" + \"%(\" + sVal + \")s\" + \")\"\n                #pass\n                dim = 0\n                continue\n            elif child.dim == 2:\n                child.error(\"multiplication shape mismatch, rowvec*rowvec\")\n            elif child.dim == 3:\n                #pass\n                dim = 3\n\n        elif dim == 3:\n            if child.dim == 0:\n                #pass\n                dim = 3\n            elif child.dim == 1:\n                #pass\n                dim = 1\n            elif child.dim == 2:\n                child.error(\"multiplication shape mismatch, matrix*rowvec\")\n            elif child.dim == 3:\n                #pass\n                dim = 3\n\n        if c_flag:\n            out = out + \"*\" + \"(cx_double) %(\" + sVal + \")s\"\n        else:\n            out = out + \"*\" + \"%(\" + sVal + \")s\"\n        #mem = max(mem, child.mem)\n\n    node.type = (dim, mem)\n\n    #return \"\", \"*\", \"\"\n    return out\n\ndef Elmul(node):\n    \"\"\"Element multiplication\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"a = [1,2,3]; b = [4,5,6]; c = a.*b\"))\n    sword _a [] = {1, 2, 3} ;\n    a = irowvec(_a, 3, false) ;\n    sword _b [] = {4, 5, 6} ;\n    b = irowvec(_b, 3, false) ;\n    c = a%b ;\n    \"\"\"\n\n    # unknown input\n    if node.type == \"TYPE\":\n        return \"\", \"__percent__\", \"\"\n\n    # not numerical\n    if not node.num:\n        node.error(\"non-numerical multiplication %s\" % str([n.type for n in node]))\n        return \"\", \"*\", \"\"\n\n    # scalar multiplication, lhs or rhs of elmul is scalar\n    if node.dim == 0 or node[0].dim == 0 or node[1].dim == 0:\n        return \"\", \"*\", \"\"\n\n    # Sclar's multiplication in Armadillo '%' needs special handle because of\n    # interpolation in python\n    return \"\", \"__percent__\", \"\"\n\ndef Plus(node):\n    \"\"\"Addition\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"a = [1,2,3]; b = [4,5,6]; c = a+b\"))\n    sword _a [] = {1, 2, 3} ;\n    a = irowvec(_a, 3, false) ;\n    sword _b [] = {4, 5, 6} ;\n    b = irowvec(_b, 3, false) ;\n    c = a+b ;\n    \"\"\"\n\n    # non-numerical addition\n    if not node.num:\n        node.error(\"non-numerical addition %s\" % str([n.type for n in node]))\n\n    if node.mem == 4 and node.dim == 0:\n        out = []\n        for child in node:\n            if child.mem < 4:\n                out.append(\"cx_double(\" + str(child) + \", 0)\")\n            else:\n                out.append(str(child))\n        return \"+\".join(out)\n\n    return \"\", \"+\", \"\"\n\ndef Minus(node):\n    \"\"\"Subtraction\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"a = [1,2,3]; b = [4,5,6]; c = a-b\"))\n    sword _a [] = {1, 2, 3} ;\n    a = irowvec(_a, 3, false) ;\n    sword _b [] = {4, 5, 6} ;\n    b = irowvec(_b, 3, false) ;\n    c = a-b ;\n    \"\"\"\n    return \"\", \"-\", \"\"\n\nGt      = \"\", \">\", \"\"\nGe      = \"\", \">=\", \"\"\nLt      = \"\", \"<\", \"\"\nLe      = \"\", \"<=\", \"\"\nNe      = \"\", \"!=\", \"\"\nEq      = \"\", \"==\", \"\"\nBand    = \"\", \" && \", \"\"\nLand    = \"\", \" && \", \"\"\nBor     = \"\", \" || \", \"\"\nLor     = \"\", \" || \", \"\"\n\ndef Elementdivision(node):\n    \"\"\"Element wise division\n    \"\"\"\n\n    # unknown input\n    if node.type == \"TYPE\":\n\n        # default to assume everything scalar\n        out = str(node[0])\n        for child in node[1:]:\n\n            # force to be float if int in divisor\n            if child.cls == \"Int\":\n                out = out + \"/\" + str(child) + \".0\"\n            else:\n                out = out + \"/\" + str(child)\n        return out\n\n    out = str(node[0])\n\n    \n    # I commented out the the code below\n    # force float output\n    mem = node[0].mem\n    if mem<2:\n        mem = 2\n    mem = max(node[0].mem, node[1].mem)\n    \n    # I think node will always have length 2,\n    # thus for child in node[1:] should be same as child = node[1:]\n    # but why fix whats not broken? commented out mem = max(...) and node.mem = mem\n    for child in node[1:]:\n\n        # convert ints to floats\n        if child.cls == \"Int\":\n            out = out + \"/\" + str(child) + \".0\"\n\n        # avoid int/uword division, or int/int division\n        elif mem < 2:\n            out = out + \"*1.0/\" + str(child)\n\n        else:\n            out = out + \"/\" + str(child)\n\n        #mem = max(mem, child.mem)\n\n    #node.mem = mem\n\n    return out\n\n\ndef Leftelementdivision(node):\n    \"\"\"Left element wise division\n    \"\"\"\n\n    # unknown input\n    if node.type == \"TYPE\":\n        return \"\", \"\\\\\", \"\"\n\n    # iterate backwards\n    out = str(node[-1])\n\n    # force float output\n    mem = node[-1].mem\n    if mem<2:\n        mem = 2\n\n    for child in node[-2::-1]:\n\n        # avoid explicit integer division\n        if child.cls == \"Int\":\n            out = str(child) + \".0/\" + out\n\n        # avoid implicit integer division\n        if child.mem < 2 and mem < 2:\n            out = str(child) + \"*1.0/\" + out\n\n        else:\n            out = str(child) + \"/\" + out\n\n        #mem = max(mem, child.mem)\n\n    #node.mem = mem\n    \n    return out\n\n\ndef Matrixdivision(node):\n\n    # start with first element ...\n    out = str(node[0])\n\n    mem = node[0].mem or 2\n    dim = node[0].dim or 0\n\n    # everything scalar -> use element division\n    if {n.dim for n in node} == {0}:\n\n        return Elementdivision(node)\n\n    else:\n\n        # ... iterate over the others\n        for child in node[1:]:\n\n            # matrix handle\n            if child.dim == 3:\n                out = \"arma::solve(\" + str(child) + \".t(), \" + out + \".t(), solve_opts::fast).t()\"\n\n            # integer handle\n            elif child.cls == \"Int\":\n                out = out + \"/\" + str(child) + \".0\"\n\n            # avoid integer division\n            elif child.mem < 2 and mem < 2:\n                out = out + \"*1.0/\" + str(child)\n\n            elif child.type == \"int\" and mem == 4:\n                out = out + \"/\" + \"double(\" + str(child) + \")\"\n\n            else:\n                out = out + \"/\" + str(child)\n\n            # track memory output\n            #mem = max(mem, child.mem)\n\n            # assert if division legal in matlab\n            if dim == 0:\n                pass\n                #dim = child.dim\n\n            elif dim == 1:\n                if child.dim == 0:\n                    pass\n                    #dim = 1\n                elif child.dim == 1:\n                    node.error(\"Matrix division error 'colvec\\\\colvec'\")\n                elif child.dim == 2:\n                    pass\n                    #dim = 3\n                elif child.dim == 3:\n                    node.error(\"Matrix division error 'colvec\\\\matrix'\")\n                elif child.dim == 3:\n                    node.error(\"Matrix division error 'colvec\\\\cube'\")\n\n            elif dim == 2:\n                if child.dim == 0:\n                    pass\n                    #dim = 2\n                elif child.dim == 1:\n                    pass\n                    #dim = 0\n                elif child.dim == 2:\n                    node.error(\"Matrix division error 'rowvec\\\\rowvec'\")\n                elif child.dim == 3:\n                    pass\n                    #dim = 2\n                elif child.dim == 4:\n                    pass\n                    #dim = 3\n\n            elif dim == 3:\n                if child.dim == 0:\n                    pass\n                    #dim = 3\n                elif child.dim == 1:\n                    pass\n                    #dim = 1\n                elif child.dim == 2:\n                    node.error(\"Matrix division error 'matrix\\\\rowvec'\")\n                elif child.dim == 3:\n                    pass\n                    #dim = 3\n                elif child.dim == 4:\n                    pass\n                    #dim = 4\n\n    #if not (dim is None) and not (mem is None):\n    #    node.type = (dim, mem)\n\n    return out\n\n\ndef Leftmatrixdivision(node):\n    \"\"\"Left operator matrix devision\n    \"\"\"\n\n    # unknown input\n    if node.type == \"TYPE\":\n        return \"\", \"\\\\\", \"\"\n\n    # start with first node ...\n    out = str(node[0])\n\n    mem = node[0].mem\n    dim = node[0].dim\n\n    # everything scalar -> use left element division\n    if {n.dim for n in node} == {0}:\n        return Leftelementdivision(node)\n\n    else:\n\n        # ... iterate forwards\n        for child in node[1:]:\n\n            # classical array inversion\n            if child.dim > 0:\n                out = \"arma::solve(\" + out + \", \" + str(child) + \", solve_opts::fast)\"\n\n            # avoid integer division\n            # backwords since left division is reverse\n            elif child.mem < 2 and mem < 2:\n                out = \"(\" + out + \")*1.0/\" + str(child)\n                #mem = 2\n\n            # backwords since left division is reverse\n            else:\n                out = \"(\" + out + \")/\" + str(child)\n                # out = str(child) + \"/\" + out\n\n            #mem = max(mem, child.mem)\n\n            # assert division as legal\n            if dim == 0:\n                dim = node.dim\n\n            elif dim == 1:\n                if node.dim == 0:\n                    pass\n                    #dim = 1\n                elif node.dim == 1:\n                    node.error(\"Matrix division error 'colvec\\\\colvec'\")\n                elif node.dim == 2:\n                    pass\n                    #dim = 3\n                elif node.dim == 3:\n                    node.error(\"Matrix division error 'colvec\\\\matrix'\")\n                elif node.dim == 3:\n                    node.error(\"Matrix division error 'colvec\\\\cube'\")\n\n            elif dim == 2:\n                if node.dim == 0:\n                    pass\n                    #dim = 2\n                elif node.dim == 1:\n                    pass\n                    #dim = 0\n                elif node.dim == 2:\n                    node.error(\"Matrix division error 'rowvec\\\\rowvec'\")\n                elif node.dim == 3:\n                    pass\n                    #dim = 2\n                elif node.dim == 4:\n                    pass\n                    #dim = 3\n\n            elif dim == 3:\n                if node.dim == 0:\n                    pass\n                    #dim = 3\n                elif node.dim == 1:\n                    pass\n                    #dim = 1\n                elif node.dim == 2:\n                    node.error(\"Matrix division error 'matrix\\\\rowvec'\")\n                elif node.dim == 3:\n                    pass\n                    #dim = 3\n                elif node.dim == 4:\n                    pass\n                    #dim = 4\n\n    #node.type = (dim, mem)\n\n    return out\n\n\n\ndef Exp(node):\n    \"\"\"Exponent\n    \"\"\"\n\n    out = str(node[0])\n    for child in node[1:]:\n        out = \"pow(\" + str(out) + \", \" + str(child) + \")\"\n\n    return out\n\ndef Elexp(node):\n    \"\"\"Elementwise exponent\n    \"\"\"\n\n    node.type = node[0].type\n    out = str(node[0])\n\n    if len(node) == 2:\n        exponent = str(node[1])\n        if exponent == \"2\":\n            if(node[0].dim == 0):\n                return \"m2cpp::square(\" + out + \")\"\n            else:\n                return \"arma::square(\" + out + \")\"\n\n    for child in node[1:]:\n        out = \"arma::pow(\" + str(out) + \", \" + str(child) + \")\"\n    return out\n\n\ndef All(node):\n    \"\"\"All ':' element\n    \"\"\"\n    arg = node.parent.name\n\n    # is first arg\n    if len(node.parent) > 0 and node.parent[0] is node:\n        arg += \".n_rows\"\n\n    # is second arg\n    elif len(node.parent) > 1 and node.parent[1] is node:\n        arg += \".n_cols\"\n\n    # is third arg\n    elif len(node.parent) > 2 and node.parent[2] is node:\n        arg += \".n_slices\"\n\n    else:\n        return \"span::all\"\n\n    return \"m2cpp::span<uvec>(0, \" + arg + \"-1)\"\n\nNeg = \"-\", \"\", \"\"\n#Not = \"not \", \"\", \"\"\nNot = \"!\", \"\", \"\"\n\ndef Transpose(node):\n    \"\"\"(Simple) transpose\n\n    >>> print(matlab2cpp.qscript(\"a = [1,2,3]; b = a.'\"))\n    sword _a [] = {1, 2, 3} ;\n    a = irowvec(_a, 3, false) ;\n    b = arma::strans(a) ;\n    \"\"\"\n\n    # unknown datatype\n    if not node.num:\n        return \"arma::strans(%(0)s)\"\n\n    \"\"\"\n    # colvec -> rowvec\n    if node[0].dim == 1:\n        node.dim = 2\n\n    # rowvec -> colvec\n    elif node[0].dim == 2:\n        node.dim = 1\n    \"\"\"\n\n    # not complex type\n    #if node.mem < 4:\n    #    return \"arma::strans(\", \"\", \")\"\n\n    return \"arma::strans(\", \"\", \")\"\n\ndef Ctranspose(node):\n    \"\"\"Complex transpose\n    >>> print(matlab2cpp.qscript(\"a = [1,2,3]; b = a'\"))\n    sword _a [] = {1, 2, 3} ;\n    a = irowvec(_a, 3, false) ;\n    b = arma::trans(a) ;\n    \"\"\"\n\n    # unknown input\n    if not node.num:\n        return \"arma::trans(\", \"\", \")\"\n\n    \"\"\"\n    # colvec -> rowvec\n    if node[0].dim == 1:\n        node.dim = 2\n\n    # rowvec -> colvec\n    elif node[0].dim == 2:\n        node.dim = 1\n    \"\"\"\n\n    return \"arma::trans(\", \"\", \")\"\n\ndef Colon(node):\n    \"\"\"Colon (as operator)\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"a = 1:10; b = 1:10:2\"))\n    a = m2cpp::fspan(1, 1, 10) ;\n    b = m2cpp::fspan(1, 10, 2) ;\n    >>> print(matlab2cpp.qscript(\"a = [1,2,3]; a(1:2:2)\"))\n    sword _a [] = {1, 2, 3} ;\n    a = irowvec(_a, 3, false) ;\n    arma::strans(a(m2cpp::span<uvec>(0, 2, 1))) ;\n    \"\"\"\n\n    # context: array argument (must always be uvec)\n    if node.group.cls in (\"Get\", \"Cget\", \"Nget\", \"Fget\", \"Sget\",\n                \"Set\", \"Cset\", \"Nset\", \"Fset\", \"Sset\") and node.parent.num:\n        #node.type = \"uvec\"\n\n        node.include(\"m2cpp\")\n        # two arguments, use Armadillo span from:to\n        if len(node) == 2:\n\n            if node.parent.cls in (\"Get\", \"Cget\", \"Nget\", \"Fget\", \"Sget\",\n                \"Set\", \"Cset\", \"Nset\", \"Fset\", \"Sset\") and node.parent.num and node.parent.backend != \"reserved\":\n                if node.dim in (1, 2):\n                    return \"arma::span(%(0)s-1, %(1)s-1)\"\n\n            if node.group.backend == \"reserved\":\n                node.type = 'rowvec'\n                return \"m2cpp::fspan(%(0)s, 1, %(1)s)\"\n            return \"m2cpp::span<%(type)s>(%(0)s-1, %(1)s-1)\"\n\n        # three arguments, not supported in Armadillo\n        elif len(node) == 3:\n            if node.group.backend == \"reserved\":\n                node.type = 'rowvec'\n                return \"m2cpp::fspan(%(0)s, %(1)s, %(2)s)\"\n            return \"m2cpp::span<%(type)s>(%(0)s-1, %(1)s, %(2)s-1)\"\n\n        else:\n            return \"m2cpp::span<%(type)s>(\", \", \", \")\"\n\n    else:\n\n        # context: matrix concatination\n        #if node.group.cls in (\"Matrix\",) and node.group.num:\n        #    node.type = \"rowvec\"\n\n        # context: pass to function\n        #elif node.parent.cls in (\"Get\", \"Cget\", \"Nget\", \"Fget\", \"Sget\",\n        #        \"Set\", \"Cset\", \"Nset\", \"Fset\", \"Sset\"):\n        #    node.type = \"rowvec\"\n\n        # context: assignment\n        #elif node.group.cls in (\"Assign\",) and node.group[0].num:\n            #Below the span is set to have the same type as LHS\n            #Had to change here ass well or there will be an strans,\n            #LHS have  rowvec, while node.type (RHS) have vec dim\n            #node.type = node.group[0].type\n        #    node.type = \"rowvec\"\n            #print(node.group[0].mem)\n            #node.mem = node.group[0].mem\n\n        #else:\n        #    node.type = \"rowvec\"\n\n        #include mconvert.h, which contain namespace m2cpp\n        node.include(\"m2cpp\")\n        \n        # <start>:<stop>\n        if len(node) == 2:\n            if node.group.cls == \"Assign\":\n                node.type = 'rowvec'\n                return \"m2cpp::fspan\" + \"(%(0)s, 1, %(1)s)\"\n            return \"m2cpp::fspan\" + \"(%(0)s, 1, %(1)s)\"\n\n        # <start>:<step>:<stop>\n        elif len(node) == 3:\n            node.type = 'rowvec'\n            args = \"(%(0)s, %(1)s, %(2)s)\"\n            #return \"m2cpp::span<\" + node.type + \">\" + args\n            #return \"arma::strans(arma::linspace(%(0)s, %(2)s, (%(2)s%(1)s))\"\n            return \"m2cpp::fspan\" + args\n\n        #Sets template type to LHS:\n        # ex, ti is type vec: ti = (m2cpp::span<vec>(0, 1, nt-1))*dt ;\n        #should probably change the if statement above, context: assignment\n        #if node.group.cls == \"Assign\":\n            #print(node.group)\n            #print(node.group.cls)\n            #print(node.group[0].type)\n            #print(\"\\n\\n\\n\")\n        #    return \"m2cpp::span<\" + node.group[0].type + \">\" +args\n        return \"m2cpp::span<\" + node.type + \">(\", \", \", \")\"\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/rules/_fcube.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .cube import Get, Set, Resize\n\nDeclare = \"fcube = %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_float.py",
    "content": "from .assign import Assign\nfrom .variables import *\n\nDeclare = \"float %(name)s ;\"\nFloat = \"%(value)s\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_fmat.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .mat import Get, Set\n\nDeclare = \"fmat %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_frowvec.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .rowvec import Get, Set\n\nDeclare = \"frowvec %(name)s ;\"\n\n"
  },
  {
    "path": "src/matlab2cpp/rules/_func_lambda.py",
    "content": "\"\"\"\nAnonymous/Lambda Functions\n\"\"\"\n\nimport matlab2cpp\n\nfrom .function import type_string\nfrom .assign import Assign\n\ndef Get(node):\n    \"\"\"Function call of an lambda function\n\nContains: Expression*\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"x = 4; f = @() x; y = f()\"))\n    x = 4 ;\n    f = [x] () {x ; } ;\n    y = f() ;\n    \"\"\"\n    return \"%(name)s(\", \", \", \")\"\n\nVar = \"%(name)s\"\n\n\n\ndef Lambda(node):\n    \"\"\"Lambda function statement\n\nDuring construction, builder creates a full function for lambda expression.\nThese functions are available through node.reference.\n\nProperty: name (of function)\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"f = @() 4\"))\n    f = [] () {4 ; } ;\n    \"\"\"\n\n    # lambda function are created as full functions, but referenced to be\n    # written inline\n    lfunc = node.reference\n    ldeclares, lreturns, lparams, lblock = lfunc\n    lnames = lparams.names + ldeclares.names\n    expr = lblock[0][1]\n\n    # location for where lambda is created\n    func = node.func\n    declares, returns, params, block = func\n\n    out = \"\"\n\n    # declare list in lambda function\n    for declare in declares:\n        if declare not in ldeclares:\n            continue\n\n        name = declare.name\n        out += \", \" + name\n\n    # translate again where datatypes updated\n    expr.translate()\n    lfunc.translate()\n\n    # return string\n    out = \"[\" + out[2:] + \"] \"\n    out += \"(\" + str(lparams) + \") {\" + str(expr) + \" ; }\"\n    return out\n\nReturns = \"\"\n\ndef Params(node):\n    \"\"\"Parameter structure in lambda functions\n\nContains: Var*\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"f = @(x,y,z) x+y+z; f(1,2.,'3')\"))\n    f = [] (int x, double y, std::string z) {x+y+z ; } ;\n    f(1, 2., \"3\") ;\n    \"\"\"\n    return \", \".join([\"%s %s\" % (type_string(n), n.name) for n in node])\n\ndef Declares(node):\n    \"\"\"Variable scope in lambda function\n\nIf variables\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"x = 4; f = @() x+2\"))\n    x = 4 ;\n    f = [x] () {x+2 ; } ;\n    \"\"\"\n\n    # handle in Lambda\n    return \"\"\n\n# Actual lambda function is hidden\nFunc = \"\"\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/rules/_func_return.py",
    "content": "\"\"\"\nFunctions with single return\n\nNodes\n-----\nFunc : Function definition\n    Contains: Declares, Returns, Params, Block\n    Property: name\n\nReturns : Function return variables\n    Contains: Var, ...\n\nParams : Function parameter variables\n\nGet : Function call\n    Example: \"y(4)\"\n    Contains: Gets\n    Property: name\n\nVar : Function call hidden as variable\n    Example \"y\"\n    Contains: nothing\n\"\"\"\n\nimport matlab2cpp\n\nfrom .function import type_string\nfrom .variables import Get\nfrom .assign import Assign\n\n\ndef Var(node):\n    \"\"\"\n    Function call as variable\n\n    Writing a function as if a variable, is equivalent to calling the function\n    without arguments.\n\n    property: name (of variable)\n\n    Examples:\n        >>> print(matlab2cpp.qscript(\"function y=f(); y=1; end; function g(); f\"))\n        int f()\n        {\n          int y ;\n          y = 1 ;\n          return y ;\n        }\n        <BLANKLINE>\n        void g()\n        {\n          f() ;\n        }\n    \"\"\"\n    # push the job over to Get\n    return Get(node)\n\nReturns = \"\", \"\"\n\"\"\"single return value are used verbatim\"\"\"\n\ndef Params(node):\n    \"\"\"\n    Parameters in functions with one return\n\n    Adds type prefix.\n\n    Contains: Var*\n\n    Examples:\n        >>> code = \"function y=f(a,b,c,d,e); y=1\"\n        >>> from matlab2cpp.tree import Builder\n        >>> builder = Builder()\n        >>> builder.load(\"unamed\", code)\n        >>> builder[0].ftypes = {\"f\":{\"a\": \"int\", \"b\":\"double\", \"c\":\"cx_mat\",\n        ...     \"d\":\"func_lambda\", \"e\":\"struct\", \"y\":\"int\"}}\n        >>> print(matlab2cpp.qscript(builder))\n        int f(int a, double b, cx_mat c, std::function d, _E e)\n        {\n          int y ;\n          y = 1 ;\n          return y ;\n        }\n    \"\"\"\n    out = \"\"\n\n    # if -ref, -reference flag option\n    if node.project.builder.reference:\n        out += \", \".join([\"const \" + type_string(child) + \"& \" + child.name if child.dim > 0 else\n                           type_string(child) + \" \" + child.name for child in node])\n\n    else:\n        out = \", \".join([type_string(child) + \" \" + child.name for child in node])\n\n    return out\n\n\ndef Declares(node):\n    \"\"\"\n    Declarations in the beginning of function\n\n    Contains: Var*\n\n    Examples:\n        >>> print(matlab2cpp.qscript(\"function d=f(); a=1; b.c='2'; d.e(1)=[4,5]\"))\n        _D f()\n        {\n          _B b ;\n          _D d ;\n          int a ;\n          a = 1 ;\n          b.c = \"2\" ;\n          sword _d [] = {4, 5} ;\n          d.e[0] = irowvec(_d, 2, false) ;\n          return d ;\n        }\n    \"\"\"\n    if not node:\n        return \"\"\n\n    returns = node.parent[1]\n\n    declares = {}   # {\"int\" : [\"a\", \"b\"]} -> int a, b ;\n    structs = {}    # {\"_A\" : \"a\"} -> _A a;\n\n    # fill declares and structs\n    for child in node[:]:\n\n        type = type_string(child)\n\n        if type not in declares:\n            declares[type] = []\n\n        declares[type].append(child)\n\n        if child.type == \"structs\":\n            structs[child.name] = child\n\n    # create output\n    out = \"\"\n    keys = sorted(declares.keys())\n    for key in keys:\n        val = sorted(declares[key], key=lambda x: x.name)\n\n        # datatype\n        out += \"\\n\" + key + \" \"\n\n        # all variables with that type\n        for v in val:\n\n            out += str(v)\n            if v.name in structs:\n\n                structs_ = node.program[3]\n                struct = structs_[structs_.names.index(v.name)]\n                size = struct[struct.names.index(\"_size\")].value\n                out += \"[%s]\" % size\n\n            out += \", \"\n\n        out = out[:-2] + \" ;\"\n\n    return out[1:]\n\n\ndef Func(node):\n    \"\"\"\n    Function declaration\n\n    Contains: Declares Returns Params Block\n    Property: name (of function)\n\n    Examples:\n        >>> print(matlab2cpp.qscript(\"function y=f(); y=1\"))\n        int f()\n        {\n          int y ;\n          y = 1 ;\n          return y ;\n        }\n    \"\"\"\n    # type information is in params and declare, not return\n    retname = node[1][0].name\n    if retname in node[0].names:\n        retval = node[0][node[0].names.index(retname)]\n    if retname in node[2].names:\n        retval = node[2][node[1].names.index(retname)]\n    rettype = type_string(retval)\n\n    # empty code_block function with return statement\n    if len(node[-1]) == 0:\n        return rettype + \"\"\" %(name)s(%(2)s)\n{\nreturn %(1)s\n}\"\"\"\n\n    # function ends with a return statement\n    if node[-1][-1] and node[-1][-1][-1].cls == \"Return\":\n        return rettype + \"\"\" %(name)s(%(2)s)\n{\n%(0)s\n%(3)s\n}\"\"\"\n\n    return rettype + \"\"\" %(name)s(%(2)s)\n{\n%(0)s\n%(3)s\nreturn %(1)s ;\n}\"\"\"\n\n\ndef Main(node):\n    \"\"\"\n    Main function\n\n    Contains: Declares Returns Params Block\n    Property: name (of function)\n\n    Examples:\n        >>> print(matlab2cpp.qcpp(\"4\"))\n        #include <armadillo>\n        using namespace arma ;\n        <BLANKLINE>\n        int main(int argc, char** argv)\n        {\n          4 ;\n          return 0 ;\n        }\n    \"\"\"\n\n    # has variables to declare\n    if node[0]:\n        return \"\"\"int main(int argc, char** argv)\n{\n%(0)s\n%(3)s\nreturn 0 ;\n}\"\"\"\n    return \"\"\"int main(int argc, char** argv)\n{\n%(3)s\nreturn 0 ;\n}\"\"\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_func_returns.py",
    "content": "\"\"\"\nFunctions with multiple returns\n\"\"\"\n\nimport matlab2cpp\nfrom .function import type_string\nfrom .variables import Get\n\n\ndef Func(node):\n    \"\"\"Function declaration\n\nContains: Declares Returns Params Block\nProperty: name (of function)\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"function f()\"))\n    void f()\n    {\n      // Empty block\n    }\n    \"\"\"\n\n    if len(node[1]) and len(node[2]):\n        if len(node[0])>len(node[1]):\n            return \"\"\"void %(name)s(%(2)s, %(1)s)\n{\n%(0)s\n%(3)s\n}\"\"\"\n        return \"\"\"void %(name)s(%(2)s, %(1)s)\n{\n%(3)s\n}\"\"\"\n\n    # one of returns or params are missing\n    if len(node[0])>len(node[1]):\n        return \"\"\"void %(name)s(%(2)s%(1)s)\n{\n%(0)s\n%(3)s\n}\"\"\"\n    return \"\"\"void %(name)s(%(2)s%(1)s)\n{\n%(3)s\n}\"\"\"\n\n\n\ndef Var(node):\n    \"\"\"Function call as variable\n    \nWriting a function as if a variable, is equivalent to calling the function\nwithout arguments.\n\nProperty: name (of variable)\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"function f(); end; function g(); f\"))\n    void f()\n    {\n      // Empty block\n    }\n    <BLANKLINE>\n    void g()\n    {\n      f() ;\n    }\n\"\"\"\n    # push the job over to Get\n    return Get(node)\n\ndef Assign(node):\n    \"\"\"The function have multiple returns, but only one lhs return.\n\n    \"\"\"\n    return Assigns(node)\n\ndef Assigns(node):\n    \"\"\"\n    Assignment where rhs is a function call and lhs are multiple returns.\n\n    Concatenates return variables after the parameters, if any.\n\n    Property: name (of function)\n    Contains: Expression Expression+ Get\n\n    Examples:\n        >>> print(matlab2cpp.qscript('''function [a,b]=f(c,d); a=c; b=d\n        ...     function g(); [a,b] = f(1,2.)'''))\n        void f(int c, double d, int& a, double& b)\n        {\n          a = c ;\n          b = d ;\n        }\n        <BLANKLINE>\n        void g()\n        {\n          double b ;\n          int a ;\n          f(1, 2., a, b) ;\n        }\n    \"\"\"\n    # existence of parameters in function call\n    if node[-1]:\n        params = [s.str for s in node[-1]]\n        params = \", \".join(params) + \", \"\n\n    else:\n        params = \"\"\n\n    returns = [s.str for s in node[:-1]]\n    returns = \", \".join(returns)\n\n    return \"%(name)s(\" + params + returns + \") ;\"\n\ndef Returns(node):\n    \"\"\"Return value in function definition with zero or multiple returns\n\nAdds type prefix and '&' (since they are to be placed in parameters)\n\nContains: Return*\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"function [a,b]=f(); a=1, b=2.\"))\n    void f(int& a, double& b)\n    {\n      a = 1 ;\n      b = 2. ;\n    }\n    \"\"\"\n\n    out = \"\"\n    for child in node[:]:\n        out += \", \" + type_string(child) + \"& \" + str(child)\n    return out[2:]\n\n\ndef Params(node):\n    \"\"\"Parameters in function definition with zero or multiple returns\n\nAdds type prefix.\n\nContains: Var*\n\nExamples:\n    >>> ftypes = {\"f\": {\"a\":\"int\", \"b\":\"double\"}}\n    >>> print(matlab2cpp.qscript(\"function f(a,b)\", ftypes=ftypes))\n    void f(int a, double b)\n    {\n      // Empty block\n    }\n    \"\"\"\n\n    # Create list of parameters\n    out = \"\"\n\n    # if -ref, -reference flag option\n    if node.project.builder.reference:\n\n        out += \", \".join([\"const \" + type_string(child) + \"& \" + child.name if child.dim > 0 else\n                           type_string(child) + \" \" + child.name for child in node])\n\n        return out\n\n    else:\n        out = \", \".join([type_string(child) + \" \" + child.name for child in node])\n\n    return out\n\n\ndef Declares(node):\n    \"\"\"Variables declared on the top of the function\n\nContains: Declare*\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"function f(); a=1; b.c='2'; d.e(1)=[4,5]\"))\n    void f()\n    {\n      _B b ;\n      _D d ;\n      int a ;\n      a = 1 ;\n      b.c = \"2\" ;\n      sword _d [] = {4, 5} ;\n      d.e[0] = irowvec(_d, 2, false) ;\n    }\n    \"\"\"\n\n    # nothing to declare\n    if not node:\n        return \"\"\n\n    returns = node.parent[1]\n\n    declares = {}   # {\"int\" : [\"a\", \"b\"]} -> int a, b ;\n    structs = {}    # {\"_A\" : \"a\"} -> _A a;\n\n    # fill declares and structs\n    for child in node[:]:\n\n        # return values in multi-returns are declared as parameter\n        if child.name in returns:\n            continue\n\n        type = type_string(child)\n\n        if type not in declares:\n            declares[type] = []\n\n        declares[type].append(child)\n\n        if child.type == \"structs\":\n            structs[child.name] = child\n\n    # create output\n    out = \"\"\n    keys = sorted(declares.keys())\n    for key in keys:\n\n        val = sorted(declares[key], key=lambda x: x.name)\n\n\n        # datatype\n        out += \"\\n\" + key + \" \"\n\n        # all variables with that type\n        for v in val:\n\n            out += str(v)\n            if v.name in structs:\n\n                structs_ = node.program[3]\n                struct = structs_[structs_.names.index(v.name)]\n                size = struct[struct.names.index(\"_size\")].value\n                out += \"[%s]\" % size\n\n            out += \", \"\n\n        out = out[:-2] + \" ;\"\n\n    return out[1:]\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/rules/_fvec.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .vec import Get, Set\n\nDeclare = \"fvec %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_icube.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .cube import Get, Set, Resize\n\nDeclare = \"icube = %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_imat.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .mat import Get, Set\n\nDeclare = \"imat %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_int.py",
    "content": "from .assign import Assign\nfrom .variables import *\n\n# Declare = \"int %(name)s ;\"\nInt = \"%(value)s\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_irowvec.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .rowvec import Get, Set\n\nDeclare = \"irowvec %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_ivec.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .vec import Get, Set\n\nDeclare = \"ivec %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_mat.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .mat import Get, Set\n\nDeclare = \"mat %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_matrix.py",
    "content": "\"\"\"\nMatrix declaration rules\n\nNodes\n-----\nMatrix : Matrix container\n    Example: \"[x;y]\"\n    Contains: Vector, ...\n\nVector : (Column)-Vector container\n    Contains: Expr, ...\n\"\"\"\nfrom ._code_block import Statement\nfrom . import assign, armadillo as arma\n\n\ndef Vector(node):\n    \"\"\"A (row-)vector\n    \"\"\"\n\n    if node.value == \"scalarsonly\":\n        return \"\", \", \", \"\"\n\n    if node.type == \"string\":\n        return \"\", \" + \", \"\" \n\n    nodes = [str(n) for n in node]\n\n    #max mem in list and type list\n    try:\n        mem = max([int(n.mem) if n.num else -1 for n in node])\n    except:\n        mem = -1\n    mem_type = [\"uword\", \"sword\", \"float\", \"double\", \"cx_double\"]\n\n    #Join columns: a = [0, my_rowvec, b]\n    for i in range(len(nodes)):\n        # scalars must be converted first\n        if node[i].value or node[i].dim == 0: # value=scalarsonly\n            node[i].include(\"m2cpp\")\n            if mem != -1:\n                nodes[i] = \"m2cpp::srow<\" + mem_type[mem] + \">(\" + nodes[i] + \")\"\n            else:\n                nodes[i] = \"m2cpp::srow(\" + nodes[i] + \")\"\n\n    if nodes:\n        out = str(nodes[0])\n        for node_ in nodes[1:]:\n            out = \"arma::join_rows(%s, %s)\" % (out, node_)\n        return out\n    return \"\"\n\n\ndef Matrix(node):\n\n    # ensure all vectors in matrix same length\n    m = len(node[0])\n    if any([len(n)-m for n in node if n.value == \"scalarsonly\"]):\n        shape = str([len(n) for n in node if n.value == \"scalarsonly\"])\n        node.error(\"shape missmatch %s\" % shape)\n\n    if node.type == \"string\":\n        if len(node) > 1:\n            return \"\", \" + \", \"\"\n        return \"\", \" \", \"\"\n\n    #clims in imagesc needs two {{ and }} for the python implementation\n    if node.parent.name in (\"imagesc\", \"wigb\") and \\\n      len(node) == 1 and len(node[0]) > 1:\n        if all([n.dim == 0 for n in node[0]]):\n            return \"{{\", \", \", \"}}\"\n        #{ } around arma::join_rows()\n        return \"{\", \", \", \"}\"\n\n    # non-numerical elements in matrix\n    if not node.num:\n        if len(node[0]) == 1 and node[0][0].cls == \"Colon\":\n            return \"\", \", \", \"\"\n        return \"{\", \", \", \"}\"\n\n    dims = {n.dim for n in node}\n\n    # single vector with no content\n    if len(node) == 1 and len(node[0]) == 0:\n        return \"{\", \", \", \"}\"\n\n    # everything on scalarsonly form\n    elif all([n.value for n in node]):\n\n        # Inline matrices are moved to own lines\n        if node.parent.cls not in (\"Assign\", \"Statement\") and \\\n                    node.parent.backend != \"reserved\":\n            if node.parent.cls in (\"Get\", \"Set\") and node.mem != 0:\n                if node.parent.type == \"TYPE\":\n                    node.type = (node.dim, 3)\n                else:\n                    node.type = (node.dim, 0)\n            return str(node.auxiliary())\n\n        # if node.parent.cls in (\"Assign\", \"Statement\"):\n        #     node.parent.backend = \"matrix\"\n\n        return \"{\", \", \", \"}\"\n\n\n    # mix of scalars and colvecs, scalar and matrix, scalar and vec and matrix\n    elif dims in ({0, 1}, {1}, {0, 3}, {0, 1, 3}):\n\n        # make string of each vector in matrix\n        nodes = []\n        for i in range(len(node)):\n\n            #max mem in list and type list\n            try:\n                mem = max([int(n.mem) if n.num else -1 for n in node])\n            except:\n                mem = -1\n            mem_type = [\"uword\", \"sword\", \"float\", \"double\", \"cx_double\"]\n\n            # scalars must be converted first\n            if node[i].value or node[i].dim == 0: # value=scalarsonly\n                node[i].include(\"m2cpp\")\n                if mem != -1:\n                    nodes.append(\"m2cpp::scol<\" + mem_type[mem] + \">(\" + str(node[i]) + \")\")\n                else:\n                    nodes.append(\"m2cpp::scol(\" + str(node[i]) + \")\")\n            else:\n                nodes.append(str(node[i]))\n\n    # mix of rowvecs and matrices, mix of columnvecs and matrices\n    elif dims in ({2}, {3}, {2, 3}, {1, 3}):\n\n        # make string of each vector in matrix\n        nodes = []\n        for idx in range(len(node)):\n\n            # decomposed vectors should be moved to own lines\n            if node[idx].value:\n                nodes.append(str(node[idx].auxiliary()))\n            else:\n                nodes.append(str(node[idx]))\n\n    out = str(nodes[0])\n    for node_ in nodes[1:]:\n        out = \"arma::join_cols(%s, %s)\" % (out, node_)\n    if node.parent.name in (\"imagesc\", \"wigb\"):\n        out = \"{%s}\" % out\n    return out\n\n\ndef Assign(node):\n\n    #left-hand-side, right-hand-side\n    lhs, rhs = node\n\n    assert rhs.cls in (\"Matrix\", \"Cell\")\n\n    # no content in matrix\n    if len(rhs[0]) == 0:\n        return \"%(0)s.reset() ;\"\n\n    # non-numerical values in matrix or variable assign\n    if not lhs.num or not rhs.num:\n        return \"%(0)s = %(1)s ;\"\n\n    # new local variable 'ctype' contains convertion type\n    node.type = node[\"ctype\"] = node[0].type\n    dim = node.dim\n    node.dim = 0\n\n    # decomposed matrix\n    if rhs.value:\n\n        type = node.type\n        if type == \"int\":\n            type = \"sword\"\n\n        # scalar\n        if rhs.dim == 0:\n            return arma.scalar_assign(node)\n\n        # colvec\n        elif rhs.dim == 1:\n\n            # save number of rows as 'rows'\n            node[\"rows\"] = len(node[1][0])*len(node[1])\n\n            if node.prop[\"ctype\"] == \"mat\":\n                return type + \" _\" + node[0].name + \" [] = %(1)s ;\\n\"+\\\n                \"%(0)s = %(ctype)s(_\" + node[0].name + \", %(rows)s, 1, false) ;\"\n            else:\n                return type + \" _\" + node[0].name + \" [] = %(1)s ;\\n\"+\\\n                \"%(0)s = %(ctype)s(_\" + node[0].name + \", %(rows)s, false) ;\"\n\n            # use uniform initialization\n            #return \"%(0)s = %(1)s ;\"\n\n        # rowvec\n        elif rhs.dim == 2:\n\n            # save number of cols as 'cols'\n            node[\"cols\"] = len(node[1][0])*len(node[1])\n\n            if node.prop[\"ctype\"] == \"mat\":\n                return type + \" _\" + node[0].name + \" [] = %(1)s ;\\n\"+\\\n                \"%(0)s = %(ctype)s(_\" + node[0].name + \", 1, %(cols)s, false) ;\"\n            else:\n                return type + \" _\" + node[0].name + \" [] = %(1)s ;\\n\"+\\\n                \"%(0)s = %(ctype)s(_\" + node[0].name + \", %(cols)s, false) ;\"\n\n            # use uniform initialization\n            #return \"%(0)s = %(1)s ;\"\n\n        # matrix\n        elif rhs.dim == 3:\n            # save number of rows and columns\n            node[\"rows\"] = len(node[1][0])\n            node[\"cols\"] = len(node[1])\n            return type + \" _\" + node[0].name + \" [] = %(1)s ;\\n\"+\\\n            \"%(0)s = arma::strans(%(ctype)s(_\" + node[0].name + \", %(rows)s, %(cols)s, false)) ;\"\n\n            # use uniform initialization\n            #my_list = node[1].children\n            #my_list = [\"{\" + str(elem) + \"}\" for elem in my_list]\n            #return \"%(0)s = {\" + \", \".join(my_list) + \"} ;\"\n\n        assert False\n\n    else:\n        node.dim = dim\n\n    return assign.Assign(node)\n\n\nVar = \"%(name)s\"\n\ndef Cell(node):\n\n    # move inline cells to own lines\n    if node.parent.cls not in (\"Assign\", \"Assigns\"):\n        node.auxiliary()\n\n    return \"{\", \", \", \"}\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_program.py",
    "content": "import re\n\nimport matlab2cpp\nfrom . import armadillo as arma\nfrom .function import type_string\n\ndef add_indenting(text):\n    \"\"\"Add identing to text\n    \"\"\"\n\n    lines = text.split(\"\\n\")\n\n    indent = 0\n    for i in range(len(lines)):\n        line = lines[i]\n\n        # Fix indentation and linesplit\n        if line in (\"}\", \"} ;\") or line[:4] == \"} //\":\n            indent -= 1\n            line = \"  \"*indent + line\n\n        elif line == \"{\":\n            line = \"  \"*indent + line\n            indent += 1\n        else:\n            line = \"  \"*indent + line\n        lines[i] = line\n\n    text = \"\\n\".join(lines)\n\n    return text\n\n\ndef number_fix(text):\n    \"\"\"Code has allot of '-1' statements in indexing. This code substitutes\nexplicit number subtractions with the single index equivalent.\n\nExamples:\n    >>> print(number_fix(\"a(8-1, 5-1)\"))\n    a(7, 4)\n    \"\"\"\n    # Cosmetic fix\n    for p0,p1,p2 in set(re.findall(r\"(([ ,(\\[])(-?\\d+)-1(?![*/]))\", text)):\n        val = int(p2)-1\n        val = p1+str(val)\n        text = val.join(text.split(p0))\n\n    for p0,p1,p2 in \\\n            set(re.findall(r\"(([+\\- ])(\\d+)-1(?![*/]))\", text)):\n        if p1==\"-\":     val = int(p2)+1\n        else:           val = int(p2)-1\n        if val:         val = p1+str(val)\n        else:           val = \"\"\n        text = val.join(text.split(p0))\n\n    text = re.sub(r\"\\+-\", r\"-\", text)\n    return text\n\n\ndef strip(text):\n    \"\"\"Remove trailing spaces and linefeeds.\n    \"\"\"\n    if not text: return text\n\n    start = 0\n    while text[start] in \"\\n \":\n        start += 1\n    end = 0\n    while text[end-1] in \"\\n \":\n        end -= 1\n\n    if end:\n        text = text[start:end]\n    else:\n        text = text[start:]\n\n    return text\n\ndef Project(node):\n    return \"\"\n\ndef Program(node):\n    arma.include(node)\n    return \"\"\n\ndef Includes(node):\n    return \"\", \"\\n\", \"\"\n\ndef Headers(node):\n    return \"\", \"\\n\", \"\"\n\n\ndef Header(node):\n    func = node.program[1][node.program[1].names.index(node.name)]\n    if func.backend == \"func_return\":\n\n        # if -ref, -reference flag option\n        if node.project.builder.reference:\n\n            code = func[1][0].type + \" \" + func.name + \"(\" +\\\n                   \", \".join([\"const \" + type_string(p) + \"& \" + p.name if p.dim > 0 else\n                           type_string(p) + \" \" + p.name for p in func[2]]) + \") ;\"\n\n        else:\n            code = func[1][0].type + \" \" + func.name + \"(\" +\\\n            \", \".join([type_string(p) + \" \" + p.name for p in func[2]]) + \") ;\"\n\n\n    elif func.backend == \"func_returns\" and not func[1]:\n\n        # if -ref, -reference flag option\n        if node.project.builder.reference:\n            code = \"void \" + func.name + \"(\" +\\\n                \", \".join([\"const \" + type_string(p) + \"& \" + p.name if p.dim > 0 else\n                           type_string(p) + \" \" + p.name for p in func[2]]) + \") ;\"\n\n        else:\n            code = \"void \" + func.name + \"(\" +\\\n            \", \".join([type_string(p) + \" \" + p.name for p in func[2]]) + \") ;\"\n\n    elif func.backend == \"func_returns\" and func[1]:\n\n        # if -ref, -reference flag option\n        if node.project.builder.reference:\n            code = \"void \" + func.name + \"(\" +\\\n                \", \".join([\"const \" + type_string(p) + \"& \" + p.name if p.dim > 0 else\n                           type_string(p) + \" \" + p.name for p in func[2]]) + \", \" +\\\n                \", \".join([type_string(p) + \"& \" + p.name for p in func[1]]) + \") ;\"\n\n        else:\n            code = \"void \" + func.name + \"(\" +\\\n            \", \".join([type_string(p) + \" \" + p.name for p in func[2]]) + \", \" +\\\n            \", \".join([type_string(p) + \"& \" + p.name for p in func[1]]) + \") ;\"\n\n\n\n    return code\n\nInclude = \"%(name)s\"\n\n\ndef Funcs(node):\n    text = \"\\n\\n\".join(map(str, node[:]))\n    # text = add_indenting(text)\n    # text = number_fix(text)\n    text = re.sub(r\"\\n *(\\n *)+\", r\"\\n\\n\", text)\n    # text = strip(text)\n\n    return text\n\ndef Inlines(node):\n\n    if not node:\n        return \"\"\n\n    text = \"\\n\\n\".join([n.name for n in node])\n\n    text = \"\"\"#ifndef MCONVERT_H\n#define MCONVERT_H\n\nnamespace m2cpp\n{\n\"\"\" + text + \"\"\"\n}\n\n#endif\n\"\"\"\n    # text = add_indenting(text)\n    return text\n\ndef Inline(node):\n    return \"\"\n\nStructs = \"\", \"\\n\\n\", \"\"\n\ndef Log(node):\n    return \"\", \"\\n\\n\", \"\"\n\n\ndef Error(node):\n    cls = node.name.split(\":\")[0]\n    return 'Error in class ' + cls + ''' on line %(line)d:\n%(code)s\n''' + \" \"*node.cur + \"^\\n%(value)s\"\n\ndef Warning(node):\n    cls = node.name.split(\":\")[0]\n    return 'Warning in class ' + cls + ''' on line %(line)d:\n%(code)s\n''' + \" \"*node.cur + \"^\\n%(value)s\"\n\ndef Struct(node):\n\n    name = \"_\"+node.name.capitalize()\n    out = \"struct \" + name + \"\\n{\"\n\n    declares = {}\n    for child in node[:]:\n\n        type = child.type\n        if type == \"func_lambda\":\n            type == \"std::function\"\n\n        if type == \"structs\":\n            continue\n\n        if type not in declares:\n            declares[type] = []\n\n        declares[type].append(child)\n\n    for key, val in declares.items():\n        out = out + \"\\n\" + key + \" \" + \", \".join([str(v) for v in val]) + \" ;\"\n    out = out + \"\\n} ;\"\n\n    # out = add_indenting(out)\n\n    return out\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/rules/_reserved.py",
    "content": "\"\"\"\nReserved translation rules\n\nSee :py:attr:`rules.reserved <matlab2cpp.rules.reserved>` for a collection of\nset of the various reserved words implemented into matlab2cpp.\n\"\"\"\n\nimport matlab2cpp\n\n# List of function names that should be handled by reserved.py:\nreserved = {\n    \"and\", \"or\", \"not\", \"all\", \"any\", \"isequal\",\n    \"false\", \"true\", \"pi\", \"inf\", \"Inf\", \"nan\", \"NaN\",\n    \"eps\", \"exp\", \"log\", \"log2\", \"log10\", \"power\", \"floor\", \"ceil\", \"fix\",\n    \"cos\", \"acos\", \"cosh\", \"acosh\",\n    \"sin\", \"asin\", \"sinh\", \"asinh\", \"mod\",\n    \"eye\", \"fliplr\", \"flipud\", \"length\", \"max\", \"min\", \"size\", \"chol\",\n    \"trace\", \"transpose\", \"ctranspose\",\n    \"abs\", \"sqrt\", \"nextpow2\", \"fft\", \"ifft\", \"fft2\", \"ifft2\", \"hankel\",\n    \"zeros\", \"ones\", \"round\", \"return\", \"rand\",\n    \"qr\",\n    \"clear\", \"close\", \"clc\", \"clf\", \"more\", \"format\",\n    \"_conv_to\", \"_reshape\", \"reshape\",\n    \"interp1\", \"linspace\", \"varargin\",\n    \"sum\", \"cumsum\", \"conj\", \"real\", \"imag\",\n    \"tic\", \"toc\", \"diag\", \"tril\", \"triu\",\n    \"disp\", \"fprintf\", \"error\", \"convmtx\", \"conv2\",\n    \"figure\", \"clf\", \"cla\", \"show\", \"xlabel\", \"ylabel\", \"hold\", \"load\",\n    \"title\", \"plot\", \"imshow\", \"imagesc\", \"wigb\", \"colorbar\",\n    \"xlim\", \"ylim\", \"caxis\", \"axis\", \"grid\", \"subplot\", \"colormap\",\n    \"_splot\", \"logspace\", \"find\", \"unique\", \"intersect\", \"isempty\", \"sortrows\",\n}\n\n# Common attribute\n\nfrom .assign import Assign\n#Assign = \"%(0)s = %(1)s ;\"\n\ndef Var(node):\n    return \"%(name)s\"\n\nVar_pi = \"datum::pi\"\nVar_true = \"1\"\nVar_false = \"0\"\nVar_inf = \"datum::inf\"\nVar_Inf = \"datum::inf\"\nVar_nan = \"datum::nan\"\nVar_NaN = \"datum::nan\"\nVar_eps = \"datum::eps\"\n\ndef Get_NaN(node):\n    return \"arma::zeros(\", \", \", \") * datum::nan\"\n\ndef conv_to(str, type):\n    return \"arma::conv_to<\" + type +  \">::from(\" + str + \")\"\n\ndef Assign_elemwise_(node):\n\n    if node[0].type != node[1].type:\n\n        if node[0].dim == 0 and node[1].dim == 0:\n            return \"%(0)s = \" + node[0].type + \"(%(1)s) ;\"\n\n        if node[0].dim == 0 and node[1].dim > 0:\n            if node[0].mem != node[1].mem:\n                return \"%(0)s = \" + node[0].type + \"(arma::as_scalar(%(1)s)) ;\"\n            return \"%(0)s = arma::as_scalar(%(1)s) ;\"\n\n        if node[0].mem != node[1].mem:\n            return \"%(0)s = arma::conv_to<\" + node[0].type + \">::from(%(1)s) ;\"\n\n    return \"%(0)s = %(1)s ;\"\n\ndef Get_exp(node):\n    node.type = node[0].type\n    # scalar done through std\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::exp(\", \", \", \")\"\n\n    return \"arma::exp(\", \", \", \")\"\n\ndef Get_log(node):\n    node.type = node[0].type\n    # scalar done through std\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::log(\", \", \", \")\"\n    return \"arma::log(\", \", \", \")\"\n\ndef Get_log2(node):\n    node.type = node[0].type\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::log(%(0)s)/std::log(2)\"\n        #seems like it is a C++11 feature\n        #return \"std::log2(\", \", \", \")\"\n    return \"arma::log2(\", \", \", \")\"\n\ndef Get_log10(node) :\n    node.type = node[0].type\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::log10(\", \", \", \")\"\n    return \"arma::log10(\", \", \", \")\"\n\ndef Get_power(node):\n    node.type = node[0].type\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::pow(\", \", \", \")\"\n    return \"arma::pow(\", \", \", \")\"\n\ndef Get_floor(node):\n    # unknown input\n    #if node[0].type == \"TYPE\":\n    #    return \"floor(\", \", \", \")\"\n    node.type = node[0].type\n\n    # scalar done through std\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::floor(\", \", \", \")\"\n\n    return \"arma::floor(\", \", \", \")\"\n\ndef Get_ceil(node):\n    node.type = node[0].type\n    # scalar done through std\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::ceil(%(0)s)\"\n\n    return \"arma::ceil(%(0)s)\"\n\ndef Get_round(node):\n    node.type = node[0].type\n    assert len(node)<3\n\n    # number of decimals to retain\n    if len(node) == 2:\n        decimals = str(node[1])\n    else:\n        decimals = \"0\"\n\n    # int and uword do not have decimals\n    if node[0].mem < 2:\n        return \"%(0)s\"\n\n    # hack to cut-off for scalars\n    if node[0].dim == 0:\n        node.include(\"cmath\")\n        if decimals == \"0\":\n            return \"std::round(%(0)s)\"\n        return \"std::round(%(0)s*std::pow(10, %(1)s))*std::pow(10, -%(1)s)\"\n\n    # hack for cut-off for array-type\n    if decimals == \"0\":\n        return \"arma::round(%(0)s)\"\n    return \"arma::round(%(0)s*std::pow(10, %(1)s))*std::pow(10, -%(1)s)\"\n\ndef Get_fix(node):\n    node.type = node[0].type\n\n    if node[0].mem < 2:\n        return \"%(0)s\"\n\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"mconvert\")\n        return \"m2cpp::fix(%(0)s)\"\n\n    return \"arma::trunc(%(0)s)\"\n\ndef Assign_fix(node):\n    return Assign_elemwise_(node)\n\ndef Get_cos(node):\n    node.type = node[0].type\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::cos(\", \", \", \")\"\n    return \"arma::cos(\", \", \", \")\"\n\ndef Get_acos(node):\n    node.type = node[0].type\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::acos(\", \", \", \")\"\n    return \"arma::acos(\", \", \", \")\"\n\ndef Get_cosh(node):\n    node.type = node[0].type\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::cosh(\", \", \", \")\"\n    return \"arma::cosh(\", \", \", \")\"\n\ndef Get_acosh(node):\n    node.type = node[0].type\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        #is a C++11 feature\n        return \"std::acosh(\", \", \", \")\"\n    return \"arma::acosh(\", \", \", \")\"\n\ndef Get_sin(node):\n    node.type = node[0].type\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::sin(\", \", \", \")\"\n    return \"arma::sin(\", \", \", \")\"\n\ndef Get_asin(node):\n    node.type = node[0].type\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::asin\", \", \", \")\"\n    return \"arma::asin(\", \", \", \")\"\n\ndef Get_sinh(node):\n    node.type = node[0].type\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::sinh\", \", \", \")\"\n    return \"arma::sinh(\", \", \", \")\"\n\ndef Get_asinh(node):\n    node.type = node[0].type\n    if node[0].dim == 0 and node[0].mem != 4:\n        node.include(\"cmath\")\n        return \"std::asinh\", \", \", \")\"\n    return \"arma::asinh(\", \", \", \")\"\n\n# Special handle of 'i'-variable\n\"\"\" removed from reserved: \"i\",\ndef Var_i(node):\n    return \"cx_double(0, 1)\"\n\"\"\"\n\ndef Get_mod(node):\n    node.type = node[0].type\n    if node[0].dim == 0 and node[0].mem != 4:\n        return \"\", \" __percent__ \", \"\"\n    return \"mod(\", \", \", \")\"\n\ndef Get_abs(node):\n    node.type = node[0].type\n    if len(node) and node[0].dim == 0:\n        if node[0].mem == 4: #cx_double\n            node.include(\"m2cpp\")\n            return \"abs(m2cpp::smat(%(0)s))\"\n        node.include(\"cmath\")\n        return \"std::abs(\", \", \", \")\"\n    return \"abs(\", \", \", \")\"\n\ndef Get_sqrt(node):\n    node.type = node[0].type\n    #if len(node) > 0 ...\n    if len(node) and node[0].cls == \"Neg\" and len(node[0]) == 1:\n        return \"cx_double(0, \" + node[0][0].str + \")\"\n    return \"sqrt(\", \", \", \")\"\n\ndef Get_and(node):\n    return \"(\", \"*\", \")\"\n\ndef Get_or(node):\n    return \"(\"+\"+\".join([\"%(\" + i +\")s*%(\" + i + \")s\" \\\n            for i in range(len(node))])+\")\"\n\ndef Get_not(node):\n    assert len(node) == 1\n    if not node[0].num:\n        return \"not(%(0)s)\"\n    return \"(%(0)s == 0)\"\n\ndef Get_any(node):\n    if not node[0].num:\n        return \"any(\", \", \", \")\"\n\n    # unknown datatype\n    if node[0].dim == 0:\n        return \"%(0)s\"\n\n    return \"any(\", \", \", \")\"\n\ndef Get_all(node):\n\n    # unkonwn datatype\n    if not node[0].num:\n        return \"all(\", \", \", \")\"\n\n    # scalar value\n    if node[0].dim == 0:\n        return \"%(0)s\"\n\n    return \"all(\", \", \", \")\"\n\ndef Get_isequal(node):\n    return \"%(0)s == %(1)s\"\n\ndef Var_return(node):\n\n    # multi-return does not return a value\n    if node.func.backend == \"func_returns\":\n        return \"return\"\n    return \"return \" + str(node.func[0])\n\n\ndef Get_size(node):\n\n    # unknown input\n    if node[0].type == \"TYPE\" or node.parent.cls == \"Assigns\":\n        return \"size(\", \", \", \")\"\n\n    var = str(node[0])\n\n    # multiple args\n    if len(node) > 1:\n\n        # determine ax from second arg\n        arg2 = node[1].value\n        if arg2 == \"1\":\n            return var+\".n_rows\"\n        if arg2 == \"2\":\n            return var+\".n_cols\"\n        if arg2 == \"3\":\n            return var+\".n_slices\"\n\n    # colvec or rowvec\n    elif node[0].dim in (1,2):\n        #if node.parent.backend == \"reserved\" and\\\n        #  node.parent.name in (\"min\", \"max\"):\n        #    return var+\".n_elem\"\n\n        #if node[0].dim == 1:\n        #    return \"%(0)s.n_elem, 1\"\n        #elif node[0].dim == 2:\n        #    return \"1, %(0)s.n_elem\"\n        #return var+\".n_elem\"\n\n        if node.parent.cls == \"Get\":\n            if node.parent.backend in (\"reserved\", \"func_return\",\n                \"func_returns\", \"func_lambda\", \"unknown\"):\n                return \"%(0)s.n_rows, %(0)s.n_cols\"\n\n        # inline calls moved to own line\n        if node.parent.cls not in (\"Statement\", \"Assign\"):\n            return str(node.auxiliary())\n\n        return \"{%(0)s.n_rows, %(0)s.n_cols}\"\n\n    # matrix (returns two values)\n    elif node[0].dim == 3:\n\n        if node.parent.cls == \"Get\":\n            if node.parent.backend in (\"reserved\", \"func_return\",\n                    \"func_returns\", \"func_lambda\", \"unknown\"):\n                return \"%(0)s.n_rows, %(0)s.n_cols\"\n            return \"%(0)s.n_rows-1, %(0)s.n_cols\"\n\n        # inline calls moved to own line\n        if node.parent.cls not in (\"Statement\", \"Assign\"):\n            return str(node.auxiliary())\n\n        return \"{%(0)s.n_rows, %(0)s.n_cols}\"\n\n    # cube (return three values)\n    elif node[0].dim == 4:\n\n        if node.parent.cls == \"Get\":\n            if node.parent.backend in (\"reserved\", \"func_return\",\n                    \"func_returns\", \"func_lambda\", \"unknown\"):\n                return \"%(0)s.n_rows, %(0)s.n_cols, %(0)s.n_slices\"\n            return \"%(0)s.n_rows-1, %(0)s.n_cols-1, %(0)s.n_slices\"\n\n        # inline calls moved to own line\n        if node.parent.cls not in (\"Statement\", \"Assign\"):\n            return str(node.auxiliary())\n\n        return \"{%(0)s.n_rows, %(0)s.n_cols, %(0)s.n_slices}\"\n\n    return \"size(\", \", \", \")\"\n\ndef Assign_size(node):\n    num = node[-1][0].dim == 3 and \"2\" or \"2\"\n    if len(node[-1]) == 2 and (node[-1][1].str == \"1\" or node[-1][1].str == \"2\"):\n        return \"%(0)s = %(1)s ;\"\n    else:\n        return \"uword _%(0)s [] = %(1)s ;\\n\"+\\\n            \"%(0)s = urowvec(_%(0)s, \" + num + \", false) ;\"\n\ndef Assigns_size(node):\n\n    val = node[-1][0]\n    # multi-assigned size to own line\n    if val.cls != \"Var\":\n        val = val.auxiliary()\n    val = str(val)\n\n    # suggest some types for matrix\n\n    out = \"\"\n\n    if node[0].str != '~':\n        out += \"%(0)s = \" + val + \".n_rows;\\n\"\n    if node[1].str != '~':\n        out += \"%(1)s = \" + val + \".n_cols;\\n\"\n    if len(node) == 4 and node[2] != '~':\n        out += \"%(2)s = \" + val + \".n_slices;\\n\"\n    #if len(node)==3:\n    #    return \n    #    return \"%(0)s = \" +val+ \".n_rows ;\\n%(1)s = \" +val+ \".n_cols ;\"\n\n    if not (len(node) == 3 or len(node) == 4):\n        raise NotImplementedError\n\n    return out\n\n\n    # suggest some types for cube\n    #if len(node)==4:\n\n    #    return  \"%(0)s = \"+val+\".n_rows ;\\n\"+\\\n    #            \"%(1)s = \"+val+\".n_cols ;\\n\"+\\\n    #            \"%(2)s = \"+val+\".n_slices ;\"\n\n\n\ndef Get_chol(node):\n    return \"\", \", \", \"\"\n\n\ndef Assign_chol(node):\n    lhs, rhs = node\n    my_list = []\n    for n in rhs:\n        my_list.append(n.str)\n    my_string = \", \".join(my_list)\n\n    return \"%(0)s = chol(\" + my_string + \") ;\"\n\ndef Assigns_chol(node):\n    lhs = node[:-1]\n    rhs = node[-1]\n\n    if len(lhs) == 2:\n        rhs_string = lhs[0].str + \", \" + rhs.str\n        # flip p bool value, to get same value as matlab\n        ret_bool = lhs[1].str + \" = !\" + lhs[1].str + \" ;\"\n        return lhs[1].str + \" = chol(\" + rhs_string + \") ;\\n\" + ret_bool\n\n    # Default out. If more lhs values, then write new if statement\n    lhs_list = [n.str for n in lhs]\n    rhs_list = [n.str for n in rhs]\n    lhs_string = \", \".join(lhs_list)\n    rhs_string = \", \".join(rhs_list)\n    return \"[\" + lhs_string + \"]\" + \" = chol(\" + rhs_string + \") ;\"\n\n\ndef Get_unique(node):\n    node.include(\"m2cpp\")\n    return \"\", \", \", \"\"\n\ndef Assign_unique(node):\n    node.include(\"m2cpp\")\n    args = \", \".join([n.str for n in node])\n    return \"m2cpp::unique(\" + args + \");\"\n\ndef Assigns_unique(node):\n    node.include(\"m2cpp\")\n    args = \", \".join([n.str for n in node])\n    return \"m2cpp::unique(\" + args + \");\"\n\ndef Get_sortrows(node):\n    node.include(\"m2cpp\")\n    args = \", \".join([n.str for n in node])\n    return \"m2cpp::sortrows(\" + args + \");\"\n\ndef Get_intersect(node):\n    node.include(\"m2cpp\")\n    return \"\", \", \", \"\"\n\n\ndef Assign_intersect(node):\n    node.include(\"m2cpp\")\n    lhs, rhs = node\n    my_list = []\n    for n in rhs:\n        my_list.append(n.str)\n    my_string = \", \".join(my_list)\n\n    return \"%(0)s = m2cpp::intersect(\" + my_string + \") ;\"\n\ndef Assigns_intersect(node):\n    node.include(\"m2cpp\")\n    rhs = \", \".join([n.str for n in node])\n    return \"m2cpp::intersect(\" + rhs + \");\"\n\ndef Get_length(node):\n    # array-type uses n_elem\n    if node.cls == \"Var\":\n        return \"%(0)s.n_elem\"\n\n    node.include(\"m2cpp\")\n    return \"m2cpp::length(%(0)s)\"\n\ndef Get_isempty(node):\n    node.include(\"m2cpp\")\n    return \"m2cpp::isempty(%(0)s)\"\n\ndef Get_min(node):\n\n    # non.numerical input\n    if not all([n.num for n in node]):\n        return \"min(\", \", \", \")\"\n\n    # everything scalar\n    if all([(n.dim < 1) for n in node]):\n\n        if any([n.mem == 4 for n in node]):\n            node.include(\"m2cpp\")\n            nodes = map(str, node)\n            nodes = [\"m2cpp::smat<cx_double>(\" + name + \")\" for name in nodes]\n            arg = \", \".join(nodes)\n            return \"arma::min(\" + arg + \")\"\n\n        node.include(\"algorithm\")\n        return \"std::min(\", \", \", \")\"\n\n    # single arg\n    if len(node) == 1:\n        return \"arma::min(%(0)s)\"\n\n    # two args\n    if len(node) == 2:\n        if node[0].dim and node[1].dim:\n            return \"arma::min(%(0)s, %(1)s)\"\n\n        if node[0].dim==0:\n            return \"arma::clamp(%(1)s, %(1)s.min(), %(0)s)\"\n\n        if node[1].dim==0:\n            return \"arma::clamp(%(0)s, %(0)s.min(), %(1)s)\"\n\n\n    # three args\n    if len(node) == 3:\n        if node[2].dim == 0:\n\n            # assues third arg is int and sets axis\n            val = node[2].value\n            if val == \"1\":\n                return \"arma::min(%(0)s, 1)\"\n            elif val == \"2\":\n                return \"arma::min(%(0)s, 0)\"\n\n            return \"arma::min(%(0)s, %(2)s-1)\"\n\n    assert False\n\ndef Assigns_min(node):\n    assert len(node) == 3\n\n    var = node[2][0]\n\n    # non-numerical assignment\n    if not var.num:\n        return \"[\", \", \", \"] = min(\", \") ;\"\n\n    # multi-assignmens on own line\n    if var.cls != \"Var\":\n        var = var.auxiliary()\n    var = str(var)\n    if node[0].str != '~':\n        return \"%(0)s = \" + var + \".min(%(1)s) ;\"\n    else:\n        return var + \".min(%(1)s);\"\n\ndef Get_max(node):\n\n    # non.numerical input\n    if not all([n.num for n in node]):\n        return \"max(\", \", \", \")\"\n\n    # everything scalar\n    if all([(n.dim<1) for n in node]):\n\n        if any([n.mem == 4 for n in node]):\n            node.include(\"m2cpp\")\n            nodes = map(str, node)\n            nodes = [\"m2cpp::smat<cx_double>(\" + name + \")\" for name in nodes]\n            arg = \", \".join(nodes)\n            return \"arma::max(\" + arg + \")\"\n\n        # single element, uword (returned from size(a))\n        #if len(node) == 1 and node[0].dim == 0:\n        #    return \"%(0)s\"\n\n        node.include(\"algorithm\")\n        return \"std::max(\", \", \", \")\"\n\n    # number of args is ...\n    if len(node) == 1:\n        return \"arma::max(%(0)s)\"\n\n    if len(node) == 2:\n        if node[0].dim and node[1].dim:\n            return \"arma::max(%(0)s, %(1)s)\"\n\n        if node[0].dim==0:\n            return \"arma::clamp(%(1)s, %(0)s, %(1)s.max())\"\n\n        if node[1].dim==0:\n            return \"arma::clamp(%(0)s, %(1)s, %(0)s.max())\"\n\n    if len(node) == 3:\n        if node[2].dim == 0:\n\n            # thrid argument sets axis to take max over\n            val = node[2][\"value\"]\n            if val == \"1\":\n                return \"arma::max(%(0)s, 1)\"\n            elif val == \"2\":\n                return \"arma::max(%(0)s, 0)\"\n\n            return \"arma::max(%(0)s, %(2)s-1)\"\n\n    assert False\n\ndef Assigns_max(node):\n    assert len(node) == 3\n\n    # right hand side of assignment\n    var = node[-1]\n\n    # non-numerical input\n    if not var.num:\n        return \"[\", \", \", \"] = max(\", \") ;\"\n\n    # multi-assign max on own line\n    if var.cls != \"Var\":\n        var = var.auxiliary()\n    var = str(var)\n\n    if node[0].str != '~':\n        return \"%(0)s = \" + var + \".max(%(1)s);\"\n    else:\n        var + \".max(%(1)s);\"\n\nVar_eye = \"1\"\n\ndef Get_eye(node):\n\n    # not numerical input\n    if not node[0].num:\n        return \"eye(\", \", \", \")\"\n\n    # single argument constructor\n    if len(node) == 1:\n        if node[0].dim == 0:\n            return \"arma::eye<%(type)s>(%(0)s, %(0)s)\"\n        return \"arma::eye<%(type)s>(%(0)s(0), %(0)s(1))\"\n\n    # double arguments\n    if len(node) == 2:\n        return \"arma::eye<%(type)s>(%(0)s, %(1)s)\"\n\n    raise NotImplementedError\n\ndef Get_trace(node):\n    return \"arma::trace(\", \", \", \")\"\n\ndef Get_transpose(node):\n    \"\"\"Simple transpose\n    \"\"\"\n\n    return \"arma::strans(%(0)s)\"\n\ndef Get_ctranspose(node):\n    \"\"\"Complex transpose\n    \"\"\"\n\n    return \"arma::trans(%(0)s)\"\n\ndef Get_fliplr(node):\n    return \"arma::fliplr(%(0)s)\"\n\ndef Get_flipud(node):\n    return \"arma::flipud(%(0)s)\"\n\n\ndef Get_ones(node):\n\n    # one argument\n    if len(node) == 1:\n        #size as argument: zeros(size(A))\n        if node[0].backend == \"reserved\" and node[0].name == \"size\":\n            #Take the type of the LHS, normally it is the other way around\n            if node.parent.cls == \"Assign\" and node.parent[0] != node:\n                out = \"arma::ones<\" + node.parent[0].type + \">(\"\n                return out, \", \", \")\"\n            #return \"arma::ones<%(type)s>(\", \", \", \")\"\n\n        #arg input is a scalar\n        if node[0].num and node[0].dim == 0:\n            #dim is matrix\n            if node.dim == 3:\n                return \"arma::ones<%(type)s>(%(0)s, %(0)s)\"\n\n        # arg input is vector\n        if node[0].num and node[0].dim in (1,2):\n\n            # non-trivial variables moved out to own line\n            if node[0].cls != \"Var\":\n                node[0].auxiliary()\n\n            # indexing arg as input\n            if node.dim in (1,2):\n                return \"arma::ones<%(type)s>(%(0)s(0))\"\n            if node.dim == 3:\n                return \"arma::ones<%(type)s>(%(0)s(0), %(0)s(1))\"\n            if node.dim == 4:\n                return \"arma::ones<%(type)s>(%(0)s(0), %(0)s(1), %(0)s(2))\"\n\n    # two args where one vector and other \"1\" handled specially\n    elif len(node) == 2:\n\n        if node.dim == 3:\n            return \"arma::ones<%(type)s>(%(0)s, %(1)s)\"\n\n        if node.dim in (1,2):\n            if node[0].cls == \"Int\" and node[0].value == \"1\":\n                return \"arma::ones<%(type)s>(%(1)s)\"\n            if node[1].cls == \"Int\" and node[1].value == \"1\":\n                return \"arma::ones<%(type)s>(%(0)s)\"\n\n    return \"arma::ones<%(type)s>(\", \", \", \")\"\n\n\ndef Get_zeros(node):\n\n    # one argument\n    if len(node) == 1:\n\n        #size as argument: zeros(size(A))\n        if node[0].backend == \"reserved\" and node[0].name == \"size\":\n            #Take the type of the LHS, normally it is the other way around\n            if node.parent.cls == \"Assign\" and node.parent[0] != node:\n                out = \"arma::zeros<\" + node.parent[0].type + \">(\"\n                return out, \", \", \")\"\n            #return \"arma::zeros<%(type)s>(\", \", \", \")\"\n\n        #arg input is a scalar\n        if node[0].num and node[0].dim == 0:\n            #dim is matrix\n            if node.dim == 3:\n                return \"arma::zeros<%(type)s>(%(0)s, %(0)s)\"\n\n        # arg input is vector\n        if node[0].num and node[0].dim in (1,2):\n\n            # non-trivial variables moved out to own line\n            if node[0].cls != \"Var\":\n                node[0].auxiliary()\n\n            # indexing arg as input if vector\n            if node.dim in (1,2):\n                return \"arma::zeros<%(type)s>(%(0)s(0))\"\n            if node.dim == 3:\n                return \"arma::zeros<%(type)s>(%(0)s(0), %(0)s(1))\"\n            if node.dim == 4:\n                return \"arma::zeros<%(type)s>(%(0)s(0), %(0)s(1), %(0)s(2))\"\n\n    # double argument creates colvec/rowvec/matrix depending on context\n    elif len(node) == 2:\n\n        if node.dim == 3:\n            return \"arma::zeros<%(type)s>(%(0)s, %(1)s)\"\n\n        if node.dim in (1,2):\n            # use colvec if first index is '1'\n            if node[0].cls == \"Int\" and node[0].value == \"1\":\n                return \"arma::zeros<%(type)s>(%(1)s)\"\n\n            # use rowvec if second index is '1'\n            elif node[1].cls == \"Int\" and node[1].value == \"1\":\n                return \"arma::zeros<%(type)s>(%(0)s)\"\n\n    return \"arma::zeros<%(type)s>(\", \", \", \")\"\n\ndef Get_qr(node):\n    return \"\", \", \", \"\"\n\ndef Assign_qr(node):\n    return \"arma::qr(\", \", \", \")\"\n\ndef Assigns_qr(node):\n    return \"arma::qr(\", \", \", \")\"\n\ndef Var_rand(node):\n    return \"arma::randu<\" + node.type + \">(1)\"\n\n\ndef Get_rand(node):\n    return \"arma::randu<\" + node.type + \">(\", \", \", \")\"\n\ndef Var_clear(node):\n    #index = node.parent.children.index(node)\n    #print(node.parent.parent.names)\n    #del node.parent.parent.children[0]\n    #print(node.parent.summary())\n    #return \"\"\n    return \"// clear\"\n\ndef Get_clear(node):\n    return \"// clear(\", \", \", \")\"\n\ndef Var_close(node):\n    return \"// close\"\n\ndef Get_close(node):\n    return \"// close(\", \", \", \")\"\n\ndef Var_clc(node):\n    return \"// clc\"\n\ndef Get_clc(node):\n    return \"// clc\"\n\ndef Var_clf(node):\n    return \"// clf\"\n\ndef Get_clf(node):\n    return \"// clf\"\n\ndef Var_more(node):\n    return \"// more\"\n\ndef Get_more(node):\n    return \"// more\"\n\ndef Var_format(node):\n    return \"// format\"\n\ndef Get_format(node):\n    return \"// format\"\n\ndef Get__conv_to(node):\n    return \"conv_to<%(type)s>::from(%(0)s)\"\n\ndef Get__reshape(node):\n    return \"%(value)s(\", \", \", \")\"\n\ndef Get_reshape(node):\n    return \"reshape(\", \", \", \")\"\n\ndef Get_nextpow2(node):\n    node.include(\"m2cpp\")\n    return \"m2cpp::nextpow2(\", \", \", \")\"\n\n\ndef Assign_fft(node):\n\n    if node[0].mem == 3:\n        return \"%(0)s = arma::conv_to<\" + node[0].type + \">::from(%(1)s) ;\"\n\n    return \"%(0)s = %(1)s ;\"\n\ndef Assign_ifft(node):\n    return Assign_fft(node)\n\ndef Get_fft(node):\n\n    if node[0].mem != None:\n        node.type = node[0].type\n\n    # arma & matlab fft same for n_args in (1,2)\n    if len(node) in (1, 2):\n        return \"arma::fft(\", \", \", \")\"\n\n    elif len(node) == 3:\n\n        if node[0].dim in (1,2):\n            return \"arma::fft(%(0)s, %(1)s)\"\n\n        if node[1].cls == \"Matrix\":\n            node.include(\"m2cpp\")\n            return \"m2cpp::fft<\" + node[0].type + \">(%(0)s, %(2)s)\"\n        else:\n            node.include(\"m2cpp\")\n            return \"m2cpp::fft<\" + node[0].type + \">(\", \", \", \")\"\n\n    else:\n        node.error(\"Number of args in 'fft' should be between 1 and 3\")\n\n\n\n    return \"arma::fft(\", \", \", \")\"\n\ndef Get_ifft(node):\n\n    if node[0].mem != None:\n        node.type = node[0].type\n\n    # unknown input\n    if not node.num:\n        return \"arma::ifft(\", \", \", \")\"\n\n    if len(node) == 1:\n        return \"arma::ifft<%(type)s>(%(0)s)\"\n\n\n    elif len(node) == 2:\n        return \"arma::ifft<%(type)s>(%(0)s, %(1)s)\"\n\n\n    elif len(node) == 3:\n\n        if node[0].dim in (1, 2):\n            return \"arma::ifft<%(type)s>(%(0)s, %(1)s)\"\n\n        if node[1].cls == \"Matrix\":\n            node.include(\"m2cpp\")\n            return \"m2cpp::ifft<%(type)s>(%(0)s, %(2)s)\"\n        else:\n            node.include(\"m2cpp\")\n            return \"m2cpp::ifft<%(type)s>(\", \", \", \")\"\n\n    else:\n        node.error(\"Number of args in 'ifft' should be between 1 and 3\")\n\n    if node[0].mem != 4:\n        node.warning(\"Argument datatype of 'ifft' should be complex\")\n\n    return \"arma::ifft(\", \", \", \")\"\n\ndef Get_fft2(node):\n\n    if node[0].mem != None:\n        node.type = node[0].type\n\n    return \"arma::fft2(\", \", \", \")\"\n\ndef Get_ifft2(node):\n\n    if node[0].mem != None:\n        node.type = node[0].type\n\n    return \"arma::ifft2(\", \", \", \")\"\n\ndef Assign_fft2(node):\n    return Assign_fft(node)\n\ndef Assign_ifft2(node):\n    return Assign_fft(node)\n\n\ndef Get_hankel(node):\n    node.include(\"m2cpp\")\n    return \"m2cpp::hankel(\", \", \", \")\"\n\ndef Get_interp1(node):\n\n    if node.parent.cls == \"Assign\":\n        out = \"arma::interp1(%(0)s, %(1)s, %(2)s, \" + node.parent[0].str\n\n        if node[-1].type == \"string\":\n            out = out + \", %(3)s)\"\n        else:\n            out = out + \")\"\n    else:\n        out = \"arma::interp1(\", \", \", \")\"\n\n    return out\n\ndef Assign_interp1(node):\n    return \"%(1)s ;\"\n\ndef Get_linspace(node):\n    return \"arma::linspace<%(type)s>(\", \", \", \")\"\n\n\ndef Get_sum(node):\n    \"\"\"\n    Summation function.\n\n    Examples:\n        >>> print(matlab2cpp.qscript(\"a=[1,2]; b = sum(a)\", suggest=True))\n        sword _a [] = {1, 2} ;\n        a = irowvec(_a, 2, false) ;\n        b = int(arma::as_scalar(arma::sum(a))) ;\n        >>> print(matlab2cpp.qscript(\"a=[1.5;2]; b = sum(a)\", suggest=True))\n        double _a [] = {1.5, 2} ;\n        a = vec(_a, 2, false) ;\n        b = double(arma::as_scalar(arma::sum(a))) ;\n        >>> print(matlab2cpp.qscript(\"a=[-1,2;3,4]; b = sum(a, 1)\", suggest=True))\n        sword _a [] = {-1, 2, 3, 4} ;\n        a = arma::strans(imat(_a, 2, 2, false)) ;\n        b = arma::sum(arma:vectorize(a), 0) ;\n        >>> print(matlab2cpp.qscript(\"a=[1., 2.; 3., 4.]; b = sum(a(:))\", suggest=True))\n        double _a [] = {1., 2., 3., 4.} ;\n        a = arma::strans(mat(_a, 2, 2, false)) ;\n        b = double(arma::as_scalar(arma::sum(arma:vectorize(a(span(0, a.n_rows-1)))))) ;\n        >>> print(matlab2cpp.qscript(\"a=rand(9, 9, 9); b = sum(a(:))\", suggest=True))\n        a = arma::randu<cube>(9, 9, 9) ;\n        b = double(arma::as_scalar(arma::sum(arma:vectorize(a(span(0, a.n_rows-1)))))) ;\n    \"\"\"\n    arg = node[0]\n    # unknown input\n    if not arg.num or arg.dim == 0:\n        node.error(\"sum over non-array\")\n        return \"arma::sum(\", \", \", \")\"\n\n    if arg.dim > 2:\n        arg = \"arma:vectorize(%(0)s)\"\n    else:\n        arg = \"%(0)s\"\n\n    # second argument should be dim, matlab uses dim 1/2, and armadillo 0/1\n    if len(node) == 1:\n        node.dim = 0\n        out = \"%(type)s(arma::as_scalar(arma::sum(\" + arg + \")))\"\n\n    elif len(node) == 2:\n        out = \"arma::sum(\" + arg + \", %(1)s-1)\"\n\n    else:\n        out = \"arma::sum(\", \", \", \")\"\n    return out\n\ndef Get_cumsum(node):\n    if len(node) < 2:\n        return \"cumsum(\", \", \", \")\"\n    elif len(node) == 2:\n        return \"cumsum(%(0)s, %(1)s-1)\"\n    else:\n        return \"cumsum(\", \", \", \")\"\n\ndef Get_conj(node):\n    if node.dim == 0:\n        if node.mem == 4:\n            node.include(\"complex\")\n            return \"std::conj(\", \", \", \")\"\n        else:\n            return \"%(0)s\"\n\n    return \"arma::conj(\", \", \", \")\"\n\ndef Get_imag(node):\n    return \"arma::imag(\", \", \", \")\"\n\ndef Get_real(node):\n    # output always real\n    return \"arma::real(\", \", \", \")\"\n\ndef Var_tic(node):\n    return Get_tic(node)\n\ndef Get_tic(node):\n    node.wall_clock()\n    node.type = 'double'\n    return \"m2cpp::tic()\"\n\ndef Assign_tic(node):\n    node.wall_clock()\n    node[0].type = 'double'\n    return \"%(0)s = m2cpp::tic();\"\n\ndef Var_toc(node):\n    return Get_toc(node)\n\ndef Get_toc(node):\n    node.wall_clock()\n\n    arg = \", \".join([n.str for n in node])\n\n    if node.parent.cls != \"Statement\":\n        return \"m2cpp::toc(\" + arg + \")\"\n\n    node.include(\"iostream\")\n    return 'std::cout << \"Elapsed time = \" << m2cpp::toc(' + arg + ') << std::endl'\n\ndef Get_diag(node):\n    if node.dim == 3:\n        return \"diagmat(\", \", \", \")\"\n    return \"diagvec(\", \", \", \")\"\n\ndef Get_tril(node):\n    return \"trimatl(\", \", \", \")\"\n\ndef Get_triu(node):\n    return \"trimatu(\", \", \", \")\"\n\ndef Var_disp(node):\n    return \"// disp\"\n\ndef Get_disp(node):\n    node.include(\"iostream\")\n\n    if len(node) == 1:\n        arg = node[0]\n        if not arg.num or arg.dim == 0:\n            return \"std::cout << %(0)s << std::endl\"\n        else:\n            return \"%(0)s.print()\"\n    else:\n        node.error(\"disp should take one argument\")\n    return \"std::cout << \", \"<< \", \" << std::endl\"\n\ndef Get_fprintf(node):\n    \"\"\" Matlab's fprintf can write to file and screen... this is translated to printf (so only printing to screen)\n    will give error if trying to write to file.\n    \"\"\"\n    node.include(\"cstdio\")\n    return \"std::printf(\", \", \", \")\"\n\n\ndef Get_error(node):\n    node.include(\"iostream\")\n\n    return \"std::cerr << \", \"<< \", \" << std::endl\"\n\ndef Get_convmtx(node):\n    node.include(\"m2cpp\")\n    return \"m2cpp::convmtx(\", \", \", \")\"\n\ndef Get_conv2(node):\n    node.include(\"m2cpp\")\n    return \"m2cpp::conv2<%(type)s>(\", \", \", \")\"\n    #return \"m2cpp::conv2<\" + node[0].type + \",\" + node[1].type + \">(\", \", \", \")\"\n\n#SPlot reserved words\ndef Get_figure(node):\n    node.plotting()\n    return \"_plot.figure(\", \", \", \")\"\n\ndef Var_hold(node):\n    return Get_hold(node)\n\ndef Get_hold(node):\n    node.plotting()\n    if node and node[0].cls == \"String\":\n\n        if node[0].value == \"on\":\n            return \"_plot.hold(1)\"\n\n        if node[0].value == \"off\":\n            return \"_plot.hold(0)\"\n\n        node.error('argument must either be \"on\" or \"off\"')\n\n        return \"_plot.hold(\", \", \", \")\"\n\n    node.error(\"hold toggle not supported\")\n    return \"_plot.hold(\", \", \", \")\"\n\ndef Var_load(node):\n    return Get_load(node)\n\ndef Get_load(node):\n\n    out = \"load \" + node.code\n    if len(node) == 1:\n        if node[0].cls == \"String\":\n            name = str(node[0].value).split(\".\")[0]\n            out = name + \".load(%(0)s)\"\n        else:\n            out = \"%(0)s.load(\\\"\" + node.value + \"\\\")\"\n\n    return out\n\ndef Var_clf(node):\n    return Get_clf(node)\n\ndef Get_clf(node):\n    node.plotting()\n    return \"_plot.clf(\", \", \", \")\"\n\ndef Var_cla(node):\n    return Get_cla(node)\n\ndef Get_cla(node):\n    node.plotting()\n    return \"_plot.cla(\", \", \", \")\"\n\ndef Get_show(node):\n    node.plotting()\n    return \"_plot.show(\", \", \", \")\"\n\ndef Get_xlabel(node):\n    node.plotting()\n    return \"_plot.xlabel(\", \", \", \")\"\n\ndef Get_ylabel(node):\n    node.plotting()\n    return \"_plot.ylabel(\", \", \", \")\"\n\ndef Get_title(node):\n    node.plotting()\n    return \"_plot.title(\", \", \", \")\"\n\ndef Get_plot(node):\n    node.plotting()\n\n    if len(node) > 2:\n        state = True\n\n        num_children = len(node)\n        cur_child = 0\n\n        out = \"\"\n        while state:\n            #if cur_child > 0 and cur_child < num_children:\n            #    out += \"\\n\"\n            #elif cur_child >= num_children:\n            #    break\n\n            out += \"_plot.plot(\"\n\n            #add next two childen\n            if (cur_child+2) <= num_children:\n                out += \"%(\" + str(cur_child) + \")s, \"\n                cur_child += 1\n                out += \"%(\" + str(cur_child) + \")s\"\n                cur_child += 1\n\n            #test if linespec\n            if cur_child < num_children and node[cur_child].type == \"string\":\n                out += \", %(\" + str(cur_child) + \")s\"\n                cur_child += 1\n            elif cur_child < num_children and node[cur_child].type != \"string\":\n                out += \"\"\n            elif cur_child >= num_children:\n                out += \"\"\n\n            #add next two children\n            if (cur_child+2) <= num_children:\n                out += \", %(\" + str(cur_child) + \")s, \"\n                cur_child += 1\n                out += \"%(\" + str(cur_child) + \")s\"\n                cur_child += 1\n\n            #test if linespec\n            if cur_child < num_children and node[cur_child].type == \"string\":\n                out += \", %(\" + str(cur_child) + \")s\"\n                cur_child += 1\n            elif cur_child < num_children and node[cur_child].type != \"string\":\n                out += \"\"\n            elif cur_child >= num_children:\n                out += \"\"\n\n\n            if (cur_child+1) <= num_children:\n                out += \") ;\\n\"\n            else:\n                out += \")\"\n                state = False\n\n        return out\n\n    return \"_plot.plot(\", \", \", \")\"\n\ndef Get_imshow(node):\n    node.plotting()\n    return \"_plot.imshow(\", \", \", \")\"\n\ndef Get_imagesc(node):\n    node.plotting()\n    return \"_plot.imagesc(\", \", \", \")\"\n\ndef Get_wigb(node):\n    node.plotting()\n    return \"_plot.wigb(\", \", \", \")\"\n\ndef Var_colorbar(node):\n    return Get_colorbar(node)\n\ndef Get_colorbar(node):\n    node.plotting()\n    return \"_plot.colorbar(\", \", \", \")\"\n\ndef Get_xlim(node):\n    \"\"\"\nExamples:\n    >>> print(matlab2cpp.qscript(\"xlim(0.0, 3.14)\"))\n    _plot.xlim(0.0, 3.14) ;\n    _plot.show() ;\n    >>> print(matlab2cpp.qscript(\"xlim([0.0, 3.14])\"))\n    _plot.xlim(0.0, 3.14) ;\n    _plot.show() ;\n    \"\"\"\n\n    node.plotting()\n\n    if len(node) == 1:\n        arg = node[0]\n\n        if arg.cls == \"Matrix\" and len(arg[0]) == 2:\n\n            a,b = arg[0]\n            return \"_plot.xlim(\" + str(a) + \", \" + str(b) + \")\"\n\n        elif arg.cls != \"Matrix\" and arg.num and arg.dim>0:\n\n            name1 = arg.name + \"(0)\"\n            name2 = arg.name + \"(1)\"\n            if arg.mem not in (2,3):\n                name1 = \"static_cast<double>(\" + name1 + \")\"\n                name2 = \"static_cast<double>(\" + name2 + \")\"\n\n            return \"_plot.xlim(\" + name1 + \", \" + name2 + \")\"\n\n    node.error(\"argument array type\")\n    return \"_plot.xlim(\", \", \", \")\"\n\ndef Get_ylim(node):\n    \"\"\"\nExamples:\n    >>> print(matlab2cpp.qscript(\"ylim(0.5,.7)\"))\n    _plot.ylim(0.5, 0.7) ;\n    _plot.show() ;\n    >>> print(matlab2cpp.qscript(\"ylim([0.5,.7])\"))\n    _plot.ylim(0.5, 0.7) ;\n    _plot.show() ;\n    \"\"\"\n\n    node.plotting()\n\n    if len(node) == 1:\n        arg = node[0]\n\n        if arg.cls == \"Matrix\" and len(arg[0]) == 2:\n                a,b = arg[0]\n                return \"_plot.ylim(\" + str(a) + \", \" + str(b) + \")\"\n\n        elif arg.cls != \"Matrix\" and arg.num and arg.dim>0:\n\n            name1 = arg.name + \"(0)\"\n            name2 = arg.name + \"(1)\"\n            if arg.mem not in (2,3):\n                name1 = \"static_cast<double>(\" + name1 + \")\"\n                name2 = \"static_cast<double>(\" + name2 + \")\"\n\n            return \"_plot.ylim(\" + name1 + \", \" + name2 + \")\"\n\n    node.error(\"argument array type\")\n    return \"_plot.ylim(\", \", \", \")\"\n\ndef Get_caxis(node):\n    \"\"\"\n    >>> print(matlab2cpp.qscript(\"caxis(0, 3)\"))\n    _plot.caxis(0, 3) ;\n    _plot.show() ;\n    >>> print(matlab2cpp.qscript(\"caxis([0, 3])\"))\n    _plot.caxis(0, 3) ;\n    _plot.show() ;\n    \"\"\"\n\n    node.plotting()\n\n    if len(node) == 1:\n        arg = node[0]\n\n        if arg.cls == \"Matrix\" and len(arg[0]) == 2:\n                a,b = arg[0]\n                return \"_plot.caxis(\" + str(a) + \", \" + str(b) + \")\"\n\n        elif arg.cls != \"Matrix\" and arg.num and arg.dim>0:\n\n            name1 = arg.name + \"(0)\"\n            name2 = arg.name + \"(1)\"\n            if arg.mem not in (2,3):\n                name1 = \"static_cast<double>(\" + name1 + \")\"\n                name2 = \"static_cast<double>(\" + name2 + \")\"\n\n            return \"_plot.caxis(\" + name1 + \", \" + name2 + \")\"\n\n    node.error(\"argument array type\")\n    return \"_plot.caxis(\", \", \", \")\"\n\ndef Get_axis(node):\n    \"\"\"\n    >>> print(matlab2cpp.qscript(\"axis(0, 3, -2, 4)\"))\n    _plot.axis(0, 3, -2, 4) ;\n    _plot.show() ;\n    >>> print(matlab2cpp.qscript(\"axis([0, 3, -2, 4])\"))\n    _plot.axis(0, 3, -2, 4) ;\n    _plot.show() ;\n    \"\"\"\n\n    node.plotting()\n\n    if len(node) == 1:\n        arg = node[0]\n\n        if arg.cls == \"Matrix\" and len(arg[0]) == 4:\n                a,b,c,d = arg[0]\n                return \"_plot.axis(\" + str(a) + \", \" + str(b) + \", \" + str(c) + \", \" + str(d) + \")\"\n\n        elif arg.cls != \"Matrix\" and arg.num and arg.dim>0:\n\n            name1 = arg.name + \"(0)\";\n            name2 = arg.name + \"(1)\"\n            name3 = arg.name + \"(2)\";\n            name4 = arg.name + \"(3)\"\n            if arg.mem not in (2,3):\n                name1 = \"static_cast<double>(\" + name1 + \")\"\n                name2 = \"static_cast<double>(\" + name2 + \")\"\n                name3 = \"static_cast<double>(\" + name3 + \")\"\n                name4 = \"static_cast<double>(\" + name4 + \")\"\n\n            return \"_plot.axis(\" + name1 + \", \" + name2 + \", \" + name3 + \", \" + name4 + \")\"\n\n    node.error(\"argument array type\")\n    return \"_plot.axis(\", \", \", \")\"\n\ndef Var_grid(node):\n    return Get_grid(node)\n\ndef Get_grid(node):\n    node.plotting()\n\n    if node and node[0].cls == \"String\":\n\n        if node[0].value == \"on\":\n            return \"_plot.grid({{\\\"b\\\", \\\"on\\\"}})\"\n\n        if node[0].value == \"off\":\n            return \"_plot.grid({{\\\"b\\\", \\\"off\\\"}})\"\n\n        node.error('argument must either be \"on\" or \"off\"')\n\n        return \"_plot.grid(\", \", \", \")\"\n\n    return \"_plot.grid(\", \", \", \")\"\n\ndef Get_subplot(node):\n    node.plotting()\n    return \"_plot.subplot(\", \", \", \")\"\n\ndef Get_colormap(node):\n    node.plotting()\n\n    if len(node) == 1:\n        arg = node[0]\n\n        if len(arg) == 0:\n            name = str(arg)[:-2] + \"(1)\"\n            return \"_plot.colormap(\" + name + \")\"\n\n    return \"_plot.colormap(\", \", \", \")\"\n\ndef Get__splot(node):\n    return \"_plot.show()\"\n\ndef Get_logspace(node):\n    if len(node) == 2:\n        return \"logspace<%(type)s>(%(0)s, %(1)s, 50)\"\n\n    if len(node) == 3:\n        return \"logspace<%(type)s>(%(0)s, %(1)s, %(2)s)\"\n\n    return \"logspace<%(type)s>(\", \", \", \")\"\n\ndef Get_find(node):\n    return \"find(\", \", \", \") + 1\"\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/rules/_rowvec.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .rowvec import Get, Set\n\nDeclare = \"rowvec %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_size_t.py",
    "content": "from .assign import Assign\nfrom .variables import *\n\nSize_t = \"%(value)s\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_string.py",
    "content": "from .assign import Assign\nfrom .variables import *\n\nDeclare = \"string %(name)s ;\"\n\ndef String(node):\n    if node.name or node.parent.backend != \"matrix\":\n        return '\"%(value)s\"'\n    else:\n        return 'std::string(\"%(value)s\")'\n        \n"
  },
  {
    "path": "src/matlab2cpp/rules/_struct.py",
    "content": "from .assign import Assign\nfrom .variables import *\n\n#def Fvar(node): #defined in variables.py\n#    return \"%(name)s.%(value)s\"\n\nDeclare = \"struct %(name)s\"\n\ndef Matrix(node):\n    return \"\", \", \", \"\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_structs.py",
    "content": "#from assign import Assign\nfrom .variables import *\nimport matlab2cpp\n\nDeclare = \"struct %(name)s\"\n\ndef Counter(node):\n    return \"%(name)s = %(value)s\"\n\n#def Fvar(node): #defined in variables.py\n#    return \"%(name)s.%(value)s\"\n    \ndef Fget(node):\n    pass\n\ndef Fset(node):\n    return \"%(name)s.%(value)s[\", \", \", \"-1]\"\n\ndef Matrix(node):\n    if node.backend == \"structs\":\n        if node[0].cls == \"Vector\":\n            if len(node[0]) == 1:\n                return \"%(0)s\"\n    return \"[\", \", \", \"]\"\n\n\"\"\"def Assign(node):\n    lhs, rhs = node\n    print('here')\n    # assign a my_var = [a.val], a is a structs, my_var should be a vec\n    if node[1].cls == \"Matrix\" and node[1].backend == \"structs\":\n        element = rhs[0][0]\n        if element.backend == \"structs\":\n            size = rhs.str\n            var = lhs.name\n            name = element.name\n            value = element.value\n\n            declares = node.func[0]\n            if \"_i\" not in declares:\n                declare = matlab2cpp.collection.Var(declares, \"_i\")\n                declare.type = \"int\"\n                declare.backend = \"int\"\n                declares.translate()\n            \n            string = var + \".resize(\" + size + \") ;\\n\" +\\\n                \"for (_i=0; _i<\" + size + \"; ++_i)\\n  \"+\\\n                var + \"[_i] = \" + name + \"[_i].\" + value + \" ;\"\n\n            return string\n\n    return \"%(0)s = %(1)s\"\"\"\"\"\n\n"
  },
  {
    "path": "src/matlab2cpp/rules/_ucube.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .cube import Get, Set, Resize\n\nDeclare = \"ucube = %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_umat.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .mat import Get, Set\n\nDeclare = \"umat %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_unknown.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom . import armadillo as arma\n\nDeclare = \"TYPE %(name)s ;\"\n\ndef Assigns(node):\n    lhs = map(str, node[:-1])\n    lhs = \"[\" + \", \".join(lhs) + \"]\"\n    rhs = str(node[-1])\n    return lhs + \" = \" + rhs + \" ;\"\n\ndef Matrix(node):\n    return \"\", \", \", \"\"\n\ndef Get(node):\n\n    if len(node) == 2:\n        arg0, dim0 = arma.configure_arg(node[0], 0)\n        arg1, dim1 = arma.configure_arg(node[1], 1)\n\n        # All + All\n        if node[0].cls == node[1].cls == \"All\":\n            return \"%(name)s\"\n\n        # All + ...\n        if node[0].cls == \"All\":\n            # All + uvec\n            if dim1:\n                return \"%(name)s.cols(\" + arg1 + \")\"\n            # All + scalar\n            return \"%(name)s.col(\" + arg1 + \")\"\n\n        # ... + All\n        elif node[1].cls == \"All\":\n            # uvec + All\n            if dim0:\n                return \"%(name)s.rows(\" + arg0 + \")\"\n            # scalar + All\n            return \"%(name)s.row(\" + arg0 + \")\"\n\n    return \"%(name)s(\", \", \", \")\"\n\ndef Set(node):\n    node.error(\"unknown data type\")\n\n    # Double argument\n    if len(node) == 2:\n\n        arg0, dim0 = arma.configure_arg(node[0], 0)\n        arg1, dim1 = arma.configure_arg(node[1], 1)\n\n        # All + All\n        if node[0].cls == node[1].cls == \"All\":\n            return \"%(name)s\"\n\n        # All + ...\n        if node[0].cls == \"All\":\n            # All + uvec\n            if dim1:\n                return \"%(name)s.cols(\" + arg1 + \")\"\n            # All + scalar\n            return \"%(name)s.col(\" + arg1 + \")\"\n\n        # ... + All\n        elif node[1].cls == \"All\":\n            # uvec + All\n            if dim0:\n                return \"%(name)s.rows(\" + arg0 + \")\"\n            # scalar + All\n            return \"%(name)s.row(\" + arg0 + \")\"\n\n        # scalar + uvec\n        if dim0 == 0 and dim1 > 0:\n            #arg0 = \"m2cpp::asuvec(\" + arg0 + \")\"\n            return \"%(name)s.col(\" + arg0 + \").rows(\" + arg1 + \")\"\n\n        # uvec + scalar\n        elif dim0 > 0 and dim1 == 0:\n            #arg1 = \"m2cpp::asuvec(\" + arg1 + \")\"\n            return \"%(name)s.row(\" + arg0 + \").cols(\" + arg1 + \")\"\n\n        return \"%(name)s(\" + arg0 + \", \" + arg1 + \")\"\n\n    return \"%(name)s(\", \", \", \")\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_urowvec.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .rowvec import Get, Set\n\nDeclare = \"urowvec %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_uvec.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .vec import Get, Set\n\nDeclare = \"uvec %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_uword.py",
    "content": "from .assign import Assign\nfrom .variables import *\n\nDeclare = \"uword %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_vec.py",
    "content": "from .assign import Assign\nfrom .variables import *\nfrom .vec import Get, Set\n\nDeclare = \"vec %(name)s ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/_verbatim.py",
    "content": "Verbatim = \"// %(name)s\\n%(value)s\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/armadillo.py",
    "content": "\"\"\"\nfiller for Armadillo\n\"\"\"\n\nimport matlab2cpp\n\ndef configure_arg(node, index):\n    \"\"\"\nConfigure an argument of an vector, matrix or cube.\n\nArgs:\n    node (Get, Set): Current possition in node-tree\n    index (int): argument index (starting from 0)\n\nReturns:\n    tuple: A string representation of argument and an index (-1,0,1) indicating\n    if the argument was unknown, scalar or a vector, respectively.\n\nExamples:\n    >>> print(matlab2cpp.qscript('x=[1,2]; x(:)'))\n    sword _x [] = {1, 2} ;\n    x = irowvec(_x, 2, false) ;\n    x(span(0, x.n_rows-1)) ;\n    >>> print(matlab2cpp.qscript('x=[1,2]; x(1)'))\n    sword _x [] = {1, 2} ;\n    x = irowvec(_x, 2, false) ;\n    x(0) ;\n    >>> print(matlab2cpp.qscript('x=[1,2]; x([1,2])'))\n    sword _x [] = {1, 2} ;\n    x = irowvec(_x, 2, false) ;\n    uword __aux_urowvec_1 [] = {1, 2} ;\n    _aux_urowvec_1 = urowvec(__aux_urowvec_1, 2, false) ;\n    x(arma::strans(_aux_urowvec_1)-1) ;\n    >>> print(matlab2cpp.qscript('x=[1,2]; x([1,2;2,1])'))\n    sword _x [] = {1, 2} ;\n    x = irowvec(_x, 2, false) ;\n    uword __aux_umat_1 [] = {1, 2, 2, 1} ;\n    _aux_umat_1 = arma::strans(umat(__aux_umat_1, 2, 2, false)) ;\n    x(_aux_umat_1-1) ;\n    >>> print(matlab2cpp.qscript(\"x=[1,2]; x(x')\"))\n    sword _x [] = {1, 2} ;\n    x = irowvec(_x, 2, false) ;\n    x(arma::trans(x)-1) ;\n    \"\"\"\n\n    out = \"%(\" + str(index) + \")s\"\n\n    # the full range ':'\n    if node.cls == \"All\":\n\n        arg = node.parent.name\n\n        # first axis\n        if index == 0:\n\n            # axis and dim does not match for colvec and rowvec\n            if node.parent.dim == 1:\n                arg += \".n_cols\"\n            else:\n                arg += \".n_rows\"\n\n        # second axis\n        elif index == 1:\n            arg += \".n_cols\"\n\n        # third axis\n        elif index == 2:\n            arg += \".n_slices\"\n\n        return \"span(0, \" + arg + \"-1)\", 1\n\n    # undefined type\n    elif node.type == \"TYPE\":\n        return out, -1\n\n    # float point scalar\n    elif node.mem > 1 and node.dim == 0:\n        out = \"(uword) \" + out\n\n    #Float or double, vec or rowvec\n        \"\"\"\n    elif node.mem not in (0, 4) and node.dim in (1, 2):\n        out = \"arma::conv_to<uvec>::from(\" + out + \")\"\n        \"\"\"\n    # rowvec (-> colvec)\n    elif node.dim == 2:\n        out = \"arma::strans(\" + out + \")\"\n\n    # scalar done verbatim\n    if node.dim == 0:\n        if node.cls == \"Int\":\n            out = str(int(node.value)-1)\n        elif node.cls == \"Float\":\n            out = str(float(node.value)-1)\n        else:\n            out = out + \"-1\"\n        dim = 0\n\n    # matrices and cubes \n    elif node.dim > 2:\n        dim = node.dim\n        out = out + \"-1\"\n\n    else:\n        dim = 1\n\n        if len(node) > 0 and node[0].cls == \"Paren\":\n            pass\n        elif node.cls not in [\"Colon\", \"Paren\"]:\n            out = out + \"-1\"\n\n    return out, dim\n\n\ndef scalar_assign(node):\n    \"\"\"\nconvert scalar to various array types\n    \"\"\"\n\n    # left-hand-side and right-hand-side\n    lhs, rhs = node\n\n    if lhs.mem < rhs.mem:\n        node.warning(\"Type reduction from %s to %s\" % (rhs.type, lhs.type))\n\n    # matrix suround are ignored\n    if rhs.cls == \"Matrix\":\n        rhs = str(rhs[0][0])\n\n    else:\n        rhs = \"%(1)s\"\n\n    if lhs.cls == \"Set\":\n        return \"%(0)s.fill(\" + rhs + \") ;\"\n\n    #Earlier stuff, replaced with code right above\n    \"\"\"\n    if lhs.dim == 0:\n        pass\n\n    # as colvec\n    elif lhs.dim == 1:\n        node.include(\"m2cpp\")\n        rhs = \"m2cpp::scol(\" + rhs + \")\"\n\n    # as rowvec\n    elif lhs.dim == 2:\n        node.include(\"m2cpp\")\n        rhs = \"m2cpp::srow(\" + rhs + \")\"\n\n    # as matrix\n    elif lhs.dim == 3:\n        node.include(\"m2cpp\")\n        rhs = \"m2cpp::smat(\" + rhs + \")\"\n\n    # as cube\n    elif lhs.dim == 4:\n        #scube is not implemented in mconvert.h, namespace m2cpp at the moment\n        node.include(\"m2cpp\")\n        rhs = \"m2cpp::scube(\" + rhs + \")\"\n    \"\"\"\n    \n    return \"%(0)s = \" + rhs + \" ;\"\n\n\ndef include(node):\n    \"\"\"Add armadillo to header\"\"\"\n\n    program = node.program\n    includes = program[0]\n\n    arma = \"#include <armadillo>\"\n    namespace = \"using namespace arma ;\"\n\n    if arma in includes and namespace in includes:\n        return\n\n    if arma not in includes:\n        include = matlab2cpp.collection.Include(includes, arma, value=includes.value)\n        include.backend = \"program\"\n\n    if namespace not in includes:\n        include = matlab2cpp.collection.Include(includes, namespace, value=includes.value)\n        include.backend = \"program\"\n\n    includes.translate()\n\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/rules/assign.py",
    "content": "import matlab2cpp\nfrom . import armadillo as arma\n\ndef Assign(node):\n    \"\"\"\nAssignment (General case)\n\nArgs:\n    node (Assign): Current position in node-tree.\n\nReturns:\n    str : Translation of current node.\n\nExamples:\n    >>> print(matlab2cpp.qscript(\"a = b\"))\n    a = b ;\n    >>> print(matlab2cpp.qscript(\"a=[1,2]; b=[1;2]; a=b\"))\n    sword _a [] = {1, 2} ;\n    a = irowvec(_a, 2, false) ;\n    sword _b [] = {1, 2} ;\n    b = ivec(_b, 2, false) ;\n    a = arma::strans(b) ;\n    >>> print(matlab2cpp.qscript(\"a=[1,2,2,1]; b=[2,1;1,2]; a=b\"))\n    sword _a [] = {1, 2, 2, 1} ;\n    a = irowvec(_a, 4, false) ;\n    sword _b [] = {2, 1, 1, 2} ;\n    b = arma::strans(imat(_b, 2, 2, false)) ;\n    a = b ;\n    \"\"\"\n\n    # left-hand-side and right-hand-side\n    lhs, rhs = node\n\n    # unknown datatype\n    if \"TYPE\" in (lhs.type, rhs.type) or lhs.type == rhs.type:\n        return \"%(0)s = %(1)s ;\"\n\n    # numerical\n    if lhs.num and rhs.num:\n        \n        # mismatch between colvec and rowvec, do transpose\n        if (lhs.dim == 2 and rhs.dim == 1) or\\\n                (lhs.dim == 1 and rhs.dim == 2): #or lhs.mem != rhs.mem:\n            #out = \"arma::conv_to<\" + lhs.type + \">::from(%(1)s)\"\n            out = \"arma::strans(%(1)s)\"\n        else:\n            out = \"%(1)s\"\n\n        # both scalar\n        if lhs.dim == 0 and rhs.dim == 0:\n\n            if lhs.mem >= rhs.mem:\n                out = \"\" + lhs.type + \"(\" + out + \")\"\n            else:\n                node.warning(\"Type reduction from %s to %s\" %\\\n                        (rhs.type, lhs.type))\n\n        # fill array with scalar value\n        elif lhs.dim > 0 and rhs.dim == 0:\n            return arma.scalar_assign(node)\n\n        # dimensions that works just fine\n        #elif lhs.dim in (1,2) and rhs.dim in (3, 4):\n        #    pass\n        elif lhs.dim == 0 and rhs.dim > 0:\n            out = lhs.type + \"(arma::as_scalar(%(1)s))\"\n\n        # Added this elif to handle assignment of: complex type = non_complex type\n        elif  lhs.mem > rhs.mem:\n            if lhs.dim > 0 and rhs.dim > 0:\n                out = \"conv_to<\" + lhs.type + \">::from(%(1)s)\"\n            elif lhs.dim == 0 and rhs.dim == 0:\n                if lhs.mem == 4:\n                    out = \"\" + lhs.type + \"\" + \"(%(1)s)\"\n\n        # all the ways things are wrong\n        elif lhs.dim > 0 and rhs.dim > 0:\n\n            if lhs.mem >= rhs.mem:\n                node.warning(\"Possible size incompatibility \"+\\\n                        \"%s and %s\" % (lhs.type, rhs.type))\n            else:\n                node.warning(\"Type reduction and possible size \"+\\\n                        \"incompatible %s and %s\" % (lhs.type, rhs.type))\n\n        else:\n            node.error(\"Types incompatible %s and %s\" % (lhs.type, rhs.type))\n\n    else:\n        node.error(\"Types incompatible %s and %s\" % (lhs.type, rhs.type))\n        out = \"%(1)s\"\n\n    out = \"%(0)s = \" + out + \" ;\"\n    return out\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/rules/cube.py",
    "content": "from .variables import *\nfrom . import armadillo as arma\n\ndef Get(node):\n\n    # number of argument not legal for cube\n    if len(node) not in (1,2,3):\n\n        if not len(node):\n            node.error(\"Zero arguments in a cube call\")\n        else:\n            node.error(\"More than three arguments in a cube call\")\n\n        return \"%(name)s(\", \"-1, \", \"-1)\"\n\n\n    # Single argument\n    if len(node) == 1:\n\n        arg, dim = arma.configure_arg(node[0], 0)\n\n        # unknown input\n        if dim == -1:\n            return \"%(name)s(%(0)s-1)\"\n\n        # scalar input\n        #if dim == 0:\n        #    node.dim = 0\n\n        return \"%(name)s(\" + arg + \")\"\n\n\n    # Double argument\n    elif len(node) == 2:\n\n        arg0, dim0 = arma.configure_arg(node[0], 0)\n        arg1, dim1 = arma.configure_arg(node[1], 1)\n\n        # unkonwn input\n        if -1 in (dim0, dim1):\n            return \"%(name)s(\", \"-1, \", \"-1)\"\n\n        # Configure dimensions\n        #if dim0:\n        #    if dim1:\n        #        node.dim = 3\n        #    else:\n        #        node.dim = 1\n        #else:\n        #    if dim1:\n        #        node.dim = 2\n        #    else:\n        #        node.dim = 0\n\n        node = node.resize() # matlab to armadillo fix for cubes\n\n        return \"_%(name)s(\" + arg0 + \", \" + arg1 + \")\"\n\n    # Triple argument\n    elif len(node) == 3:\n\n        arg0, dim0 = arma.configure_arg(node[0], 0)\n        arg1, dim1 = arma.configure_arg(node[1], 1)\n        arg2, dim2 = arma.configure_arg(node[2], 2)\n\n        # unknown arguments\n        if -1 in (dim0, dim1, dim2):\n            return \"%(name)s(\", \"-1, \", \"-1)\"\n\n        # Configure dimensions\n        #if dim0:\n        #    if dim1:\n        #        if dim2:\n        #            node.dim = 4#cube\n        #        else:\n        #            node.dim = 3#matrix\n        #    else:\n        #        if dim2:\n        #            node.dim = 3#matrix\n        #        else:\n        #            node.dim = 1#colvec\n        \n        #else:\n        #    if dim1:\n        #        if dim2:\n        #            node.dim = 3#matrix\n        #        else:\n        #            node.dim = 1#colvec\n        #    else:\n        #        if dim2:\n        #            node.dim = 1#colvec\n        #        else:\n        #            node.dim = 0#scalar\n        \n        return \"%(name)s(\" + arg0 + \", \" + arg1 + \", \" + arg2 + \")\"\n\n\ndef Set(node):\n\n    if len(node) not in (1,2,3):\n\n        if not len(node):\n            node.error(\"Zero arguments in a cube set\")\n        else:\n            node.error(\"More than three arguments in a cube set\")\n\n        return \"%(name)s(\", \"-1, \", \"-1)\"\n\n    # Single argument\n    if len(node) == 1:\n\n        arg, dim = arma.configure_arg(node[0], 0)\n\n        # unknown arguments\n        if dim == -1:\n            return \"%(name)s(%(0)s-1)\"\n\n        # if scalar arg, set node as scalar\n        #if dim == 0:\n        #    node.dim = 0\n\n        return \"%(name)s(\" + arg + \")\"\n\n\n    # Double argument\n    elif len(node) == 2:\n\n        arg0, dim0 = arma.configure_arg(node[0], 0)\n        arg1, dim1 = arma.configure_arg(node[1], 1)\n\n        # unknown args\n        if -1 in (dim0, dim1):\n            return \"%(name)s(\", \"-1, \", \"-1)\"\n\n        node = node.resize() # matlab to armadillo fix for cubes\n\n        # Configure dimensions\n        #if dim0:\n        #    if dim1:\n        #        node.dim = 3#matrix\n        #    else:\n        #        node.dim = 1#colvec\n        #else:\n        #    if dim1:\n        #        node.dim = 2#rowvec\n        #    else:\n        #        node.dim = 0#scalar\n        \n        return \"%(name)s(\" + arg0 + \", \" + arg1 + \", 1)\"\n\n    # triple argument\n    elif len(node) == 3:\n\n        arg0, dim0 = arma.configure_arg(node[0], 0)\n        arg1, dim1 = arma.configure_arg(node[1], 1)\n        arg2, dim2 = arma.configure_arg(node[2], 2)\n\n        # unkown input\n        if -1 in (dim0, dim1, dim2):\n            return \"%(name)s(\", \", \", \")\"\n\n        # Configure dimensions\n        #if dim0:\n        #    if dim1:\n        #        if dim2:\n        #            node.dim = 4#cube\n        #        else:\n        #            node.dim = 3#matrix\n        #    else:\n        #        if dim2:\n        #            node.dim = 3#matrix\n        #        else:\n        #            node.dim = 1#colvec\n        \n        #else:\n        #    if dim1:\n        #        if dim2:\n        #            node.dim = 3#matrix\n        #        else:\n        #            node.dim = 1#colvec\n        #    else:\n        #        if dim2:\n        #            node.dim = 1#colvec\n        #        else:\n        #            node.dim = 0#scaler\n        \n        return \"%(name)s(\" + arg0 + \", \" + arg1 + \", \" + arg2 + \")\"\n\n\ndef Resize(node):\n    \"\"\"Special resizing of cube such that properly tranlsation between matlab\n    and armadillo.\"\"\"\n\n    return \"%(type)s_%(name)s(%(name)s.memptr(), %(name)s.n_rows, \" +\\\n            \"%(name)s.n_cols*%(name)s.n_slices, false) ;\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/function.py",
    "content": "import matlab2cpp\n\ndef type_string(node):\n    \"\"\"\nDetermine string represnentation of type.\n\nOutside scalars and armadillo, the datatype name and their declaration do not\nmatch. This function converts simple datatype declaration and translate them to\nequivalent C++ declarations.\n\n+-----------------+-----------------------+\n| Input           | Output                |\n+=================+=======================+\n| numerical types | node.type             |\n+-----------------+-----------------------+\n| struct, structs | struct container name |\n+-----------------+-----------------------+\n| func_lambda     | std::function<...>    |\n+-----------------+-----------------------+\n| string          | std::string           |\n+-----------------+-----------------------+\n\nArgs:\n    node (Node): location in tree\nReturns:\n    str: String representation of node type\n    \"\"\"\n\n    # lambda-function\n    if node.type == \"func_lambda\":\n\n        # link to actual lambda-function\n        func = None\n\n        if hasattr(node.declare, \"reference\"):\n            func = node.declare.reference\n\n        elif \"_\"+node.name in node.program[1].names:\n            func = node.program[1][\"_\"+node.name]\n\n        if not (func is None):\n\n            # no returns in lambda\n            if len(func[1]) == 0:\n                ret = \"void\"\n                prm = \", \".join([p.type for p in func[2]])\n\n            # single return\n            elif len(func[1]) == 1:\n                ret = func[1][0].type\n                prm = \", \".join([p.type for p in func[2]])\n\n            # multiple return\n            else:\n                ret = \"void\"\n                prm = \", \".join([p.type for p in func[2][:]+func[1][:]])\n\n            return \"std::function<\" + ret + \"(\" + prm + \")>\"\n\n        else:\n            node.warning(\"lambda function content not found\")\n            return \"std::function\"\n\n    # struct scalar and array type\n    elif node.type in (\"struct\", \"structs\"):\n        declare = node.declare\n        if declare.parent.cls == \"Struct\":\n            declare = declare.parent\n        return \"_\" + declare.name.capitalize()\n\n    elif node.type == \"string\":\n        return \"std::string\"\n\n    return node.type\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/rules/mat.py",
    "content": "from . import armadillo as arma\n\ndef Get(node):\n    \"\"\"\n    Statement\n        Get (a)\n\n    a()\n\n    Assign\n        Var (b)\n        Get (a)\n\n    b = a()\n    \"\"\"\n\n    # number of args not correct\n    if len(node) not in (1,2):\n\n        if not len(node):\n            node.error(\"Zero arguments in a matrix call\")\n        else:\n            node.error(\"More than two arguments in a matrix call\")\n\n        return \"%(name)s(\", \"-1, \", \"-1)\"\n\n    # Single argument\n    if len(node) == 1:\n\n        arg, dim = arma.configure_arg(node[0], 0)\n\n        # unknown input\n        if dim == -1:\n            return \"%(name)s(%(0)s-1)\"\n\n        # scalar begets scalar\n        #if dim == 0:\n        #    node.dim = 0\n\n        return \"%(name)s(\" + arg + \")\"\n\n    # Double argument\n    elif len(node) == 2:\n\n        arg0, dim0 = arma.configure_arg(node[0], 0)\n        arg1, dim1 = arma.configure_arg(node[1], 1)\n\n        # unknown input\n        if -1 in (dim0, dim1):\n            return \"%(name)s(\", \"-1, \", \"-1)\"\n\n        # Configure dimensions\n        #if dim0:\n        #    if dim1:\n        #        node.dim = 3#matrix\n        #    else:\n        #        node.dim = 1#colvec\n        #else:\n        #    if dim1:\n        #        node.dim = 2#rowvec\n        #    else:\n        #        node.dim = 0#scalar\n\n        # All + All\n        if node[0].cls == node[1].cls == \"All\":\n            return \"%(name)s\"\n\n        # All + ...\n        if node[0].cls == \"All\":\n            # All + uvec\n            if dim1:\n                return \"%(name)s.cols(\" + arg1 + \")\"\n            # All + scalar\n            return \"%(name)s.col(\" + arg1 + \")\"\n\n        # ... + All\n        elif node[1].cls == \"All\":\n            # uvec + All\n            if dim0:\n                return \"%(name)s.rows(\" + arg0 + \")\"\n            # scalar + All\n            return \"%(name)s.row(\" + arg0 + \")\"\n\n        # scalar + uvec\n        if dim0 == 0 and dim1 > 0:\n\n            index = node[1].str.index('(')\n            return \"%(name)s(m2cpp::span<uvec>(\" + arg0 + \", \" + arg0 + \")\" + \", \" \\\n                   + \"m2cpp::span<uvec>\" + node[1].str[index:] + \")\"\n            #return \"%(name)s.col(\" + arg0 + \").rows(\" + arg1 + \")\"\n\n\n        # uvec + scalar\n        elif dim0 > 0 and dim1 == 0:\n            return \"%(name)s(\" + arg0 + \", m2cpp::span<uvec>(\" + arg1 + \", \" + arg1 + \"))\"\n            #index = node[0].str.index('(')\n            #return \"%(name)s(\" + \"m2cpp::span<uvec>\" + node[0].str[index:] + \", m2cpp::span<uvec>(\" + arg1 + \", \" + arg1 + \"))\"\n            #return \"%(name)s.row(\" + arg0 + \").cols(\" + arg1 + \")\"\n\n        # uvec + uvec\n        if dim0 > 0 and dim1 > 0:\n            a0 = node[0].str.replace(\"arma::span\", \"m2cpp::span<uvec>\")\n            a1 = node[1].str.replace(\"arma::span\", \"m2cpp::span<uvec>\")\n\n            return \"%(name)s(\" + a0 + \", \" + a1 + \")\"\n\n        return \"%(name)s(\" + arg0 + \", \" + arg1 + \")\"\n\n\ndef Set(node):\n    \"\"\"\n    Assign\n        Set (a)\n            Var (n)\n        Var (b)\n\n    a(n) = b\n    \"\"\"\n\n    # wrong number of argumets\n    if len(node) not in (1,2):\n\n        if not len(node):\n            node.error(\"Zero arguments in a matrix set\")\n        else:\n            node.error(\"More than two arguments in a matrix set\")\n\n        return \"%(name)s(\", \"-1, \", \"-1)\"\n\n    # Single argument\n    if len(node) == 1:\n\n        arg, dim = arma.configure_arg(node[0], 0)\n\n        # scalar arg is scalar\n        #if dim == 0:\n        #    node.dim = 0\n\n        # unknown datatype\n        if dim == -1:\n            return \"%(name)s(\", \"-1, \", \"-1)\"\n\n        return \"%(name)s(\" + arg + \")\"\n\n\n    # Double argument\n    elif len(node) == 2:\n\n        arg0, dim0 = arma.configure_arg(node[0], 0)\n        arg1, dim1 = arma.configure_arg(node[1], 1)\n\n        # unknown datatype\n        if -1 in (dim0, dim1):\n            return \"%(name)s(\", \"-1, \", \"-1)\"\n\n        # Configure dimensions\n        #if dim0:\n        #    if dim1:\n        #        node.dim = 3#matrix\n        #    else:\n        #        node.dim = 1#colvec\n        #else:\n        #    if dim1:\n        #        node.dim = 2#rowvec\n        #    else:\n        #        node.dim = 0#scalar\n\n        # All + All\n        if node[0].cls == node[1].cls == \"All\":\n            return \"%(name)s\"\n\n        # All + ...\n        if node[0].cls == \"All\":\n            # All + uvec\n            if dim1:\n                return \"%(name)s.cols(\" + arg1 + \")\"\n            # All + scalar\n            return \"%(name)s.col(\" + arg1 + \")\"\n\n        # ... + All\n        elif node[1].cls == \"All\":\n            # uvec + All\n            if dim0:\n                return \"%(name)s.rows(\" + arg0 + \")\"\n            # scalar + All\n            return \"%(name)s.row(\" + arg0 + \")\"\n\n        # scalar + uvec\n        if dim0 == 0 and dim1 > 0:\n            index = node[1].str.index('(')\n            return \"%(name)s(m2cpp::span<uvec>(\" + arg0 + \", \" + arg0 + \")\" + \", \" \\\n                   + \"m2cpp::span<uvec>\" + node[1].str[index:] + \")\"\n            #return \"%(name)s.col(\" + arg0 + \").rows(\" + arg1 + \")\"\n\n\n        # uvec + scalar\n        elif dim0 > 0 and dim1 == 0:\n            index = node[0].str.index('(')\n            return \"%(name)s(\" + \"m2cpp::span<uvec>\" + node[0].str[index:] + \\\n                   \", m2cpp::span<uvec>(\" + arg1 + \", \" + arg1 + \"))\"\n            #return \"%(name)s.row(\" + arg0 + \").cols(\" + arg1 + \")\"\n\n        # uvec + uvec\n        if dim0 > 0 and dim1 > 0:\n            a0 = node[0].str.replace(\"arma::span\", \"m2cpp::span<uvec>\")\n            a1 = node[1].str.replace(\"arma::span\", \"m2cpp::span<uvec>\")\n\n            return \"%(name)s(\" + a0 + \", \" + a1 + \")\"\n\n        return \"%(name)s(\" + arg0 + \", \" + arg1 + \")\"\n\n"
  },
  {
    "path": "src/matlab2cpp/rules/parallel.py",
    "content": "\ndef variable_lists(node):\n    nodes = node.flatten(ordered=False, reverse=False, inverse=False)\n\n    #store some variable names, in private or shared\n    assigned_var = []\n    type_info = []\n\n    #get iterator name\n    iterator_name = node[0].name\n    for n in nodes:\n        if n.cls == \"Assign\":\n            #index = n.parent.children.index(n)\n            #lhs var of the assignment\n            if n[0].cls == \"Var\":\n                if n[0].name not in assigned_var:\n                    assigned_var.append(n[0].name)\n                    type_info.append(n[0].type)\n\n\n            \"\"\"\n            if n[0].cls == \"Set\":\n                var_name = n[0].name\n\n                #subnodes to Set\n                #index = n.parent.children.index(n)\n                #subnodes = n.parent[index].flatten(ordered=False, reverse=False, inverse=False)\n                subnodes = n[0].flatten(ordered=False, reverse=False, inverse=False)\n\n                for subnode in subnodes[1:]:\n                    if subnode.name and subnode.name == iterator_name:\n                        shared_variable.append(var_name)\n                        #print(subnode.name)\n            \"\"\"\n\n        #multiple return from function are assigned to vars\n        if n.cls == \"Assigns\": #and n.backend == \"func_returns\":\n            for sub_node in n:\n                if sub_node.cls == \"Var\":\n                    if sub_node.name not in assigned_var:\n                        assigned_var.append(sub_node.name)\n                        type_info.append(sub_node.type)\n\n\n        #get the iteration variable in the for loop\n        if n.cls == \"Var\" and n.parent.cls == \"For\":\n            if n.name not in assigned_var:\n                assigned_var.append(n.name)\n                type_info.append(n.type)\n\n    #shared_variable = list(set(shared_variable))\n    #print(shared_variable)\n\n    #for n in nodes:\n    #    if (n.cls == \"Var\" or n.cls == \"Get\") and n.backend != \"reserved\" and n.name \\\n    #            not in [shared_variable, node[0].name]:\n    #        private_variable.append(n.name)\n\n    #private_variable = list(set(private_variable))\n\n    #return private_variable, shared_variable, assigned_var, type_info\n    return assigned_var, type_info\n\ndef omp(node, start, stop, step):\n    assigned_var, type_info = variable_lists(node)\n\n    #out = \"#pragma omp parallel for\\nfor (%(0)s=\" + start + \\\n            #    \"; %(0)s<=\" + stop + \"; %(0)s\"\n\n    temp_str = \"\"\n    if len(assigned_var) > 1:\n        temp_str = \", \".join(assigned_var[1:])\n        temp_str = \"firstprivate(\" + temp_str + \")\"\n\n    out = \"#pragma omp parallel for \" + temp_str + \"\\nfor (%(0)s=\" + start + \\\n                \"; %(0)s<=\" + stop + \"; %(0)s\"\n\n    return out\n\ndef tbb(node, start, stop, step):\n    assigned_var, type_info = variable_lists(node)\n\n    any_vec_or_mat = False\n    for var, type in zip(assigned_var, type_info):\n        if type not in [\"uword\", \"int\", \"float\", \"double\"]:\n            any_vec_or_mat = True\n\n    #tbb.counter += 1\n    out = \"{\\n\"\n\n    #str_val = str(tbb.counter)\n    if any_vec_or_mat:\n        declare_struct = \"struct tbb_var_struct\" + \"\\n{\"\n\n        for var, type in zip(assigned_var, type_info):\n            if type not in [\"uword\", \"int\", \"float\", \"double\"]:\n                declare_struct += \"\\n\" + type + \" \" + var + \";\"\n\n        declare_struct += \"\\n} \" + \";\\n\"\n        declare_struct += \"tbb::combinable<struct tbb_var_struct\" + \"> tbb_per_thread_data\" + \" ;\\n\"\n\n        out += declare_struct\n\n    #for var, type in zip(assigned_var, type_info):\n    #    out += \"tbb::enumerable_thread_specific<\" + type + \"> \" + \"_\" + var + \" = \" + var + \" ;\\n\"\n\n    out += \"tbb::parallel_for(tbb::blocked_range<size_t>(\" + start + \", \" + stop + \"+1\" + \\\n                  \"),\\n\" + \"[&]\" + \"(const tbb::blocked_range<size_t>& _range) \\n{\\n\"\n\n    #assign to local L, x, y\n    for var, type in zip(assigned_var, type_info):\n        if type in [\"uword\", \"int\", \"float\", \"double\"]:\n            out += type + \" \" + var + \";\\n\"\n\n    if any_vec_or_mat:\n        out += \"struct tbb_var_struct\" + \" tbb_struct_vars = tbb_per_thread_data\" + \".local() ;\\n\"\n\n        for var, type in zip(assigned_var, type_info):\n            if type not in [\"uword\", \"int\", \"float\", \"double\"]:\n                out += type + \"& \" + var + \" = \" + \"tbb_struct_vars.\" + var + \";\\n\"\n\n    #for var, type in zip(assigned_var, type_info):\n    #    out += type + \"& \" + var + \" = _\" + var + \".local() ;\\n\"\n\n    out += \"for (\" + \"%(0)s = _range.begin(); %(0)s != _range.end(); %(0)s\"\n\n    # special case for '+= 1'\n    if step == \"1\":\n        out += \"++\"\n    else:\n        out += \"+=\" + step\n\n    out += \")\\n{\\n%(2)s\\n}\"\n    out += \"\\n}\\n);\\n\"\n    out += \"}\"\n    return out\n\n#tbb.counter = 0\n"
  },
  {
    "path": "src/matlab2cpp/rules/rowvec.py",
    "content": "from . import armadillo as arma\n\ndef Get(node):\n\n    if len(node) != 1:\n\n        if not len(node):\n            node.error(\"Zero arguments in a rowvec call\")\n            return \"%(name)s()\"\n\n        elif len(node) == 2 and node[0].cls == \"Int\" and node[0].value == \"1\":\n            node_ = node[1]\n            \n        #special case hh = h0F(:,ones(1,M)) with h0F rowvec, and ones\n        elif len(node) == 2 and node[0].name == \"ones\" or \\\n            node[1].name == \"ones\":\n            out = \"%(name)s(\"\n            if node[0].name == \"ones\":\n                out = out + \"%(0)s-1, \"\n                #return \"%(name)s(%(0)s-1, %(1)s)\"\n            else:\n                out = out + \"%(0)s, \"\n            if node[1].name == \"ones\":\n                out = out + \"%(1)s-1)\"\n                #return \"%(name)s(%(0)s, %(1)s-1)\"\n            else:\n                out = out + \"%(1)s)\"\n            return out\n            \n        else:\n            node.error(\"More than one arguments in a rowvec call\")\n            return \"%(name)s(\", \"-1, \", \"-1)\"\n    else:\n        node_ = node[0]\n\n\n    arg, dim = arma.configure_arg(node_, 0)\n\n    if dim == -1:\n        return \"%(name)s(\", \"-1, \", \"-1)\"\n\n    #if dim == 0:\n    #    node.dim = 0\n\n    # a(uvec array) or a(1:2:5)\n    if (node[0].type == \"uvec\" and node[0].cls == \"Var\") or \\\n        node[0].cls == \"Colon\" and len(node[0]) == 3:\n        return \"arma::strans(%(name)s(\" + arg + \"))\"\n\n    return \"%(name)s(\" + arg + \")\"\n\n\ndef Set(node):\n    if len(node) != 1:\n\n        if not len(node):\n            node.error(\"Zero arguments in a rowvec call\")\n            return \"%(name)s()\"\n\n        elif len(node) == 2 and node[0].cls == \"Int\" and node[0].value == \"1\":\n            node_ = node[1]\n\n        else:\n            node.error(\"More than one arguments in a rowvec call\")\n            return \"%(name)s(\", \"-1, \", \"-1)\"\n    else:\n        node_ = node[0]\n\n\n    arg, dim = arma.configure_arg(node_, 0)\n\n    #if dim == 0:\n    #    node.dim = 0\n\n    if dim == -1:\n        return \"%(name)s(\", \"-1, \", \"-1)\"\n\n    return \"%(name)s(\" + arg + \")\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/variables.py",
    "content": "#import matlab2cpp\ndef Var(node):\n    if node.type == \"TYPE\":\n        node.error(\"unknown data type\")\n    return \"%(name)s\"\n\ndef Fvar(node):\n\n    if node.backend == \"structs\":\n        if node.parent.cls == \"Vector\":\n            if len(node.parent) == 1 and len(node.parent.parent) == 1:\n                size = node.declare.parent[\"_size\"]\n                return size.value\n        return \"%(name)s[0].%(value)s\"\n    return \"%(name)s.%(value)s\"\n\ndef Cvar(node):\n    \"a{b}\"\n\n    #if node.type == \"TYPE\":\n    #    node.declare.type = \"cell\"\n\n    if not node.type == \"cell\" or node.type == \"varargin\":\n        node.error(\"Behaves like cell, not %s\" % node.type)\n\n    return \"%(name)s{\", \"}{\", \"}\"\n\ndef Set(node):\n    if node.type == \"TYPE\":\n        node.error(\"unknown data type\")\n    elif node.num and node.mem == 0:\n        node.error(\"scalar are not iterable\")\n    return \"%(name)s(\", \", \", \")\"\n\ndef Cset(node):\n    \"a{b}(c) = d\"\n\n    if node.type == \"TYPE\":\n        node.declare.type = \"cell\"\n\n    elif node.type != \"cell\":\n        node.error(\"Behaves like cell, not %s\" % node.type)\n\n    n_fields = node[\"n_fields\"]\n\n    out = \"%(name)s{%(\"\n    out = out + \")s}{%(\".join(map(str, range(n_fields)))\n    out = out + \")s}(%(\"\n    out = out + \")s, %(\".join(map(str, range(n_fields, len(node))))\n    out = out + \")s)\"\n    return out\n\ndef Sset(node):\n    node.pointer = 0\n    if len(node) == 1 and node[0].cls == \"Int\":\n        return \"%(name)s[\" + str(int(node[0].value)-1) + \"].%(value)s\"\n    return \"%(name)s[\", \", \", \"-1].%(value)s\"\n\ndef Nset(node):\n    return \"%(name)s.(\", \", \", \")\"\n\ndef Get(node):\n    return \"%(name)s(\", \", \", \")\"\n\ndef Cget(node):\n    \"a{b}(c)\"\n\n    if node.type == \"TYPE\":\n        node.declare.type = \"cell\"\n\n    elif node.type != \"cell\":\n        node.error(\"Behaves like cell, not %s\" % node.type)\n\n    n_fields = node[\"n_fields\"]\n\n    out = \"%(name)s{%(\"\n    out = out + \")s}{%(\".join(map(str, range(n_fields)))\n    out = out + \")s}(%(\"\n    out = out + \")s, %(\".join(map(str, range(n_fields, len(node))))\n    out = out + \")s)\"\n    return out\n\ndef Fget(node):\n    node.pointer = 0\n    if len(node) == 1 and node[0].cls == \"Int\":\n        return \"%(name)s[\" + str(int(node[0].value)-1) + \"].%(value)s\"\n    return \"%(name)s.%(value)s(\", \", \", \")\"\n\ndef Sget(node):\n    return \"%(name)s[\", \", \", \"-1].%(value)s\"\n\ndef Nget(node):\n    return \"%(name)s.(\", \", \", \")\"\n\n\"\"\"\ndef Assign(node):\n    lhs, rhs = node\n    # assign a my_var = [a.val], a is a structs, my_var should be a vec\n    if node[1].cls == \"Matrix\" and (node[1].backend == \"struct\" or node[1].backend == \"unknown\"):\n        element = rhs[0][0]\n\n        if element.backend == \"struct\" or element.backend == \"unknown\":\n            var = lhs.name\n            name = element.name\n            value = element.value\n            declares = node.func[0]\n\n            if \"_i\" not in declares:\n                declare = matlab2cpp.collection.Var(declares, \"_i\")\n                declare.type = \"int\"\n                declare.backend = \"int\"\n                declares.translate()\n\n                for var in declares:\n                    index = var.parent.children.index(var)\n\n                    if var.name == name:\n                        del var.parent.children[index]\n                        for program in node.project:\n                            structs = program[3]\n\n                            for struct in structs:\n                                index = struct.parent.children.index(struct)\n                                if struct.name == name:\n                                    del struct.parent.children[index]\n\n            string = var + \".set_size(\" + name + \".size()\" + \") ;\\n\" +\\\n                \"for (_i=0; _i<\" + var + \".n_elem\" + \"; ++_i)\\n  \" +\\\n                var + \"(_i) = \" + name + \"[_i].\" + value + \" ;\"\n\n            return string\n\n    return \"%(0)s = %(1)s;\"\n\"\"\"\n"
  },
  {
    "path": "src/matlab2cpp/rules/vec.py",
    "content": "from .variables import *\nfrom . import armadillo as arma\n\ndef Get(node):\n\n    if len(node) != 1:\n\n        if not len(node):\n            node.error(\"Zero arguments in a vec call\")\n            return \"%(name)s()\"\n\n        elif len(node) == 2 and node[1].cls == \"Int\" and node[1].value == \"1\":\n            pass\n        #special case hh = h0F(:,ones(1,M)) with h0F vec, and ones\n        elif len(node) == 2 and node[0].name == \"ones\" or \\\n            node[1].name == \"ones\":\n            out = \"%(name)s(\"\n            if node[0].name == \"ones\":\n                out = out + \"%(0)s-1, \"\n                #return \"%(name)s(%(0)s-1, %(1)s)\"\n            else:\n                out = out + \"%(0)s, \"\n            if node[1].name == \"ones\":\n                out = out + \"%(1)s-1)\"\n                #return \"%(name)s(%(0)s, %(1)s-1)\"\n            else:\n                out = out + \"%(1)s)\"\n            return out\n            \n        else:\n            node.error(\"More than one arguments in a vec call\")\n            return \"%(name)s(\", \", \", \")\"\n\n    #if len(node) == 1:\n    arg, dim = arma.configure_arg(node[0], 0)\n\n    if dim == -1:\n        return \"%(name)s(\", \"-1, \", \"-1)\"\n\n    #if dim == 0:\n    #    node.dim = 0\n\n    return \"%(name)s(\" + arg + \")\"\n    \"\"\"\n    elif len(node) == 2:\n        arg0, dim0 = arma.configure_arg(node[0], 0)\n        arg1, dim1 = arma.configure_arg(node[1], 1)\n\n        if dim0 == -1:\n            return \"%(name)s(\", \"-1, \", \"-1)\"\n        elif dim1 == -1:\n            return \"%(name)s(\", \"-1, \", \"-1)\"\n\n        #if dim == 0:\n        #    node.dim = 0\n\n        return \"%(name)s(\" + arg0 + \", \" + arg1 + \")\"\n    \"\"\" \n\ndef Set(node):\n\n    if len(node) != 1:\n\n        if not len(node):\n            node.error(\"Zero arguments in a vec call\")\n            return \"%(name)s()\"\n\n        elif len(node) == 2 and node[1].cls == \"Int\" and node[1].value == \"1\":\n            pass\n\n        else:\n            node.error(\"More than one arguments in a vec call\")\n            return \"%(name)s(\", \"-1, \", \"-1)\"\n\n    arg, dim = arma.configure_arg(node[0], 0)\n\n    if dim == -1:\n        return \"%(name)s(\", \"-1, \", \"-1)\"\n\n    #if dim == 0:\n    #    node.dim = 0\n\n    return \"%(name)s(\" + arg + \")\"\n"
  },
  {
    "path": "src/matlab2cpp/setpaths.py",
    "content": "import os\nfrom . import tree\n\ndef multiple_folder_paths(setpath_file):\n    builder = tree.builder.Builder()\n\n    folder_paths = []\n\n    if os.path.isfile(setpath_file):\n        f = open(setpath_file, \"rU\")\n        code = f.read()\n        f.close()\n    else:\n        return folder_paths\n\n    builder.load(\"paths_file\", code)\n\n    builder.configure()\n\n    #Get code_block\n    code_block = builder.project[0][1][0][3]\n\n    #save variables that are assigned of type string\n    variables = {}\n    folder_paths = []\n\n    #each node in code_block is basically one line of code\n    for node in code_block:\n        #Assignments node\n        if node.cls == \"Assign\":\n            subnodes = node[1].flatten(ordered=False, reverse=False, inverse=False)\n\n            str_tmp = ''\n            for subnode in subnodes:\n                if subnode.cls == \"String\":\n                    str_tmp += subnode.value\n\n                elif subnode.cls == \"Var\" and subnode.type == \"string\":\n                    str_tmp += variables[subnode.name]\n\n            variables[node[0].name] = str_tmp\n\n        #Statement node\n        if node.cls == \"Statement\" and node[0].cls == \"Get\" and node[0].name in {\"path\", \"addpath\"}:\n            subnodes = node[0].flatten(ordered=False, reverse=False, inverse=False)\n\n            str_tmp = ''\n            for subnode in subnodes:\n                if subnode.cls == \"String\":\n                    str_tmp += subnode.value\n\n                if subnode.cls == \"Var\" and subnode.type == \"string\":\n                    str_tmp += variables[subnode.name]\n\n            folder_paths.append(str_tmp)\n\n    #remove separator if it is at the end of the string\n    folder_paths = [path.rstrip(os.path.sep) for path in folder_paths]\n    return folder_paths\n\n"
  },
  {
    "path": "src/matlab2cpp/supplement/__init__.py",
    "content": "\"\"\"\n\"\"\"\n\nPREFIX = \"\"\"# encoding: utf-8\n#\n# Supplement file\n#\n# Valid inputs:\n#\n# uword   int     float   double cx_double\n# uvec    ivec    fvec    vec    cx_vec\n# urowvec irowvec frowvec rowvec cx_rowvec\n# umat    imat    fmat    mat    cx_mat\n# ucube   icube   fcube   cube   cx_cube\n#\n# char    string  struct  structs func_lambda\n\"\"\"\n\nfrom .functions import Ftypes\nfrom .suggests import  Sstypes\nfrom .structs import Stypes\nfrom .includes import Itypes\nfrom .verbatim import Vtypes\n\n\ndef str_variables(types_f={}, types_s={}, types_i=[],\n        suggest={}, prefix=True, types_v={}):\n    \"\"\"\nConvert a nested dictionary for types, suggestions and structs and use them to\ncreate a suppliment text ready to be saved.\n\nKwargs:\n    types_f (dict): Function variables datatypes\n    types_s (dict): Struct variables datatypes\n    types_i (list): Includes in header\n    types_v (dict): Verbatim translations\n    suggest (dict): Suggested datatypes for types_f and types_s\n    prefix (bool): True if the type explaination should be included\n\nReturns: str\n    String representation of suppliment file\n\nExample:\n    >>> types_f = {\"f\" : {\"a\":\"int\"}, \"g\" : {\"b\":\"\"}}\n    >>> types_s = {\"c\" : {\"d\":\"\"}}\n    >>> types_i = [\"#include <armadillo>\"]\n    >>> suggest = {\"g\" : {\"b\":\"float\"}, \"c\" : {\"d\":\"vec\"}}\n    >>> print(str_variables(types_f, types_s, types_i, suggest, prefix=False))\n    functions = {\n      \"f\" : {\n        \"a\" : \"int\",\n      },\n      \"g\" : {\n        \"b\" : \"\", # float\n      },\n    }\n    structs = {\n      \"c\" : {\n        \"d\" : \"\", # vec\n      },\n    }\n    includes = [\n      '#include <armadillo>',\n    ]\n    \"\"\"\n\n    if prefix:\n        out = PREFIX\n    else:\n        out = \"\"\n\n    if types_f:\n\n        if prefix:\n            out += \"\\n\"\n\n        out += \"functions = {\\n\"\n\n        keys = sorted(types_f.keys())\n\n        for name in keys:\n\n\n            out += '  \"%s\" : {\\n' % (name)\n            types = types_f[name]\n\n            keys2 = sorted(types.keys())\n            l = max([len(k) for k in keys2]+[0])+4\n\n            for key in keys2:\n                val = types[key]\n                sug = suggest.get(name, {}).get(key, \"\")\n\n                if key[:1] == \"_\":\n                    continue\n\n                elif val:\n                    out += \" \"*(l-len(key)) + '\"%s\" : \"%s\",\\n' % (key, val)\n\n                elif sug:\n                    out += \" \"*(l-len(key)) + '\"%s\" : \"\", # %s\\n' % (key, sug)\n\n                else:\n                    out += \" \"*(l-len(key)) + '\"%s\" : \"\",\\n' % (key)\n\n            out += \"  },\\n\"\n\n        out += \"}\"\n\n    if types_s:\n\n        if types_f or prefix:\n            out += \"\\n\"\n\n        out += \"structs = {\\n\"\n\n        keys = sorted(types_s.keys())\n\n        for name in keys:\n\n            out += '  \"%s\" : {\\n' % (name)\n            types = types_s[name]\n\n            keys2 = sorted(types.keys())\n            l = max([len(k) for k in keys2])+4\n\n            for key in keys2:\n                val = types[key]\n                sug = suggest.get(name, {}).get(key, \"\")\n\n                if key[-5:] == \"_size\":\n                    val = val or 100\n                    out += \" \"*(l-len(key)) + '\"%s\" : %s,\\n' % (key, val)\n\n                elif val:\n                    out += \" \"*(l-len(key)) + '\"%s\" : \"%s\",\\n' % (key, val)\n\n                elif sug:\n                    out += \" \"*(l-len(key)) + '\"%s\" : \"\", # %s\\n' % (key, sug)\n\n                else:\n                    out += \" \"*(l-len(key)) + '\"%s\" : \"\",\\n' % (key)\n\n            out += \"  },\\n\"\n\n        out += \"}\"\n\n    if types_i:\n\n        if prefix or types_f or types_s:\n            out += \"\\n\"\n\n        out += \"includes = [\\n\"\n\n        for key in types_i:\n            if key:\n                out += \"  '\" + key + \"',\\n\"\n\n        out += \"]\"\n\n    if types_v:\n\n        if types_f or prefix or types_s or types_i:\n            out += \"\\n\"\n\n        out += \"verbatims = {\\n\"\n\n        keys = sorted(types_v.keys())\n        l = max([len(k) for k in keys])+2\n\n        for key in keys:\n            val = types_v[key]\n            if \"\\n\" in val:\n                out += \" \"*(l-len(key)) + '\"%s\" : \"\"\"%s\"\"\",\\n' % (key, val)\n            else:\n                out += \" \"*(l-len(key)) + '\"%s\" : \"%s\",\\n' % (key, val)\n\n        out += \"}\"\n\n    return out\n"
  },
  {
    "path": "src/matlab2cpp/supplement/functions.py",
    "content": "\"\"\"\n\"\"\"\n\ndef set(node, types):\n\n    funcs = node.program[1]    \n\n    # Functions\n    for name in types.keys():\n\n        if name in funcs.names:\n\n            types_ = types[name]\n            func = funcs[funcs.names.index(name)]\n            declares, returns, params = func[:3]\n\n            for key in types_.keys():\n\n                if key in declares.names:\n\n                    if key in returns.names:\n                        var = returns[returns.names.index(key)]\n                        var.type = types_[key]\n\n                    var = declares[declares.names.index(key)]\n                    var.type = types_[key]\n\n                elif key in params.names:\n                    var = params[params.names.index(key)]\n                    var.type = types_[key]\n\ndef get(node):\n\n    funcs = node.program[1]\n\n    types = {}\n\n    for func in funcs:\n\n        types[func.name] = types_ = {}\n\n        declares, params = func[0], func[2]\n        for var in declares[:]+params[:]:\n\n            type = var.type\n            if type == \"TYPE\":\n                type = \"\"\n            types_[var.name] = type\n\n            if not type:\n\n                type = var.prop[\"suggest\"]\n                if type == \"TYPE\":\n                    type = \"\"\n\n    return types\n\n\nclass Ftypes(object):\n    \"Access to function types from program node\"\n    def __get__(self, instance, owner):\n        return get(instance)\n    def __set__(self, instance, value):\n        set(instance, value)\n\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/supplement/includes.py",
    "content": "\"\"\"\n\"\"\"\nimport matlab2cpp\n\n\ndef set(node, types):\n\n    includes = node.program[0]\n\n    # Includes\n    for key in types:\n        #print(includes.names)\n\n        if key not in includes.names:\n            matlab2cpp.collection.Include(includes, key)\n\n\ndef get(node):\n\n    includes = node.program[0]\n\n    types_i = []\n    for include in includes:\n        types_i.append(include.name)\n\n    return types_i\n\n\ndef write_to_includes(include_string):\n    write = True\n    not_to_include = ['#include \"SPlot.h\"', '#include <tbb/tbb.h>', '#define NOMINMAX', 'include \"mconvert.h\"'] \n\n    if include_string in not_to_include:\n        write = False\n    return write\n\n\nclass Itypes(object):\n\n    def __get__(self, instance, owner):\n        return get(instance)\n\n    def __set__(self, instance, value):\n        set(instance, value)\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/supplement/structs.py",
    "content": "\"\"\"\n\"\"\"\n\n\ndef set(node, types):\n    from .. import collection\n\n    structs = node.program[3]\n\n    # Structs\n    for name in types.keys():\n\n        if name in structs.names:\n\n            types_ = types[name]\n            struct = structs[structs.names.index(name)]\n\n            for key in types_.keys():\n\n                if key in struct.names:\n\n                    var = struct[struct.names.index(key)]\n\n                    if var.cls == \"Counter\":\n                        var.value = str(types_[key])\n                    else:\n                        var.type = types_[key]\n\n                else:\n                    var = collection.Declare(\n                        struct, key, backend=\"struct\", type=types_[key])\n\n\ndef get(node):\n\n    structs = node.program[3]\n    types_s = {}\n    for struct in structs:\n\n        types_s[struct.prop[\"name\"]] = types = {}\n\n        for var in struct:\n\n            type = var.prop[\"type\"]\n            if type == \"TYPE\":\n                type = \"\"\n\n            if type == \"structs\":\n                type = var.prop[\"value\"]\n\n            types[var.name] = type\n\n    return types_s\n\n\nclass Stypes(object):\n\n    def __get__(self, instance, owner):\n        return get(instance)\n\n    def __set__(self, instance, value):\n        set(instance, value)\n"
  },
  {
    "path": "src/matlab2cpp/supplement/suggests.py",
    "content": "def get(node):\n\n    funcs = node.program[1]\n    structs = node.program[3]\n\n    suggest = {}\n\n    for func in funcs:\n\n        suggest[func.name] = suggest_ = {}\n\n        declares, params = func[0], func[2]\n        for var in declares[:]+params[:]:\n\n            type = var.prop[\"type\"]\n            if type == \"TYPE\":\n                type = \"\"\n\n            if not type:\n\n                type = var.prop[\"suggest\"]\n                if type == \"TYPE\":\n                    type = \"\"\n                if type:\n                    suggest_[var.name] = type\n\n    for struct in structs:\n\n        suggest[struct.name] = suggest_ = {}\n\n        for var in struct:\n\n            type = var.prop[\"type\"]\n            if type == \"TYPE\":\n                type = \"\"\n\n            if not type:\n\n                type = var.prop[\"suggest\"]\n                if type == \"TYPE\":\n                    type = \"\"\n                if type:\n                    suggest_[var.name] = type\n\n    return suggest\n\nclass Sstypes(object):\n\n    def __get__(self, instance, owner):\n        return get(instance)\n\n    def __set__(self, instance, value):\n        raise AttributeError(\"Suggestions not to be set manually\")\n"
  },
  {
    "path": "src/matlab2cpp/supplement/verbatim.py",
    "content": "import re\nset_ = set\n\ndef set(D, code):\n\n    for key, value in D.items():\n\n        findterm = r'.*' + re.escape(key) + r'.*'\n        keys = set_(re.findall(findterm, code))\n\n        value = '___' + value.replace('\\n', '___')\n        value = value.replace('\\\\', '//')\n\n        for key_ in keys:\n            findterm_ = re.escape(key_)\n            value_ = \"___\" + key_ + value\n            code = re.sub(findterm_, value_, code)\n\n    return code\n\n\n#find nodes that contain verbatim\ndef get(node):\n    nodes = node.flatten()\n\n    D = {}\n    for node in nodes:\n        if node.cls == \"Verbatim\":\n            D[node.name] = node.value\n\n    return D\n\n\nclass Vtypes(object):\n\n    def __get__(self, instance, owner):\n        return get(instance)\n"
  },
  {
    "path": "src/matlab2cpp/tree/__init__.py",
    "content": "\"\"\"\nParsing of Matlab code is solely done through the\n:py:class:`~matlab2cpp.Builder` class. It contains three main use methods:\n:py:func:`~matlab2cpp.Builder.load`, :py:func:`~matlab2cpp.Builder.configure`\nand :py:func:`~matlab2cpp.Builder.translate`. In addition there are\na collection of method with names starting with ``create_`` that creates\nvarious structures of the node tree.\n\nIn addition to :py:class:`~matlab2cpp.Builder` there are submodules with\nsupport function for modules. Constructor help functions are as follows:\n\n+--------------------------------------+--------------------------------------+\n| Module                               | Description                          |\n+======================================+======================================+\n| :py:mod:`matlab2cpp.tree.assign`     | Support functions for variable       |\n|                                      | assignments                          |\n+--------------------------------------+--------------------------------------+\n| :py:mod:`matlab2cpp.tree.branches`   | Support functions for if-tests,      |\n|                                      | loops, try-blocks                    |\n+--------------------------------------+--------------------------------------+\n| :py:mod:`matlab2cpp.tree.codeblock`  | Support functions for filling in     |\n|                                      | codeblock content                    |\n+--------------------------------------+--------------------------------------+\n| :py:mod:`matlab2cpp.tree.expression` | Support functions for filling in     |\n|                                      | expression content                   |\n+--------------------------------------+--------------------------------------+\n| :py:mod:`matlab2cpp.tree.functions`  | Support functions for constructing   |\n|                                      | Functions, both explicit and lambda, |\n|                                      | and program content                  |\n+--------------------------------------+--------------------------------------+\n| :py:mod:`matlab2cpp.tree.misc`       | Miscelenious support functions       |\n+--------------------------------------+--------------------------------------+\n| :py:mod:`matlab2cpp.tree.variables`  | Support functions for constructing   |\n|                                      | various variables                    |\n+--------------------------------------+--------------------------------------+\n\nIn addition a collectio of genereal purpose modules are available:\n\n+-------------------------------------+---------------------------------------+\n| Module                              | Description                           |\n+=====================================+=======================================+\n| :py:mod:`matlab2cpp.tree.constants` | A collection of usefull constants     |\n|                                     | used by various interpretation  rules |\n+-------------------------------------+---------------------------------------+\n| :py:mod:`matlab2cpp.tree.findend`   | Look-ahead functions for finding the  |\n|                                     | end of various code structures        |\n+-------------------------------------+---------------------------------------+\n| :py:mod:`matlab2cpp.tree.identify`  | Look-ahead functions for identifying  |\n|                                     | ambigous contexts                     |\n+-------------------------------------+---------------------------------------+\n| :py:mod:`matlab2cpp.tree.iterate`   | Support functions for segmentation of |\n|                                     | lists                                 |\n+-------------------------------------+---------------------------------------+\n\"\"\"\nfrom .builder import Builder\n__all__ = (\"Builder\",)\n"
  },
  {
    "path": "src/matlab2cpp/tree/assign.py",
    "content": "\"\"\"\nSupport functions for identifying assignments.\n\n+-------------------------------------------+----------------------------------+\n| Function                                  | Description                      |\n+===========================================+==================================+\n| :py:func:`~matlab2cpp.tree.assign.single` | Assignment with single return    |\n+-------------------------------------------+----------------------------------+\n| :py:func:`~matlab2cpp.tree.assign.multi`  | Assignment with multiple returns |\n+-------------------------------------------+----------------------------------+\n\"\"\"\nfrom __future__ import print_function\nfrom .. import collection\n\nfrom . import findend, constants as c, identify, iterate\n\n\ndef multi(self, parent, cur, eq_loc):\n    \"\"\"\nAssignment with multiple return\n\nArgs:\n    self (Builder): Code constructor.\n    parent (Node): Parent node\n    cur (int): Current position in code\n    eq_loc (int): position of the assignment marker ('='-sign)\n\nReturns:\n\tint: Index to end of assignment\n\nExample:\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder(True)\n    >>> builder.load(\"unnamed\", \"[a,b] = c\") # doctest: +NORMALIZE_WHITESPACE\n    loading unnamed\n         Program     functions.program\n       0 Main        functions.main\n       0 Codeblock   codeblock.codeblock \n       0   Assigns     assign.multi         '[a,b] = c'\n       1     Var         variables.assign     'a'\n       3     Var         variables.assign     'b'\n       8     Expression  expression.create    'c'\n       8     Var         variables.variable   'c'\n    >>> builder.configure()\n    >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n     1  1Block      code_block   TYPE\n     1  1| Assigns    unknown      TYPE    c\n     1  2| | Var        unknown      TYPE    a\n     1  4| | Var        unknown      TYPE    b\n     1  9| | Var        unknown      TYPE    c\n    \"\"\"\n\n    if  self.code[cur] != \"[\":\n        self.syntaxerror(cur, \"multi-assign start\")\n    if  self.code[eq_loc] != \"=\":\n        self.syntaxerror(cur, \"assignment sign (=)\")\n\n    j = eq_loc+1\n    while self.code[j] in \" \\t.\":\n        if self.code[j] == \".\":\n            j = findend.dots(self, j)+1\n        else:\n            j += 1\n    end = findend.expression(self, j)\n\n    if self.disp:\n        print(\"%4d   Assigns    \" % cur, end=\" \")\n        print(\"%-20s\" % \"assign.multi\", end=\" \")\n        print(repr(self.code[cur:end+1]))\n\n    if identify.space_delimited(self, cur):\n        l = iterate.space_list(self, cur)\n    else:\n        l = iterate.comma_list(self, cur)\n\n    if len(l[0]) == 1:\n        return self.create_assign(parent, l[0][0][0], eq_loc)\n\n    assigns = collection.Assigns(parent, cur=cur, code=self.code[cur:end+1])\n\n    for vector in l:\n        for start, stop in vector:\n            self.create_assign_variable(assigns, start, end=stop)\n\n    cur = eq_loc + 1\n    while self.code[cur] in \" \\t\":\n        cur += 1\n\n    cur_ =  self.create_expression(assigns, cur)\n\n    assigns.name = assigns[-1].name\n\n    return cur_\n\n\ndef single(self, parent, cur, eq_loc):\n    \"\"\"\nAssignment with single return.\n\nArgs:\n    self (Builder): Code constructor\n    parent (Node): Parent node\n    cur (int): Current position in code\n    eq_loc (int): position of the assignment marker ('='-sign)\n\nReturns:\n\tint: Index to end of assignment\n\nExample:\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder(True)\n    >>> builder.load(\"unnamed\", \"a=b\") # doctest: +NORMALIZE_WHITESPACE\n    loading unnamed\n         Program     functions.program\n       0 Main        functions.main\n       0 Codeblock   codeblock.codeblock \n       0   Assign      assign.single        'a=b'\n       0     Var         variables.assign     'a'\n       2     Expression  expression.create    'b'\n       2     Var         variables.variable   'b'\n    >>> builder.configure()\n    >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n    1 1Block      code_block   TYPE\n    1 1| Assign     unknown      TYPE    b\n    1 1| | Var        unknown      TYPE    a\n    1 3| | Var        unknown      TYPE    b\n    \"\"\"\n\n    if  self.code[cur] not in c.letters:\n        self.syntaxerror(cur, \"assignment start\")\n    if  self.code[eq_loc] != \"=\":\n        self.syntaxerror(cur, \"assignment indicator (=)\")\n\n    j = eq_loc+1\n    while self.code[j] in \" \\t\":\n        j += 1\n    end = findend.expression(self, j)\n\n    if self.disp:\n        print(\"%4d   Assign     \" % cur, end=\"\")\n        print(\"%-20s\" % \"assign.single\", end=\"\")\n        print(repr(self.code[cur:end+1]))\n\n    assign = collection.Assign(parent, cur=cur, code=self.code[cur:end+1])\n\n    cur = self.create_assign_variable(assign, cur, eq_loc)\n\n    cur += 1\n    while self.code[cur] in \" \\t\":\n        cur += 1\n\n    if self.code[cur] == \"]\":\n        cur += 1\n        while self.code[cur] in \" \\t\":\n            cur += 1\n\n    if  self.code[cur] != \"=\":\n        self.syntaxerror(cur, \"assignment indicator (=)\")\n\n    k = cur+1\n    while self.code[k] in \" \\t\":\n        k += 1\n\n    self.create_expression(assign, k, end)\n    assign.name = assign[-1].name\n\n    if  len(assign) != 2:\n        self.syntaxerror(k, \"single assign when multi-assign\")\n\n    return end\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/tree/branches.py",
    "content": "\"\"\"\nIterpretors related to branches, loops and try.\n\n+------------------------------------------------+-----------------------+\n| Function                                       | Description           |\n+================================================+=======================+\n| :py:func:`~matlab2cpp.tree.branches.trybranch` | Try-catch block       |\n+------------------------------------------------+-----------------------+\n| :py:func:`~matlab2cpp.tree.branches.switch`    | Switch-case branch    |\n+------------------------------------------------+-----------------------+\n| :py:func:`~matlab2cpp.tree.branches.whileloop` | While loop            |\n+------------------------------------------------+-----------------------+\n| :py:func:`~matlab2cpp.tree.branches.forloop`   | For loop              |\n+------------------------------------------------+-----------------------+\n| :py:func:`~matlab2cpp.tree.branches.ifbranch`  | If-ifelse-else branch |\n+------------------------------------------------+-----------------------+\n\"\"\"\nfrom __future__ import print_function\nimport matlab2cpp\n\nfrom . import constants as c, findend\n\n\ndef trybranch(self, parent, cur):\n    '''\nTry-catch block\n\nArgs:\n    self (Builder): Code constructor.\n    parent (Node): Parent node\n    cur (int): Current position in code\n\nReturns:\n\tint: Index to end of block\n\nExample:\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder(True)\n    >>> builder.load(\"unnamed\",\n    ... \"\"\"try\n    ...   a\n    ... catch\n    ...   b\"\"\") # doctest: +NORMALIZE_WHITESPACE\n    loading unnamed\n         Program     functions.program\n       0 Main        functions.main\n       0 Codeblock   codeblock.codeblock \n       0   Try           branches.trybranch   'try'\n       6 Codeblock   codeblock.codeblock \n       6   Statement     codeblock.codeblock  'a'\n       6     Expression  expression.create    'a'\n       6     Var         variables.variable   'a'\n      16 Codeblock   codeblock.codeblock \n      16   Statement     codeblock.codeblock  'b'\n      16     Expression  expression.create    'b'\n      16     Var         variables.variable   'b'\n    >>> builder.configure()\n    >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n    1  1Block      code_block   TYPE\n    1  1| Tryblock   code_block   TYPE\n    1  1| | Try        code_block   TYPE\n    2  7| | | Block      code_block   TYPE\n    2  7| | | | Statement  code_block   TYPE\n    2  7| | | | | Var        unknown      TYPE    a\n    3  9| | Catch      code_block   TYPE\n    4 17| | | Block      code_block   TYPE\n    4 17| | | | Statement  code_block   TYPE\n    4 17| | | | | Var        unknown      TYPE    b\n    '''\n\n    if  self.code[cur:cur+3] != \"try\" or self.code[cur+3] not in c.k_end:\n        self.syntaxerror(cur, \"start of try-block\")\n\n    if self.disp:\n        print(\"%4d   Try          \" % cur, end=\"\")\n        print(\"%-20s\" % \"branches.trybranch\", end=\"\")\n        print(repr(self.code[cur:cur+3]))\n\n    start = cur\n\n    tryblock = matlab2cpp.collection.Tryblock(parent, cur=cur)\n\n    trybranch = matlab2cpp.collection.Try(tryblock)\n\n    cur += 3\n    while self.code[cur] in \" \\t\\n,;\":\n        cur += 1\n\n    cur = self.create_codeblock(trybranch, cur)\n\n    trybranch.code = self.code[start:cur]\n\n    if  self.code[cur:cur+5] != \"catch\" or self.code[cur+5] not in c.k_end:\n        self.syntaxerror(cur, \"start of catch-block\")\n\n    catch_ = matlab2cpp.collection.Catch(tryblock, cur=cur)\n\n    start_ = cur\n    cur += 5\n    while self.code[cur] in \" \\t\\n,;\":\n        cur += 1\n\n    cur = self.create_codeblock(catch_, cur)\n\n    catch_.code = self.code[start_:cur]\n    tryblock.code = self.code[start:cur]\n\n    return cur\n\n\ndef switch(self, parent, cur):\n    '''\nSwitch-case branch\n\nArgs:\n    self (Builder): Code constructor.\n    parent (Node): Parent node\n    cur (int): Current position in code\n\nReturns:\n\tint: Index to end of codeblock\n\nExample:\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder(True)\n    >>> builder.load(\"unnamed\",\n    ... \"\"\"switch a\n    ... case b\n    ...   c\n    ... case d\n    ...   d\n    ... end\"\"\") # doctest: +NORMALIZE_WHITESPACE\n    loading unnamed\n         Program     functions.program\n       0 Main        functions.main\n       0 Codeblock   codeblock.codeblock \n       0   Switch        branches.switch      'switch a'\n       7     Expression  expression.create    'a'\n       7     Var         variables.variable   'a'\n       9   Case          branches.switch      'case b'\n      14     Expression  expression.create    'b'\n      14     Var         variables.variable   'b'\n      18 Codeblock   codeblock.codeblock \n      18   Statement     codeblock.codeblock  'c'\n      18     Expression  expression.create    'c'\n      18     Var         variables.variable   'c'\n      20   Case          branches.switch      'case d'\n      25     Expression  expression.create    'd'\n      25     Var         variables.variable   'd'\n      29 Codeblock   codeblock.codeblock \n      29   Statement     codeblock.codeblock  'd'\n      29     Expression  expression.create    'd'\n      29     Var         variables.variable   'd'\n    >>> builder.configure()\n    >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n    1  1Block      code_block   TYPE\n    1  1| Switch     code_block   TYPE\n    1  8| | Var        unknown      TYPE    a\n    2 10| | Case       code_block   TYPE\n    2 15| | | Var        unknown      TYPE    b\n    3 19| | | Block      code_block   TYPE\n    3 19| | | | Statement  code_block   TYPE\n    3 19| | | | | Var        unknown      TYPE    c\n    4 21| | Case       code_block   TYPE\n    4 26| | | Var        unknown      TYPE    d\n    5 30| | | Block      code_block   TYPE\n    5 30| | | | Statement  code_block   TYPE\n    5 30| | | | | Var        unknown      TYPE    d\n    '''\n\n    if not (self.code[cur:cur+6] == \"switch\" and\\\n            self.code[cur+6] in \" \\t(\"):\n        self.syntaxerror(cur, \"start of switch branch\")\n\n    k = cur+6\n    while self.code[k] in \" \\t\":\n        k += 1\n\n    end = findend.expression(self, k)\n\n    if self.disp:\n        print(\"%4d   Switch       \" % cur, end=\"\")\n        print(\"%-20s\" % \"branches.switch\", end=\"\")\n        print(repr(self.code[cur:end+1]))\n\n    switch = matlab2cpp.collection.Switch(parent, cur=cur)\n\n    self.create_expression(switch, k, end)\n\n    k = end+1\n\n    while self.code[k] in \" \\t\\n;,\":\n        k += 1\n\n    while self.code[k:k+4] == \"case\" and self.code[k+4] in \" \\t(\":\n\n        cur = k\n\n        k += 4\n        while self.code[k] in \" \\t\":\n            k += 1\n\n        end = findend.expression(self, k)\n\n        if self.disp:\n            print(\"%4d   Case         \" % cur, end=\"\")\n            print(\"%-20s\" % \"branches.switch\", end=\"\")\n            print(repr(self.code[cur:end+1]))\n\n        case = matlab2cpp.collection.Case(switch, cur=cur)\n\n        cur = self.create_expression(case, k, end)\n\n        k = cur+1\n        while self.code[k] in \" \\t;,\\n\":\n            k += 1\n\n        k = self.create_codeblock(case, k)\n\n    if self.code[k:k+9] == \"otherwise\" and self.code[k+9] in \" \\t(,;\\n\":\n\n        cur = k\n\n        if self.disp:\n            print(\"%4d   Otherwise    \" % cur, end=\"\")\n            print(\"%-20s\" % \"branches.switch\", end=\"\")\n            print(repr(self.code[cur:cur+10]))\n\n        otherwise = matlab2cpp.collection.Otherwise(switch, cur=cur)\n\n        k += 9\n        while self.code[k] in \" \\t\\n;,\":\n            k += 1\n\n        k = self.create_codeblock(otherwise, k)\n\n    return k\n\n\ndef whileloop(self, parent, cur):\n    '''\nWhile loop\n\nArgs:\n    self (Builder): Code constructor.\n    parent (Node): Parent node\n    cur (int): Current position in code\n\nReturns:\n\tint: Index to end of code block\n\nExample:\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder(True)\n    >>> builder.load(\"unnamed\",\n    ... \"\"\"while a\n    ...   b\n    ... end\"\"\") # doctest: +NORMALIZE_WHITESPACE\n    loading unnamed\n         Program     functions.program\n       0 Main        functions.main\n       0 Codeblock   codeblock.codeblock \n       0   While         branches.whileloop   'while a'\n       6     Expression  expression.create    'a'\n       6     Var         variables.variable   'a'\n      10 Codeblock   codeblock.codeblock \n      10   Statement     codeblock.codeblock  'b'\n      10     Expression  expression.create    'b'\n      10     Var         variables.variable   'b'\n    >>> builder.configure()\n    >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n    1  1Block      code_block   TYPE\n    1  1| While      code_block   TYPE\n    1  7| | Var        unknown      TYPE    a\n    2 11| | Block      code_block   TYPE\n    2 11| | | Statement  code_block   TYPE\n    2 11| | | | Var        unknown      TYPE    b\n    '''\n\n    if  self.code[cur:cur+5] != \"while\" and self.code[cur+5] not in c.k_end:\n        self.syntaxerror(cur, \"start of while-loop\")\n    start = cur\n\n    k = cur+5\n    while self.code[k] in \" \\t\":\n        k += 1\n\n    end = findend.expression(self, k)\n\n    if self.disp:\n        print(\"%4d   While        \" % cur, end=\"\")\n        print(\"%-20s\" % \"branches.whileloop\", end=\"\")\n        print(repr(self.code[cur:end+1]))\n\n    whileloop = matlab2cpp.collection.While(parent, cur=cur, code=self.code[cur:end+1])\n\n    if self.code[k] == \"(\":\n        k += 1\n        while self.code[k] in \" \\t\":\n            k += 1\n\n    cur = self.create_expression(whileloop, k)\n    cur += 1\n\n    cur += 1\n    while self.code[cur] in \" \\t\":\n        cur += 1\n\n    end = self.create_codeblock(whileloop, cur)\n\n    #whileloop.code = self.code[start:end+1]\n\n    return end\n\ndef parforloop(self, parent, cur):\n    if  self.code[cur:cur+6] != \"parfor\":\n        self.syntaxerror(cur, \"parfor loop start\")\n\n    start = cur\n\n    if self.disp:\n        print(\"%4d   Parfor          \" % cur, end=\"\")\n        print(repr(self.code[cur:self.code.find(\"\\n\", cur)]), end=\"\")\n        print(\"branches.parforloop\")\n\n    parfor_loop = matlab2cpp.collection.Parfor(parent, cur=cur, code=self.code[cur:self.code.find(\"\\n\", cur)])\n\n    cur = cur+6\n    while self.code[cur] in \"( \\t\":\n        cur += 1\n\n    cur = self.create_variable(parfor_loop, cur)\n\n    if parfor_loop.project.builder.enable_tbb:\n        parfor_loop[0].type = \"uword\"\n\n    else:\n        parfor_loop[0].create_declare()\n        parfor_loop[0].suggest = \"int\"\n\n    cur += 1\n    while self.code[cur] in \" \\t\":\n        cur += 1\n\n    if self.code[cur] != \"=\":\n        self.syntaxerror(cur, \"for-loop assignment (=)\")\n    cur += 1\n\n    while self.code[cur] in \" \\t\":\n        cur += 1\n\n    cur = self.create_expression(parfor_loop, cur)\n    cur += 1\n\n    while self.code[cur] in \") \\t\":\n        cur += 1\n\n    if self.code[cur] == \",\":\n        cur += 1\n\n    while self.code[cur] in \" \\t\\n;\":\n        cur += 1\n    end = self.create_codeblock(parfor_loop, cur)\n\n    #parfor_loop.code = self.code[start:end]\n\n    return end\n\ndef forloop(self, parent, cur):\n    '''\nFor loop\n\nArgs:\n    self (Builder): Code constructor.\n    parent (Node): Parent node\n    cur (int): Current position in code\n\nReturns:\n\tint: Index to end of code block\n\nExample:\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder(True)\n    >>> builder.load(\"unnamed\",\n    ... \"\"\"for a = b\n    ...   c\n    ... end\"\"\") # doctest: +NORMALIZE_WHITESPACE\n    loading unnamed\n         Program    functions.program\n       0 Main       functions.main\n       0 Codeblock  codeblock.codeblock\n       0   For          'for a = b' branches.forloop\n       4     Var        variables.variable  'a'\n       8     Expression expression.create   'b'\n       8     Var        variables.variable  'b'\n      12 Codeblock  codeblock.codeblock\n      12   Statement    codeblock.codeblock 'c'\n      12     Expression expression.create   'c'\n      12     Var        variables.variable  'c'\n    >>> builder.configure(suggest=False)\n    >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n    1  1Block      code_block   TYPE\n    1  1| For        code_block   TYPE\n    1  5| | Var        unknown      (int)   a\n    1  9| | Var        unknown      TYPE    b\n    2 13| | Block      code_block   TYPE\n    2 13| | | Statement  code_block   TYPE\n    2 13| | | | Var        unknown      TYPE    c\n    '''\n\n    if  self.code[cur:cur+3] != \"for\":\n        self.syntaxerror(cur, \"for loop start\")\n\n    start = cur\n\n    if self.disp:\n        print(\"%4d   For          \" % cur, end=\" \")\n        print(repr(self.code[cur:self.code.find(\"\\n\", cur)]), end=\" \")\n        print(\"branches.forloop\")\n\n    for_loop = matlab2cpp.collection.For(parent, cur=cur, code=self.code[cur:self.code.find(\"\\n\", cur)])\n\n    cur = cur+3\n    while self.code[cur] in \"( \\t\":\n        cur += 1\n\n    cur = self.create_variable(for_loop, cur)\n\n    index = for_loop.parent.children.index(for_loop)\n    tbb = for_loop.parent.children[index - 1].cls\n    if tbb == \"Tbb_for\":\n        for_loop[0].create_declare()\n        for_loop[0].suggest = \"uword\"\n\n    else:\n        for_loop[0].create_declare()\n        for_loop[0].suggest = \"int\"\n\n\n    cur += 1\n    while self.code[cur] in \" \\t\":\n        cur += 1\n\n    if self.code[cur] != \"=\":\n        self.syntaxerror(cur, \"for-loop assignment (=)\")\n    cur += 1\n\n    while self.code[cur] in \" \\t\":\n        cur += 1\n\n    cur = self.create_expression(for_loop, cur)\n    cur += 1\n\n    while self.code[cur] in \") \\t\":\n        cur += 1\n\n    if self.code[cur] == \",\":\n        cur += 1\n\n    while self.code[cur] in \" \\t\\n;\":\n        cur += 1\n\n    end = self.create_codeblock(for_loop, cur)\n\n    #for_loop.code = self.code[start:end]\n\n    return end\n\n\ndef ifbranch(self, parent, start):\n    '''\nIf-ifelse-else branch\n\nArgs:\n    self (Builder): Code constructor.\n    parent (Node): Parent node\n    cur (int): Current position in code\n\nReturns:\n\tint: Index to end of code block\n\nExample:\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder(True)\n    >>> builder.load(\"unnamed\",\n    ... \"\"\"if a\n    ...   b\n    ... elseif c\n    ...   d\n    ... end\"\"\") # doctest: +NORMALIZE_WHITESPACE\n    loading unnamed\n         Program     functions.program\n       0 Main        functions.main\n       0 Codeblock   codeblock.codeblock \n       0   If            branches.ifbranch    'if a'\n       3     Expression  expression.create    'a'\n       3     Var         variables.variable   'a'\n       4 Codeblock   codeblock.codeblock \n       7   Statement     codeblock.codeblock  'b'\n       7     Expression  expression.create    'b'\n       7     Var         variables.variable   'b'\n       9   Else if       branches.ifbranch    'elseif c'\n      16     Expression  expression.create    'c'\n      16     Var         variables.variable   'c'\n      17 Codeblock   codeblock.codeblock \n      20   Statement     codeblock.codeblock  'd'\n      20     Expression  expression.create    'd'\n      20     Var         variables.variable   'd'\n    >>> builder.configure()\n    >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n    1  1Block      code_block   TYPE\n    1  1| Branch     code_block   TYPE\n    1  4| | If         code_block   TYPE\n    1  4| | | Var        unknown      TYPE    a\n    1  5| | | Block      code_block   TYPE\n    2  8| | | | Statement  code_block   TYPE\n    2  8| | | | | Var        unknown      TYPE    b\n    3 10| | Elif       code_block   TYPE\n    3 17| | | Var        unknown      TYPE    c\n    3 18| | | Block      code_block   TYPE\n    4 21| | | | Statement  code_block   TYPE\n    4 21| | | | | Var        unknown      TYPE    d\n    '''\n\n    if  self.code[start:start+2] != \"if\" or self.code[start+2] not in c.k_end:\n        self.syntaxerror(start, \"if branch start\")\n\n    branch = matlab2cpp.collection.Branch(parent, cur=start)\n\n    cur = start\n\n    cur += 2\n    while self.code[cur] in \" \\t\":\n        cur += 1\n\n    if  self.code[cur] not in c.e_start:\n        self.syntaxerror(cur, \"expression start\")\n\n    end = findend.expression(self, cur)\n\n    if self.disp:\n        print(\"%4d   If           \" % (start), end=\"\")\n        print(\"%-20s\" % \"branches.ifbranch\", end=\"\")\n        print(repr(self.code[start:end+1]))\n\n    node = matlab2cpp.collection.If(branch, cur=cur, code=self.code[start:end+1])\n\n    # this code below gives error if the if statement is: if (a > 1) && (a < 6)\n    #because it digs down recursevly in (a > 1) and not the whole statement\n    #if self.code[cur] == \"(\":\n    #    cur += 1\n    #    while self.code[cur] in \" \\t\":\n    #        cur += 1\n    self.create_expression(node, cur)\n\n    cur = end+1\n\n    end = self.create_codeblock(node, cur)\n    #node.code = self.code[cur:end]\n    cur = end\n\n    while self.code[cur:cur+6] == \"elseif\" and self.code[cur+6] in c.k_end:\n\n        #node.code = self.code[start:cur]\n        start = cur\n\n        cur += 6\n        while self.code[cur] in \" \\t\":\n            cur += 1\n\n        end = findend.expression(self, cur)\n\n        if self.disp:\n            print(\"%4d   Else if      \" % (start), end=\"\")\n            print(\"%-20s\" % \"branches.ifbranch\", end=\"\")\n            print(repr(self.code[start:end+1]))\n\n        node = matlab2cpp.collection.Elif(branch, cur=start, code=self.code[start:end+1])\n\n        #if self.code[cur] == \"(\":\n        #    cur += 1\n        #    while self.code[cur] in \" \\t\":\n        #        cur += 1\n\n        self.create_expression(node, cur)\n        cur = end+1\n\n        cur = end = self.create_codeblock(node, cur)\n\n\n    cur = end\n    #node.code = self.code[start:cur]\n\n    if self.code[cur:cur+4] == \"else\" and self.code[cur+4] in c.k_end:\n\n        start = cur\n\n        cur += 4\n\n        if self.disp:\n            print(\"%4d   Else         \" % (start), end=\"\")\n            print(\"%-20s\" % \"branches.ifbranch\", end=\"\")\n            print(repr(self.code[start:start+5]))\n\n        node = matlab2cpp.collection.Else(branch, cur=start)\n\n        end = self.create_codeblock(node, cur)\n        #node.code = self.code[start:end+1]\n\n    branch.code = self.code[start:end+1]\n\n    return end\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/tree/builder.py",
    "content": "from __future__ import print_function\nfrom .. import collection, rules, configure\n\n\nclass Builder(object):\n    \"\"\"\nConvert Matlab-code to a tree of nodes.\n\nGiven that one or more Matlab programs are loaded, each one can be accessed\nthrough indexing the Builder instance. For example::\n\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder()\n    >>> builder.load(\"prg1.m\", \"function y=prg1(x); y=x\")\n    >>> builder.load(\"prg2.m\", \"prg1(4)\")\n    >>> builder.configure(suggest=True)\n    >>> builder.translate()\n    >>> prg1, prg2 = builder\n    >>> print(prg1.cls, prg1.name)\n    Program prg1.m\n    >>> print(prg2.cls, prg2.name)\n    Program prg2.m\n\nPrograms that are loaded, configured and translated, can be converted into C++\ncode through the front end functions in :py:mod:`matlab2cpp.qfunctions`::\n\n    >>> print(matlab2cpp.qhpp(prg1))\n    #ifndef PRG1_M_HPP\n    #define PRG1_M_HPP\n    <BLANKLINE>\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    int prg1(int x)\n    {\n      int y ;\n      y = x ;\n      return y ;\n    }\n    #endif\n    >>> print(matlab2cpp.qcpp(prg2))\n    #include <armadillo>\n    using namespace arma ;\n    <BLANKLINE>\n    int main(int argc, char** argv)\n    {\n      prg1(4) ;\n      return 0 ;\n    }\n    \"\"\"\n\n    def __init__(self, disp=False, comments=True, original=False, enable_omp=False, enable_tbb=False,\n                 reference=False, **kws):\n        \"\"\"\nArgs:\n    disp (bool):\n        Verbose output while loading code\n    comments (bool):\n        Include comments in the code interpretation\n    **kws: \n        Optional arguments are passed to :py:mod:`matlab2cpp.rules`\n        \"\"\"\n\n        self.disp = disp\n        self.comments = comments\n        self.original = original\n        self.project = collection.Project()\n        self.project.kws = kws\n        self.project.builder = self\n        self.enable_omp = enable_omp\n        self.enable_tbb = enable_tbb\n        self.reference = reference\n        self.configured = False\n\n\n    def __getitem__(self, index):\n        \"\"\"\nGet root node for a program through indexing\n\nbuilder[index] <=> Builder.__getitem__(builder, index)\n\n\nArgs:\n    index (int): Loaded order\n\nExample:\n\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder()\n    >>> builder.load(\"prg1.m\", \"function y=prg1(x); y=x\")\n    >>> builder.load(\"prg2.m\", \"prg1(4)\")\n    >>> prg1 = builder[0]\n    >>> prg2 = builder[1]\n        \"\"\"\n        return self.project[index]\n\n    def __str__(self):\n        \"\"\"\nSummary of all node trees\n\nSame as :py:func:`matlab2cpp.Node.summary`, but for the whole project.\n\nstr(builder) <=> Builder.__str__(builder)\n\nExample:\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder()\n    >>> print(builder) # doctest: +NORMALIZE_WHITESPACE\n         Project    unknown      TYPE\n\nSee also:\n    :py:func:`matlab2cpp.Node.summary`\n        \"\"\"\n        return self.project.summary()\n\n\n    def load(self, name, code):\n        \"\"\"\nLoad a Matlab code into the node tree.\n\nThe code is inserted into the attribute `self.code` and initiate the\n:py:func:`matlab2cpp.Builder.create_program`, which evoces various other\n``create_*`` methods. Each method creates nodes and/or pushes the job over to\nother create methods.\n\nArgs:\n    name (str): Name of program (usually valid filename).\n    code (str): Matlab code to be loaded\n\nRaises:\n    SyntaxError: Error in the Matlab code.\n\nExample::\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder()\n    >>> builder.load(\"unnamed.m\", \"\")\n    >>> print(builder) # doctest: +NORMALIZE_WHITESPACE\n         Project    unknown      TYPE\n         | Program    unknown      TYPE    unnamed.m\n         | | Includes   unknown      TYPE\n     1  1| | Funcs      unknown      TYPE    unnamed.m\n         | | Inlines    unknown      TYPE    unnamed.m\n         | | Structs    unknown      TYPE    unnamed.m\n         | | Headers    unknown      TYPE    unnamed.m\n         | | Log        unknown      TYPE    unnamed.m\n        \"\"\"\n        assert isinstance(name, str)\n        assert isinstance(code, str)\n\n        if self.disp:\n            print(\"loading\", name)\n\n        #Replace ... [stuff] \\n with ... [stuff] \\n \" \"\n        l = 0\n        while l != -1:  #str.find returns -1 if not found\n            l = code.find(\"...\", l)\n            if l != -1:\n                m = code.find(\"\\n\", l)\n                if m != -1:\n                    #m = m+1\n                    code = code[:m+1] + \" \" + code[m+1:]\n                l = m\n\n        self.code = code + \"\\n\\n\\n\"\n        self.create_program(name)\n\n        index = self.project.names.index(name)\n        program = self.project[index]\n\n        nodes = program.flatten(False, True, False)\n        # Find if some names should be reserved\n        unassigned = {}\n        for node in nodes[::-1]:\n\n            if node.cls not in (\"Var\", \"Fvar\", \"Cvar\", \"Set\", \"Cset\", \"Sset\",\n                    \"Fset\", \"Nset\", \"Get\", \"Cget\", \"Fget\", \"Nget\", \"Sget\"):\n                continue\n\n            if node.name not in unassigned:\n                unassigned[node.name] = True\n\n            if node.parent.cls in (\"Params\", \"Declares\"):\n                unassigned[node.name] = False\n\n        unassigned = [k for k,v in unassigned.items() if v]\n\n        reserved = set([])\n        for i in range(len(unassigned)-1, -1, -1):\n\n            if unassigned[i] in rules._reserved.reserved:\n                reserved.add(unassigned.pop(i))\n\n        for node in nodes[::-1]:\n\n            if node.name in reserved:\n                node.backend = \"reserved\"\n\n        program.unassigned = unassigned\n\n\n    def get_unknowns(self, index=-1):\n        \"\"\"\nGet unknown variables and function calls names in a program.\n\nArgs:\n    index (int, str): Either loading index or the name of the program.\n\nReturns:\n    list: strings of the names of the unknown variables and calls.\n\nExample:\n    >>> builder = Builder(); builder.load(\"prg.m\", \"a;b;c\")\n    >>> print(sorted(builder.get_unknowns()))\n    ['a', 'b', 'c']\n        \"\"\"\n        if isinstance(index, str):\n            index = self.project.names.index(index)\n        assert isinstance(index, int)\n        return self.project[index].unassigned\n\n\n    def configure(self, suggest=True, **kws):\n        \"\"\"\nConfigure node tree with datatypes.\n\nArgs:\n    suggest (bool): Uses suggestion engine to fill in types\n\nExample::\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder()\n    >>> builder.load(\"unnamed.m\", \"a=1; b=2.; c='c'\")\n    >>> print(builder) # doctest: +NORMALIZE_WHITESPACE\n         Project    unknown      TYPE\n         | Program    unknown      TYPE    unnamed.m\n         | | Includes   unknown      TYPE\n     1  1| | Funcs      unknown      TYPE    unnamed.m\n     1  1| | | Main       unknown      TYPE    main\n     1  1| | | | Declares   unknown      TYPE\n     1  1| | | | | Var        unknown      TYPE    a\n     1  1| | | | | Var        unknown      TYPE    b\n     1  1| | | | | Var        unknown      TYPE    c\n     1  1| | | | Returns    unknown      TYPE\n     1  1| | | | Params     unknown      TYPE\n     1  1| | | | Block      unknown      TYPE\n     1  1| | | | | Assign     unknown      TYPE\n     1  1| | | | | | Var        unknown      TYPE    a\n     1  3| | | | | | Int        unknown      TYPE\n     1  6| | | | | Assign     unknown      TYPE\n     1  6| | | | | | Var        unknown      TYPE    b\n     1  8| | | | | | Float      unknown      TYPE\n     1 12| | | | | Assign     unknown      TYPE\n     1 12| | | | | | Var        unknown      TYPE    c\n     1 14| | | | | | String     unknown      TYPE\n         | | Inlines    unknown      TYPE    unnamed.m\n         | | Structs    unknown      TYPE    unnamed.m\n         | | Headers    unknown      TYPE    unnamed.m\n         | | Log        unknown      TYPE    unnamed.m\n    >>> builder.configure(suggest=True)\n    >>> print(builder) # doctest: +NORMALIZE_WHITESPACE\n         Project    program      TYPE\n         | Program    program      TYPE    unnamed.m\n         | | Includes   program      TYPE\n     1  1| | Funcs      program      TYPE    unnamed.m\n     1  1| | | Main       func_return  TYPE    main\n     1  1| | | | Declares   func_return  TYPE\n     1  1| | | | | Var        int          int     a\n     1  1| | | | | Var        double       double  b\n     1  1| | | | | Var        string       string  c\n     1  1| | | | Returns    func_return  TYPE\n     1  1| | | | Params     func_return  TYPE\n     1  1| | | | Block      code_block   TYPE\n     1  1| | | | | Assign     int          int \n     1  1| | | | | | Var        int          int     a\n     1  3| | | | | | Int        int          int\n     1  6| | | | | Assign     double       double\n     1  6| | | | | | Var        double       double  b\n     1  8| | | | | | Float      double       double\n     1 12| | | | | Assign     string       string\n     1 12| | | | | | Var        string       string  c\n     1 14| | | | | | String     string       string\n         | | Inlines    program      TYPE    unnamed.m\n         | | Structs    program      TYPE    unnamed.m\n         | | Headers    program      TYPE    unnamed.m\n         | | Log        program      TYPE    unnamed.m\n\nRaises:\n    RuntimeError: Method can only be run once.\n    \"\"\"\n        if self.configured:\n            raise RuntimeError(\"configure can only be run once\")\n        self.configured = True\n        configure.configure(self, suggest, **kws)\n\n\n    def translate(self):\n        \"\"\"\nPerform translation on all nodes in all programs in builder.\nAlso runs configure if not done already.\n\nSee also:\n    :py:mod:`matlab2cpp.rules`\n        \"\"\"\n\n        if not self.configured:\n            self.configure()\n\n        for program in self.project:\n            program.translate()\n\n\n    def syntaxerror(self, cur, text):\n        \"\"\"\nRaise an SyntaxError related to the Matlab code. Called from various\n``create_*`` methods when code is invalid.\n\nArgs:\n    cur (int): Current location in the Matlab code\n    text (str): The related rational presented to the user\n\nRaises:\n    SyntaxError: Error in the Matlab code.\n\nExample::\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder()\n    >>> prg = builder.load(\"unnamed.m\", \"0123456789\")\n    >>> builder.syntaxerror(7, \"example of error\")\n    Traceback (most recent call last):\n        ...\n    SyntaxError: File: unnamed.m, line 1 in Matlab code:\n    0123456789\n           ^\n    Expected: example of error\n    \"\"\"\n\n        start = cur-1\n        while start > 0 and self.code[start] != \"\\n\":\n            start -= 1\n\n        end = cur+1\n        while end < len(self.code) and self.code[end] != \"\\n\":\n            end += 1\n\n        out = \"File: %s, line %d in Matlab code:\\n\" % (self.project[-1].name, self.code.count(\"\\n\", 0, cur)+1)\n        out += self.code[start:end] + \"\\n\" + \" \"*(cur-start) + \"^\\n\"\n        out += \"Expected: \" + text\n        raise SyntaxError(out)\n\n\n    def create_program(self, name):\n        \"\"\"\nCreate program meta variables and initiates to fill them\n\n| Structure:\n|   Program\n|   | Includes\n|   | Funcs\n|   | Inlines\n|   | Structs\n|   | Headers\n|   | Log\n\nArgs:\n    name (str): filename of program\n\nReturns:\n    int: position in program when scanning is complete.\n\nSee also:\n    :py:func:`matlab2cpp.tree.functions.program`\n        \"\"\"\n        from . import functions\n        assert isinstance(name, (int, str))\n        return functions.program(self, name)\n\n\n    def create_function(self, parent, cur):\n        \"\"\"\nCreate function (not main)\n\n| Structure:\n|   Func\n|   | Declares\n|   | Returns\n|   | Params\n|   | <code block>\n\nArgs:\n    parent (Funcs): Reference to parent node\n    cur (int): position where function is identified\n\nReturns:\n    int: position where function ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.functions.function`\n        \"\"\"\n        from . import functions\n        assert isinstance(parent, collection.Funcs)\n        return functions.function(self, parent, cur)\n\n\n    def create_main(self, parent, cur):\n        \"\"\"\nCreate main function\n\n| Structure:\n|   Main\n|   | Declares\n|   | Returns\n|   | Params\n|   | <code block>\n\nArgs:\n    parent (Funcs): Reference to parent node\n    cur (int): position where main function is identified\n\nReturns:\n    int: position where main function ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.functions.main`\n        \"\"\"\n        from . import functions\n        assert isinstance(parent, collection.Funcs)\n        return functions.main(self, parent, cur)\n\n\n    def create_lambda_assign(self, parent, cur, eq_loc):\n        \"\"\"\nCreate assignments involving lambda functions\n\n| Structure:\n|   Assign\n|   | <assign variable>\n|   | <lambda function>\n\nArgs:\n    parent (Block): Reference to parent node\n    cur (int): position where Lambda assignment is identified\n    eq_loc (int): position of assignment equal sign\n\nReturns:\n    int: position where Lambda assignment ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.functions.lambda_assign`\n        \"\"\"\n        from . import functions\n        assert isinstance(parent, collection.Block)\n        return functions.lambda_assign(self, parent, cur, eq_loc)\n\n\n    def create_lambda_func(self, parent, cur):\n        \"\"\"\nCreate lambda function\n\n| Structure (function part):\n|   Func\n|   | Declares\n|   | Returns\n|   | | Var (_retval)\n|   | Params\n|   | Block\n|   | | Assign\n|   | | | Var (_retval)\n|   | | | <expression>\n|\n| Structure (lambda part):\n|   Lambda\n\n\nArgs:\n    parent (Assign): Reference to parent node\n    cur (int): position where Lambda function is identified\n\nReturns:\n    int: position where Lambda function ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.functions.lambda_func`\n        \"\"\"\n        from . import functions\n        assert isinstance(parent, collection.Assign)\n        return functions.lambda_func(self, parent, cur)\n\n\n    def create_codeblock(self, parent, cur):\n        \"\"\"\nCreate codeblock Block\n\n| Structure:\n|   Assign|Assigns|Bcomment|Ecomment|Lcomment|Statement\n\n`Statements` are handled locally and evoces <expression>\n\nLegal parents:\nCase, Catch, Elif, Else, For, Func, If, Main, Otherwise, Switch, Try, While\n\nArgs:\n    parent (Node): Reference to parent node\n    cur (int): position where codeblock is identified\n\nReturns:\n    int: position where codeblock ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.codeblock.codeblock`\n        \"\"\"\n        from . import codeblock\n        pnames = [\"Case\", \"Catch\", \"Elif\", \"Else\", \"Parfor\", \"For\", \"Func\", \"If\",\n                  \"Main\", \"Otherwise\", \"Switch\", \"Try\", \"While\"]\n        pnodes = [getattr(collection, name) for name in pnames]\n        ppart = [isinstance(parent, node) for node in pnodes]\n        if not any(ppart):\n            raise AssertionError(\n                \"parent of Block: %s not valid group parent\\n%s\" %\\\n                (parent.cls, str(pnames)))\n        return codeblock.codeblock(self, parent, cur)\n\n\n    def create_assigns(self, parent, cur, eq_loc):\n        \"\"\"\nCreate assignment with multiple returns\n\n| Structure:\n|   Assigns\n|   | <list of return vars>\n|   | Get|Var\n\nArgs:\n    parent (Block): Reference to parent node\n    cur (int): position where assignments is identified\n    eq_loc (int): position of assignment equal sign\n\nReturns:\n    int: position where assignments ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.assign.multi`\n        \"\"\"\n        from . import assign\n        assert isinstance(parent, collection.Block)\n        return assign.multi(self, parent, cur, eq_loc)\n\n\n    def create_assign(self, parent, cur, eq_loc):\n        \"\"\"\nCreate assignment with single return\n\n| Structure:\n|   Assign\n|   | <return var>\n|   | Get|Var\n\nArgs:\n    parent (Block): Reference to parent node\n    cur (int): position where assignment is identified\n    eq_loc (int): position of assignment equal sign\n\nReturns:\n    int: position where assignment ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.assign.single`\n        \"\"\"\n        from . import assign\n        assert isinstance(parent, collection.Block)\n        return assign.single(self, parent, cur, eq_loc)\n\n    def create_parfor(self, parent, cur):\n        \"\"\"\nCreate parfor-loop\n\n| Structure:\n|   Parfor\n|   | <loop variable>\n|   | <loop expression>\n|   | <code block>\n\nArgs:\n    parent (Block): Reference to parent node\n    cur (int): position where for-loop is identified\n\nReturns:\n    int: position where for-loop ends\n        \"\"\"\n        from . import branches\n        assert isinstance(parent, collection.Block)\n        return branches.parforloop(self, parent, cur)\n\n    def create_for(self, parent, cur):\n        \"\"\"\nCreate For-loop\n\n| Structure:\n|   For\n|   | <loop variable>\n|   | <loop expression>\n|   | <code block>\n\nArgs:\n    parent (Block): Reference to parent node\n    cur (int): position where for-loop is identified\n\nReturns:\n    int: position where for-loop ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.branches.forloop`\n        \"\"\"\n        from . import branches\n        assert isinstance(parent, collection.Block)\n        return branches.forloop(self, parent, cur)\n\n\n    def create_if(self, parent, cur):\n        \"\"\"\nCreate if-branch\n\n| Structure (main):\n|   Branch\n|   | If\n|   | | <cond expression>\n|   | | <code block>\n|   | <else if>*\n|   | <else>?\n|\n| Structure (else if):\n|   Elif\n|   | <cond expression>\n|   | <code block>\n|\n| Structure (else):\n|   Else\n|   | <code block>\n\nArgs:\n    parent (Block): Reference to parent node\n    cur (int): position where if-branch is identified\n\nReturns:\n    int: position where if-branch ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.branches.ifbranch`\n        \"\"\"\n        from . import branches\n        assert isinstance(parent, collection.Block)\n        return branches.ifbranch(self, parent, cur)\n\n\n    def create_while(self, parent, cur):\n        \"\"\"\nCreate while-loop\n\n| Structure:\n|   While\n|   | <cond expression>\n|   | <code block>\n\nArgs:\n    parent (Block): Reference to parent node\n    cur (int): position where while-loop is identified\n\nReturns:\n    int: position where while-loop ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.branches.whileloop`\n        \"\"\"\n        from . import branches\n        assert isinstance(parent, collection.Block)\n        return branches.whileloop(self, parent, cur)\n\n\n    def create_switch(self, parent, cur):\n        \"\"\"\nCreate switch-branch\n\n| Structure (main):\n|   Switch\n|   | <cond expression>\n|   | <case>+\n|   | <otherwise>?\n|\n| Structure (case):\n|   Case\n|   | <cond expression>\n|   | <code block>\n|\n| Structure (otherwise):\n|   Otherwise\n|   | <code block>\n\nArgs:\n    parent (Block): Reference to parent node\n    cur (int): position where switch is identified\n\nReturns:\n    int: position where switch ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.branches.switch`\n        \"\"\"\n        from . import branches\n        assert isinstance(parent, collection.Block)\n        return branches.switch(self, parent, cur)\n\n\n    def create_try(self, parent, cur):\n        \"\"\"\nCreate try-block\n\n| Structure:\n|   Tryblock\n|   | Try\n|   | | <code block>\n|   | Catch\n|   | | <code block>\n\nArgs:\n    parent (Block): Reference to parent node\n    cur (int): position where try-block is identified\n\nReturns:\n    int: position where try-block ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.branches.trybranch`\n        \"\"\"\n        from . import branches\n        assert isinstance(parent, collection.Block)\n        return branches.trybranch(self, parent, cur)\n\n\n    def create_cell(self, parent, cur):\n        \"\"\"\nCreate cell-structure (expression)\n\n| Structure:\n|   Cell\n|   | <expression>+\n\nArgs:\n    parent (Node): Reference to parent node\n    cur (int): position where cell is identified\n\nReturns:\n    int: position where cell ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.misc.cell`\n        \"\"\"\n        from . import misc\n        return misc.cell(self, parent, cur)\n\n    def create_pragma_parfor(self, parent, cur):\n        from . import misc\n        assert isinstance(parent, collection.Block)\n        return misc.pragma_for(self, parent, cur)\n\n    def create_comment(self, parent, cur):\n        \"\"\"\nCreate comment\n\n| Structure:\n|   Bcomment|Ecomment|Lcomment\n\nArgs:\n    parent (Block): Reference to parent node\n    cur (int): position where comment is identified\n\nReturns:\n    int: position where comment ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.misc.comment`\n        \"\"\"\n        from . import misc\n        assert isinstance(parent, collection.Block)\n        return misc.comment(self, parent, cur)\n\n\n    def create_verbatim(self, parent, cur):\n        \"\"\"\nCreate verbatim translation\n\nA manual overrides switch provided by the user to perform translations.\n\n| Structure:\n|   Verbatim\n\nArgs:\n    parent (Block): Reference to parent node\n    cur (int): position where verbatim is identified\n    \nReturns:\n    int: position where verbatim ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.misc.verbatim`\n        \"\"\"\n        from . import misc\n        return misc.verbatim(self, parent, cur)\n    \n\n    def create_string(self, parent, cur):\n        \"\"\"\nCreate string (Expression)\n\n| Structure:\n|   String\n\nArgs:\n    parent (Node): Reference to parent node\n    cur (int): position where string is identified\n\nReturns:\n    int: position where string ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.misc.string`\n        \"\"\"\n        from . import misc\n        return misc.string(self, parent, cur)\n\n\n    def create_list(self, parent, cur):\n        \"\"\"\nCreate list of expressions\n\n| Structure:\n|   <expression>*\n\nArgs:\n    parent (Node): Reference to parent node\n    cur (int): position where list is identified\n\nReturns:\n    int: position where list ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.misc.list`\n        \"\"\"\n        from . import misc\n        return misc.list(self, parent, cur)\n\n\n    def create_matrix(self, parent, cur):\n        \"\"\"\nCreate matrix (Expression)\n\n| Structure (main):\n|   Matrix\n|   | <vector>*\n|\n| Structure (vector):\n|   Vector\n|   | <expression>*\n\nArgs:\n    parent (Node): Reference to parent node\n    cur (int): position where matrix is identified\n\nReturns:\n    int: position where matrix ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.misc.matrix`\n        \"\"\"\n        from . import misc\n        return misc.matrix(self, parent, cur)\n\n\n    def create_number(self, parent, cur):\n        \"\"\"\nCreate number (Expression)\n\n| Structure:\n|   Int|Float|Imag\n\nArgs:\n    parent (Node): Reference to parent node\n    cur (int): position where number is identified\n\nReturns:\n    int: position where number ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.misc.number`\n        \"\"\"\n        from . import misc\n        return misc.number(self, parent, cur)\n\n\n    def create_reserved(self, parent, cur):\n        \"\"\"\nCreate Matlab reserved keywords.\n\nSome words like \"hold\", \"grid\" and \"clear\", behaves differently than regular\nMatlab. They take arguments after space, not in parenthesis.\n\n| Structure (main):\n|   Get\n|   | <string>*\n|\n| Structure (string):\n|   String\n\nArgs:\n    parent (Block): Reference to parent node\n    cur (int): position where reserved statement is identified\n\nReturns:\n    int: position where reserved statement ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.misc.reserved`\n        \"\"\"\n        from . import misc\n        assert isinstance(parent, collection.Block)\n        return misc.reserved(self, parent, cur)\n\n\n    def create_variable(self, parent, cur):\n        \"\"\"\nCreate left-hand-side variable (Expression)\n\n| Structure:\n|   Cget|Cvar|Fget|Fvar|Get|Nget|Var|Sget|Svar\n|   | <list of expression>?\n\nArgs:\n    parent (Node): Reference to parent node\n    cur (int): position where variable is identified\n\nReturns:\n    int: position where variable ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.variables.variable`\n        \"\"\"\n        from . import variables\n        return variables.variable(self, parent, cur)\n\n    def create_assign_variable(self, parent, cur, end=None):\n        \"\"\"\nCreate right-hand-side variable (Expression)\n\n| Structure:\n|   Cset|Cvar|Fset|Fvar|Nset|Var|Set|Sset|Svar\n|   | <list of expression>?\n\nArgs:\n    parent (Node): Reference to parent node\n    cur (int): position where variable is identified\n    end (int, optional): position where variable ends\n\nReturns:\n    int: position where variable ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.variables.assign`\n        \"\"\"\n        from . import variables\n        return variables.assign(self, parent, cur, end)\n\n\n    def create_expression(self, parent, cur, end=None):\n        \"\"\"\nCreate expression\n\nMain engine for creating expression.\n\nArgs:\n    parent (Node): Reference to parent node\n    cur (int): position where expression is identified\n    end (int, optional): position where expression ends\n\nReturns:\n    int: position where expression ends\n\nSee also:\n    :py:func:`matlab2cpp.tree.expression.create`\n        \"\"\"\n        from . import expression\n        return expression.create(self, parent, cur, end)\n"
  },
  {
    "path": "src/matlab2cpp/tree/codeblock.py",
    "content": "\"\"\"The main codeblock loop\"\"\"\nfrom __future__ import print_function\n\nimport matlab2cpp\n\nfrom . import findend, constants as c\n\ndef codeblock(self, parent, start):\n    '''\nIf-ifelse-else branch\n\nArgs:\n    self (Builder): Code constructor\n    parent (Node): Parent node\n    cur (int): Current position in code\n\nReturns:\n\tint: Index to end of codeblock\n\nExample:\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder(True)\n    >>> builder.load(\"unnamed\", \"a; 'b'; 3\") # doctest: +NORMALIZE_WHITESPACE\n    loading unnamed\n         Program     functions.program\n       0 Main        functions.main\n       0 Codeblock   codeblock.codeblock \n       0   Statement     codeblock.codeblock  'a'\n       0     Expression  expression.create    'a'\n       0     Var         variables.variable   'a'\n       3   Statement     codeblock.codeblock  \"'b'\"\n       3     String  misc.string          \"'b'\"\n       8   Statement     codeblock.codeblock  '3'\n       8     Expression  expression.create    '3'\n       8     Int         misc.number          '3'\n    >>> builder.configure()\n    >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n    1  1Block      code_block   TYPE\n    1  1| Statement  code_block   TYPE\n    1  1| | Var        unknown      TYPE    a\n    1  4| Statement  code_block   TYPE\n    1  4| | String     string       string\n    1  9| Statement  code_block   TYPE\n    1  9| | Int        int          int\n    '''\n    cur = start\n    block = matlab2cpp.collection.Block(parent, cur=cur)\n\n    if self.disp:\n        print(\"%4d Codeblock  \" % cur, end=\"\")\n        print(\"%-20s\" % \"codeblock.codeblock\")\n\n    is_end_terminated = False\n\n    while True:\n        #print(self.code[cur:cur+5])\n        if self.code[cur] in \" \\t;\":\n            pass\n\n        elif self.code[cur] == \"\\n\":\n            if len(self.code)-cur < 3:\n                break\n\n        #%#PARFOR token\n        elif self.code[cur:cur+8] == \"%#PARFOR\":\n            cur = self.create_pragma_parfor(block, cur)\n\n        elif self.code[cur] == \"%\":\n            cur = self.create_comment(block, cur)\n\n        elif self.code[cur:cur+3] == \"___\":\n            cur = self.create_verbatim(block, cur)\n\n        elif self.code[cur] == \"[\":\n            # Divide between statement and assignment\n            eq_loc = findend.matrix(self, cur)+1\n\n            while self.code[eq_loc] in \" \\t\":\n                eq_loc += 1\n\n            if self.code[eq_loc] == \"=\" and self.code[eq_loc+1] != \"=\":\n                cur = self.create_assigns(block, cur, eq_loc)\n\n            else:\n                statement = matlab2cpp.collection.Statement(block, cur=cur)\n\n                end = findend.expression(self, cur)\n                if self.disp:\n                    print(\"%4d   Statement    \" % cur, end=\"\")\n                    print(\"%-20s\" % \"codeblock.codeblock\", end=\"\")\n                    print(repr(self.code[cur:end+1]))\n\n                statement.code = self.code[cur:end+1]\n\n                cur = self.create_expression(\n                        statement, cur, end=end)\n\n\n        elif self.code[cur] == \"'\":\n            end = findend.string(self, cur)\n            if self.disp:\n                print(\"%4d   Statement    \" % cur, end=\"\")\n                print(\"%-20s\" % \"codeblock.codeblock\", end=\"\")\n                print(repr(self.code[cur:end+1]))\n\n            statement = matlab2cpp.collection.Statement(block, cur=cur,\n                    code=self.code[cur:end+1])\n\n            cur = self.create_string(statement, cur)\n\n        elif self.code[cur:cur+4] == \"case\" and self.code[cur+4] in c.k_end:\n            break\n\n        elif self.code[cur:cur+5] == \"catch\" and self.code[cur+5] in c.k_end:\n            break\n\n        elif self.code[cur:cur+3] == \"end\" and self.code[cur+3] in c.k_end:\n            cur += 3\n            is_end_terminated = True\n            break\n\n        elif self.code[cur:cur+4] == \"else\" and self.code[cur+4] in c.k_end:\n            break\n\n        elif self.code[cur:cur+6] == \"elseif\" and self.code[cur+6] in c.k_end:\n            break\n\n        elif self.code[cur:cur+6] == \"parfor\" and self.code[cur+6] in c.k_end:\n            cur = self.create_parfor(block, cur)\n\n        elif self.code[cur:cur+3] == \"for\" and self.code[cur+3] in c.k_end:\n            cur = self.create_for(block, cur)\n\n        elif self.code[cur:cur+8] == \"function\" and\\\n                self.code[cur+8] in c.k_end + \"[\":\n            cur -= 1\n            break\n\n        elif self.code[cur:cur+2] == \"if\" and self.code[cur+2] in c.k_end:\n            cur = self.create_if(block, cur)\n\n        elif self.code[cur:cur+9] == \"otherwise\" and self.code[cur+9] in c.k_end:\n            break\n\n        elif self.code[cur:cur+6] == \"switch\" and self.code[cur+6] in c.k_end:\n            cur = self.create_switch(block, cur)\n\n        elif self.code[cur:cur+3] == \"try\" and self.code[cur+3] in c.k_end:\n            cur = self.create_try(block, cur)\n\n        elif self.code[cur:cur+5] == \"while\" and self.code[cur+5] in c.k_end:\n            cur = self.create_while(block, cur)\n\n        elif self.code[cur:cur+4] == \"hold\" and \\\n            self.code[cur+4] not in c.letters+c.digits+\"_\":\n            cur = self.create_reserved(block, cur)\n\n        elif self.code[cur:cur+4] == \"load\" and \\\n            self.code[cur+4] not in c.letters+c.digits+\"_\":\n            cur = self.create_reserved(block, cur)\n\n        elif self.code[cur:cur+4] == \"disp\" and \\\n            self.code[cur+4] not in c.letters+c.digits+\"_\":\n            cur = self.create_reserved(block, cur)\n\n        elif self.code[cur:cur+4] == \"grid\" and \\\n            self.code[cur+4] not in c.letters+c.digits+\"_\":\n            cur = self.create_reserved(block, cur)\n\n        elif self.code[cur] in c.e_start:\n            j = findend.expression(self, cur)\n\n            j += 1\n            while self.code[j] in \" \\t\":\n                j += 1\n            eq_loc = j\n\n            if self.code[eq_loc] == \"=\": # and self.code[eq_loc+1] != \"=\":\n\n                j = eq_loc +1\n                while self.code[j] in \" \\t\":\n                    j += 1\n                if self.code[j] == \"@\":\n                    cur = self.create_lambda_assign(block, cur, eq_loc)\n                else:\n                    cur = self.create_assign(block, cur, eq_loc)\n\n            else:\n                end = findend.expression(self, cur)\n                if self.disp:\n                    print(\"%4d   Statement    \" % cur, end=\"\")\n                    print(\"%-20s\" % \"codeblock.codeblock\", end=\"\")\n                    print(repr(self.code[cur:end+1]))\n\n                statement = matlab2cpp.collection.Statement(block, cur=cur,\n                        code=self.code[cur:end+1])\n\n                cur = self.create_expression(statement,\n                        cur, end=end)\n\n        cur += 1\n\n        if len(self.code)-cur<3:\n            break\n    block.is_end_terminated = is_end_terminated\n    block.code = self.code[start:cur+1]\n    return cur\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/tree/constants.py",
    "content": "\"\"\"\nMatlab consists of various legal start and end characters depending on context.\nThis module is a small collection of constants available to ensure that context\nis defined correctly.\n\nAttributes:\n    e_start (str): characers allowed in expression start\n    e_end (str): characers allowed to terminate expression\n    l_start (str): characters allowed in list start\n    l_end (str): characters allowed to terminate list\n    prefixes (str): characters allowed as prefix univery operators\n    postfix1 (str): characters allowed as postfix univary operators\n    postfix2 (tuple): same as postfix1, but tuple of multi-char operators\n    op1 (str): characters allowed as infix operators\n    op2 (tuple): same as op1, but tuple of multi-char operators\n\"\"\"\nimport string\n\nletters = string.ascii_letters\ndigits = string.digits\n\n# start and end of expression\ne_start = letters + digits + \"[({~-+:@.'\"\ne_end = \"%])},;\\n\"\n\n# start and end of lists\nl_start = \"[({\"\nl_end = \"]})\"\n\n# end of keyword\nk_end = \" \\t(,;\\n%\"\n\nprefixes = \"-+~\"\npostfix1 = \"'\"\npostfix2 = (\".'\",)\n\n# operators with one character\nop1 = r\"^\\/*+-:<>&|\"\n\n# operators using two characters\nop2 = (\n    \".^\", \".\\\\\", \"./\", \".*\",\n    \"<=\", \">=\", \"==\", \"~=\",\n    \"&&\", \"||\")\n"
  },
  {
    "path": "src/matlab2cpp/tree/expression.py",
    "content": "\"\"\"\nExpression interpretor\n\"\"\"\nfrom __future__ import print_function\nfrom .. import collection\n\n\nRECIVER_OPERATORS = {\n    \"^\": collection.Exp,\n    \".^\": collection.Elexp,\n    \"\\\\\": collection.Leftmatrixdivision,\n    \".\\\\\": collection.Leftelementdivision,\n    \"/\": collection.Matrixdivision,\n    \"./\": collection.Elementdivision,\n    \"*\": collection.Mul,\n    \".*\": collection.Elmul,\n    \"+\": collection.Plus,\n    \"-\": collection.Minus,\n    \":\": collection.Colon,\n    \"<\": collection.Lt,\n    \"<=\": collection.Le,\n    \">\": collection.Gt,\n    \">=\": collection.Ge,\n    \"==\": collection.Eq,\n    \"~=\": collection.Ne,\n    \"&\": collection.Band,\n    \"|\": collection.Bor,\n    \"&&\": collection.Land,\n    \"||\": collection.Lor,\n}\n\n\ndef create(self, node, start, end=None, start_opr=None):\n    \"\"\"\nCreate expression in three steps:\n\n    1) In order, split into sub-expressions for each dividing operator\n    2) Address prefixes, postfixes, parenthesises, etc.\n    3) Identify the remaining singleton\n\nArgs:\n    self (Builder): Code constructor.\n    node (Node): Reference to the parent node\n    start (int): current possition in code\n    end (int, optional): end of expression. Required for space-delimited expression.\n    start_opr (str, optional): At which operator the recursive process is. (For internal use)\n\nReturns:\n\tint : index to end of the expression\n\nExamples::\n\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder(True)\n    >>> builder.load(\"unnamed\", \"a*b+c/d\") # doctest: +NORMALIZE_WHITESPACE\n    loading unnamed\n         Program     functions.program\n       0 Main        functions.main\n       0 Codeblock   codeblock.codeblock \n       0   Statement     codeblock.codeblock  'a*b+c/d'\n       0     Expression  expression.create    'a*b+c/d'\n       0     Expression  expression.create    'a*b'\n       0     Expression  expression.create    'a'\n       0     Var         variables.variable   'a'\n       2     Expression  expression.create    'b'\n       2     Var         variables.variable   'b'\n       4     Expression  expression.create    'c/d'\n       4     Expression  expression.create    'c'\n       4     Var         variables.variable   'c'\n       6     Expression  expression.create    'd'\n       6     Var         variables.variable   'd'\n    >>> builder.configure(suggest=False)\n    >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n    1 1Block      code_block   TYPE\n    1 1| Statement  code_block   TYPE\n    1 1| | Plus       expression   TYPE\n    1 1| | | Mul        expression   TYPE\n    1 1| | | | Var        unknown      TYPE    a\n    1 3| | | | Var        unknown      TYPE    b\n    1 5| | | Matrixdivisionexpression   TYPE\n    1 5| | | | Var        unknown      TYPE    c\n    1 7| | | | Var        unknown      TYPE    d\n    \"\"\"\n    from . import findend, identify, constants\n\n    if self.code[start:start+3] == \"...\":\n        start = findend.dots(self, start)\n        start += 1\n        while self.code[start] in \" \\t\":\n            start += 1\n\n    if self.code[start] == \":\":\n\n        if self.disp:\n\n            print(\"%4d     Expression \" % (start), end=\"\")\n            print(\"%-20s\" % \"expression.create\", end=\"\")\n            print(repr(self.code[start:start+1]))\n\n            print(\"%4d     All        \" % (start), end=\"\")\n            print(\"%-20s\" % \"expression.create\", end=\"\")\n            print(repr(self.code[start:start+1]))\n\n        collection.All(node, cur=start, code=self.code[start])\n        return start\n\n    if end is None:\n        end = findend.expression(self, start)\n\n    if self.disp:\n        print(\"%4d     Expression \" % (start), end=\"\")\n        print(\"%-20s\" % \"expression.create\", end=\"\")\n        print(repr(self.code[start:end+1]))\n\n    if  self.code[start] not in constants.e_start:\n        self.syntaxerror(start, \"expression start\")\n\n\n    operators = [\n        \"||\", \"&&\", \"|\", \"&\",\n        \"~=\", \"==\", \">=\", \">\", \"<=\", \"<\",\n        \":\", \"+\", \"-\",\n        \".*\", \"*\", \"./\", \"/\", \".\\\\\", \"\\\\\",\n        \".^\", \"^\"]\n\n    if not (start_opr is None):\n        operators = operators[operators.index(start_opr)+1:]\n\n    for opr in operators:\n        # Pre-screen\n        if opr not in self.code[start:end+1]:\n            continue\n\n        starts = [start]\n        last = start\n        ends = []\n\n        k = start\n        while True:\n\n            if self.code[k] == \"(\":\n                k = last = findend.paren(self, k)\n\n            elif self.code[k] == \"[\":\n                k = last = findend.matrix(self, k)\n\n            elif self.code[k] == \"{\":\n                k = last = findend.cell(self, k)\n\n            elif self.code[k] == \"'\":\n                if identify.string(self, k):\n                    k = last = findend.string(self, k)\n                else:\n                    last = k\n\n            elif opr == self.code[k:k+len(opr)]:\n\n                if opr in \"+-\":\n                    # no prefixes and no (scientific) numbers\n                    if self.code[last] not in constants.letters+constants.digits+\")]}\" or\\\n                            self.code[k-1] in \"dDeE\" and self.code[k-2] in\\\n                            constants.digits+\".\" and self.code[k+1] in constants.digits:\n                        k += 1\n                        continue\n\n\n                k += len(opr)-1\n                while self.code[k+1] in \" \\t\":\n                    k += 1\n\n                # no all-operator\n                if opr == \":\" and self.code[k+1] in \",;\\n)]}\":\n                    k += 1\n                    continue\n\n                starts.append(k+1)\n                ends.append(last)\n\n            elif self.code[k] in constants.letters+constants.digits+\"_\":\n                last = k\n\n            k += 1\n            if k >= end:\n                ends.append(end)\n                break\n\n        if len(ends) > 1:\n\n            operator = RECIVER_OPERATORS[opr]\n            node = operator(node)\n            node.cur = start\n            node.code = self.code[starts[0]:ends[-1]+1]\n\n            for s,e in zip(starts, ends):\n                create(self, node, s, e, opr)\n\n            return end\n\n\n    # All operators removed at this point!\n\n    END = end\n\n    # Prefixes\n    while self.code[start] in \"-~\":\n\n        if self.code[start] == \"-\":\n\n            node = collection.Neg(node, cur=start, code=self.code[start:end+1])\n            start += 1\n\n        if self.code[start] == \"~\":\n\n            node = collection.Not(node, cur=start, code=self.code[start:end+1])\n            start += 1\n\n        while self.code[start] in \" \\t\":\n            start += 1\n\n    # Postfixes\n    if self.code[end] == \"'\" and not self.code[start] == \"'\":\n        if self.code[end-1] == \".\":\n            node = collection.Transpose(node, cur=start,\n                    code=self.code[start:end+1])\n            end -= 2\n        else:\n            node = collection.Ctranspose(node, cur=start,\n                    code=self.code[start:end+1])\n            node.cur = start\n            node.code = self.code[start:end+1]\n            end -= 1\n\n        while self.code[end] in \" \\t\":\n            end -= 1\n\n    # Parenthesis\n    if self.code[start] == \"(\":\n        if self.code[end] != \")\":\n            self.syntaxerror(end, \"parenthesis end\")\n\n        node = collection.Paren(node, cur=start, code=self.code[start:end+1])\n\n        start += 1\n        while self.code[start] in \" \\t\":\n            start += 1\n\n        end -= 1\n        while self.code[end] in \" \\t\":\n            end -= 1\n\n        return create(self, node, start, end)\n\n    # Reserved keywords\n    elif self.code[start:start+3] == \"end\" and self.code[start+3] in \" +-:\\t\" + constants.e_end:\n        node = collection.End(node, cur=start, code=self.code[start:start+3])\n\n    elif self.code[start:start+6] == \"return\" and self.code[start+6] in \" ,;\\n\":\n        node = collection.Return(node, cur=start, code=self.code[start:start+6])\n\n    elif self.code[start:start+5] == \"break\" and self.code[start+5] in \" ,;\\n\":\n        node = collection.Break(node, cur=start, code=self.code[start:start+5])\n\n\n    # Rest\n    elif self.code[start] == \"'\":\n        if self.code[end] != \"'\":\n            self.syntaxerror(end, \"string end\")\n\n        if \"\\n\" in self.code[start:end]:\n            self.syntaxerror(end, \"non line-feed characters in string\")\n\n        collection.String(node, self.code[start+1:end], cur=start,\n                code=self.code[start:end+1])\n\n    elif self.code[start] in constants.digits or\\\n            self.code[start] == \".\" and self.code[start+1] in constants.digits:\n        cur = self.create_number(node, start)\n\n    elif self.code[start] == \"[\":\n        cur = self.create_matrix(node, start)\n\n    elif self.code[start] == \"{\":\n        cur = self.create_cell(node, start)\n\n    else:\n        if self.code[start] not in constants.letters+\"@\":\n            self.syntaxerror(start, \"variable name\")\n\n        cur = self.create_variable(node, start)\n\n    return END\n"
  },
  {
    "path": "src/matlab2cpp/tree/findend.py",
    "content": "\"\"\"\nLook-ahead routines to find end character.\n\n+------------------------------------------------------+------------------------+\n| Function                                             | Description            |\n+======================================================+========================+\n| :py:func:`~matlab2cpp.tree.findend.expression`       | Find end of expression |\n|                                                      | (non-space delimited)  |\n+------------------------------------------------------+------------------------+\n| :py:func:`~matlab2cpp.tree.findend.expression_space` | Find end of expression |\n|                                                      | (space delimited)      |\n+------------------------------------------------------+------------------------+\n| :py:func:`~matlab2cpp.tree.findend.matrix`           | Find end of matrix     |\n|                                                      | construction           |\n+------------------------------------------------------+------------------------+\n| :py:func:`~matlab2cpp.tree.findend.string`           | Find end of string     |\n+------------------------------------------------------+------------------------+\n| :py:func:`~matlab2cpp.tree.findend.comment`          | Find end of comment    |\n+------------------------------------------------------+------------------------+\n| :py:func:`~matlab2cpp.tree.findend.dots`             | Find continuation      |\n|                                                      | after ellipse          |\n+------------------------------------------------------+------------------------+\n| :py:func:`~matlab2cpp.tree.findend.paren`            | Find matching          |\n|                                                      | parenthesis            |\n+------------------------------------------------------+------------------------+\n| :py:func:`~matlab2cpp.tree.findend.cell`             | Find matching          |\n|                                                      | cell-parenthesis       |\n+------------------------------------------------------+------------------------+\n\"\"\"\nfrom . import constants, identify\n\n\ndef expression(self, start):\n    \"\"\"\n    Find end of expression (non-space delimited)\n\nArgs:\nself (Builder): Code constructor\nstart (int): current position in code\n\nReturns:\nint: index location of end of expression\n    \"\"\"\n\n    if  self.code[start] not in constants.e_start:\n        self.syntaxerror(start, \"expression start\")\n    k = start\n\n    while True:\n\n        if self.code[k] == \"(\":\n            k = paren(self, k)\n            #k += 1\n            #break\n\n\n        elif self.code[k] == \"[\":\n            k = matrix(self, k)\n\n        elif self.code[k] == \"'\" and identify.string(self, k):\n            k = string(self, k)\n\n        elif self.code[k] == \"{\":\n            k = cell(self, k)\n\n        #elif self.code[k:k+3] == \"...\":\n        #    k = dots(self, k)\n\n        elif self.code[k] == \"=\":\n\n            if self.code[k+1] == \"=\":\n                k += 1\n            else:\n                break\n\n        elif self.code[k] in \"><~\":\n\n            if self.code[k+1] == \"=\":\n                k += 1\n\n        elif self.code[k:k+3] == \"...\":\n            k = dots(self, k)\n\n        elif self.code[k] in constants.e_end:\n            break\n\n        k += 1\n\n    k -= 1\n    while self.code[k] in \" \\t\":\n        k -= 1\n\n    return k\n\n\ndef expression_space(self, start):\n    \"\"\"\n    Find end of expression (space delimited)\n\nArgs:\nself (Builder): Code constructor\nstart (int): current position in code\n\nReturns:\nint: index location of end of expression\n    \"\"\"\n\n    if  self.code[start] not in constants.e_start:\n        self.syntaxerror(start, \"expression start\")\n    k = last = start\n\n    while True:\n\n        if self.code[k] == \"(\":\n            k = last = paren(self, k)\n\n        elif self.code[k] == \"[\":\n            k = last = matrix(self, k)\n\n        elif self.code[k] == \"'\":\n            if identify.string(self, k):\n                k = last = string(self, k)\n            else:\n                last = k\n\n        elif self.code[k] == \"{\":\n            k = last = cell(self, k)\n\n        elif self.code[k:k+3] == \"...\":\n            k = dots(self, k)\n\n        elif self.code[k] == \";\":\n            return last\n\n        elif self.code[k] == \"=\":\n\n            if self.code[k+1] == \"=\":\n                k += 1\n            else:\n                return last\n\n        elif self.code[k] in \"><~\":\n\n            if self.code[k+1] == \"=\":\n                k += 1\n\n        elif self.code[k] in \"+-\":\n            while self.code[k+1] in \" \\t\":\n                k += 1\n\n        elif self.code[k] in \" \\t\":\n\n            if identify.space_delimiter(self, k):\n                return last\n            while self.code[k+1] in \" \\t+-~\":\n                k += 1\n\n        elif self.code[k] in constants.e_end:\n            return last\n\n        elif self.code[k] in constants.letters + constants.digits + \"_@\":\n            while self.code[k+1] in constants.letters + constants.digits + \"_@\":\n                k += 1\n            last = k\n\n        k += 1\n\n\ndef matrix(self, start):\n    \"\"\"\n    Find end of matrix construction\n\nArgs:\nself (Builder): Code constructor\nstart (int): current position in code\n\nReturns:\nint: index location of end of matrix\n    \"\"\"\n\n    if  self.code[start] != \"[\":\n        self.syntaxerror(start, \"matrix start ([)\")\n\n    k = start+1\n\n    if identify.space_delimited(self, start):\n\n        # Ignore first string occurrence\n        while self.code[k] in \" \\t\":\n            k += 1\n        if self.code[k] == \"'\":\n            k = string(self, k)+1\n\n        while True:\n\n            if self.code[k] == \"[\":\n                k = matrix(self, k)\n\n            elif self.code[k] == \"]\":\n                return k\n\n            elif self.code[k] == \"%\":\n                k = comment(self, k)\n\n            elif self.code[k] == \"'\" and identify.string(self, k): #and self.code[k-1] in constants.s_start:\n                k = string(self, k)\n\n            k += 1\n\n    else:\n        while True:\n\n            if self.code[k] == \"[\":\n                k = matrix(self, k)\n\n            elif self.code[k] == \"]\":\n                return k\n\n            elif self.code[k] == \"%\":\n                k = comment(self, k)\n\n            elif self.code[k] == \"'\" and identify.string(self, k):\n                k = string(self, k)\n\n            k += 1\n\n\ndef string(self, start):\n    \"\"\"\nFind end of string\n\nArgs:\n    self (Builder): Code constructor\n    start (int): current position in code\n\nReturns:\n\tint: index location of end of string\n    \"\"\"\n\n    if self.code[start] != \"'\":\n        self.syntaxerror(start, \"start of string (')\")\n\n    k = self.code.find(\"'\", start+1)\n    if k == -1:\n        self.syntaxerror(start, \"matching end of string (')\")\n\n    if self.code.find(\"\\n\", start, k) != -1:\n        self.syntaxerror(start, \"non line-feed character in string\")\n\n    return k\n\ndef pragma_for(self,start):\n    end = self.code.find(\"\\n\", start)\n    #while self.code[end+1] == \"%\"\n    #    end = self.code.find(\"\\n\", start+1)\n\n    if end <= -1:\n        self.syntaxerror(start, \"comment end\")\n    return end\n\ndef tbb_for(self, start):\n    end = self.code.find(\"\\n\", start)\n\n    if end <= -1:\n        self.syntaxerror(start, \"command end\")\n\n    return end\n\ndef comment(self, start):\n    \"\"\"\nFind end of comment\n\nArgs:\n    self (Builder): Code constructor\n    start (int): current position in code\n\nReturns:\n\tint: index location of end of comment\n    \"\"\"\n\n    if self.code[start] != \"%\":\n        self.syntaxerror(start, \"comment start\")\n\n    # block comment\n    if self.code[start+1] == \"{\":\n        eoc = self.code.find(\"%}\", start+2)\n\n        if eoc <= -1:\n            self.syntaxerror(start, \"matching end of comment block (%})\")\n\n        return eoc+1\n\n    # Line comment\n    eoc = self.code.find(\"\\n\", start)\n    if eoc <= -1:\n        self.syntaxerror(start, \"comment end\")\n    return eoc\n\n#should find the end of verbatim area\ndef verbatim(self, start):\n    \"\"\"\nFind end of verbatim\n\nArg:\n   self(Builder): Code constructor\n   start (int): current position in code\n\nReturns:\n   int: index location of end of verbatim\n     \"\"\"\n\n    if self.code[start:start+3] != \"___\":\n        self.syntaxerror(start, \"verbatim start\")\n    return self.code.find(\"\\n\", start)-1\n\n\ndef dots(self, start):\n    \"\"\"\nFind continuation of expression after ellipse\n\nArgs:\n    self (Builder): Code constructor\n    start (int): current position in code\n\nReturns:\n\tint: index location of end of ellipse\n    \"\"\"\n\n    if self.code[start:start+3] != \"...\":\n        self.syntaxerror(start, \"three dots (...)\")\n\n    k = self.code.find(\"\\n\", start)\n    if k == -1:\n        self.syntaxerror(start, \"next line feed character\")\n\n    return k\n\n\ndef paren(self, start):\n    \"\"\"\nFind matching parenthesis\n\nArgs:\n    self (Builder): Code constructor\n    start (int): current position in code\n\nReturns:\n\tint: index location of matching parenthesis\n    \"\"\"\n\n    if self.code[start] != \"(\":\n        self.syntaxerror(start, \"start parenthesis\")\n\n    k = start+1\n    while True:\n\n        if self.code[k] == \"%\":\n            self.syntaxerror(k, \"no comments in parenthesis\")\n\n        elif self.code[k:k+3] == \"...\":\n            k = dots(self, k)\n\n        elif self.code[k] == \"'\" and identify.string(self, k):\n            k = string(self, k)\n\n        elif self.code[k] == \"[\":\n            k = matrix(self, k)\n\n        elif self.code[k] == \"(\":\n            k = paren(self, k)\n\n        elif self.code[k] == \")\":\n            return k\n\n        k += 1\n\n\ndef cell(self, start):\n    \"\"\"\nFind matching cell-parenthesis\n\nArgs:\n    self (Builder): Code constructor\n    start (int): current position in code\n\nReturns:\n\tint: index location of matching cell-parenthesis\n    \"\"\"\n\n    if  self.code[start] != \"{\":\n        self.syntaxerror(start, \"start of cell ({)\")\n\n    k = start\n    while True:\n\n        if self.code[k] == \"%\":\n            self.syntaxerror(k, \"no comment in cell group\")\n\n        elif self.code[k] == \"'\" and identify.string(self, k):\n            k = string(self, k)\n        elif self.code[k] == \"(\":\n            k = paren(self, k)\n        elif self.code[k] == \"[\":\n            k = matrix(self, k)\n        elif self.code[k] == \"}\":\n            l = k+1\n            while self.code[l] in \" \\t\":\n                l += 1\n            if self.code[l] != \"{\":\n                return k\n            k = l\n\n        k += 1\n"
  },
  {
    "path": "src/matlab2cpp/tree/functions.py",
    "content": "\"\"\"\nFunctions, programs and meta-nodes\n\n+----------------------------------------------------+-------------------------+\n| Functions                                          | Description             |\n+====================================================+=========================+\n| :py:func:`~matlab2cpp.tree.functions.program`      | Program outer shell     |\n+----------------------------------------------------+-------------------------+\n| :py:func:`~matlab2cpp.tree.functions.function`     | Explicit functions      |\n+----------------------------------------------------+-------------------------+\n| :py:func:`~matlab2cpp.tree.functions.main`         | Main script             |\n+----------------------------------------------------+-------------------------+\n| :py:func:`~matlab2cpp.tree.functions.lambda_assign`| Anonymous function      |\n|                                                    | assignment              |\n+----------------------------------------------------+-------------------------+\n| :py:func:`~matlab2cpp.tree.functions.lambda_func`  | Anonymous function      |\n|                                                    | content                 |\n+----------------------------------------------------+-------------------------+\n\"\"\"\nfrom __future__ import print_function\nfrom . import constants, findend, iterate, identify\nfrom .. import collection\n\n\ndef program(self, name):\n    \"\"\"\n    The outer shell of the program\n\n    Args:\n        self (Builder):\n            Code constructor\n        name (str):\n            Name of the program\n\n    Returns:\n        Node: The root node of the constructed node tree\n\n    Example:\n        >>> from matlab2cpp.tree import Builder\n        >>> builder = Builder(True)\n        >>> builder.load(\"unamed\", \"a\") # doctest: +NORMALIZE_WHITESPACE\n        loading unamed\n             Program    functions.program\n           0 Main       functions.main\n           0 Codeblock  codeblock.codeblock\n           0   Statement    codeblock.codeblock 'a'\n           0     Expression expression.create   'a'\n           0     Var        variables.variable  'a'\n        >>> builder.configure(suggest=False)\n        >>> print(matlab2cpp.qtree(builder)) # doctest: +NORMALIZE_WHITESPACE\n        Program    program      TYPE    unamed\n        | Includes   program      TYPE\n        1 1| Funcs      program      TYPE    unamed\n        1 1| | Main       func_return  TYPE    main\n        1 1| | | Declares   func_return  TYPE\n        1 1| | | Returns    func_return  TYPE\n        1 1| | | Params     func_return  TYPE\n        1 1| | | Block      code_block   TYPE\n        1 1| | | | Statement  code_block   TYPE\n        1 1| | | | | Var        unknown      TYPE    a\n        | Inlines    program      TYPE    unamed\n        | Structs    program      TYPE    unamed\n        | Headers    program      TYPE    unamed\n        | Log        program      TYPE    unamed\n    \"\"\"\n    if self.disp:\n        print(\"     Program    \", end=\"\")\n        print(\"functions.program\")\n\n    # Create intial nodes\n    program = collection.Program(self.project, name=name, cur=0, code=self.code)\n    includes = collection.Includes(program, value=name, code='')\n    funcs = collection.Funcs(program, name=name)\n\n    collection.Inlines(program, name=name)\n    collection.Structs(program, name=name)\n    collection.Headers(program, name=name)\n    collection.Log(program, name=name)\n\n    #includes.include(\"armadillo\")\n    #includes.include(\"mconvert\")\n    # Start processing\n\n    cur = 0\n\n    while True:\n\n        if self.code[cur] in \" \\t;\\n\":\n            pass\n\n        elif self.code[cur] == \"%\":\n            cur = findend.comment(self, cur)\n\n        elif self.code[cur:cur+8] == \"function\":\n            cur = self.create_function(funcs, cur)\n\n        else:\n            self.create_main(funcs, cur)\n            break\n\n        if len(self.code)-cur<=2:\n            break\n        cur += 1\n\n    #includes.include(\"namespace_arma\")\n\n    return program\n\n\ndef function(self, parent, cur):\n    \"\"\"\n    Explicit functions\n\n    Args:\n        self (Builder): Code constructor\n        parent (Node): Parent node\n        cur (int): Current position in code\n\n    Returns:\n        int : Index to end of function\n\n    Example:\n        >>> from matlab2cpp.tree import Builder\n        >>> builder = Builder(True)\n        >>> builder.load(\"unnamed\", \"function f(); end\") # doctest: +NORMALIZE_WHITESPACE\n        loading unnamed\n             Program    functions.program\n           0 Function       functions.function  'function f()'\n          12 Codeblock  codeblock.codeblock\n        >>> builder.configure(suggest=False)\n        >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n        1  1Funcs      program      TYPE    unnamed\n        1  1| Func       func_returns TYPE    f\n        1  1| | Declares   func_returns TYPE\n        1  1| | Returns    func_returns TYPE\n        1 11| | Params     func_returns TYPE\n        1 13| | Block      code_block   TYPE\n\n        >>> builder = Builder(True)\n        >>> builder.load(\"unnamed\", \"function y=f(x); y=x\") # doctest: +NORMALIZE_WHITESPACE\n        loading unnamed\n             Program    functions.program\n           0 Function       functions.function  'function y=f(x)'\n           0   Return       'y'\n          12   Param        functions.function  'x'\n          15 Codeblock  codeblock.codeblock\n          17   Assign     assign.single       'y=x'\n          17     Var        variables.assign    'y'\n          19     Expression expression.create   'x'\n          19     Var        variables.variable  'x'\n        >>> builder.configure(suggest=False)\n        >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n         1   1Funcs      program      TYPE    unnamed\n         1   1| Func       func_return  TYPE    f\n         1   1| | Declares   func_return  TYPE\n         1   1| | | Var        unknown      TYPE    y\n         1   1| | Returns    func_return  TYPE\n         1  10| | | Var        unknown      TYPE    y\n         1  13| | Params     func_return  TYPE\n         1  14| | | Var        unknown      TYPE    x\n         1  16| | Block      code_block   TYPE\n         1  18| | | Assign     unknown      TYPE    x\n         1  18| | | | Var        unknown      TYPE    y\n         1  20| | | | Var        unknown      TYPE    x\n    \"\"\"\n    if self.code[cur:cur+8] != \"function\":\n        self.syntaxerror(cur, \"function start\")\n    if self.code[cur+8] not in constants.k_end+\"[\":\n        self.syntaxerror(cur, \"function name or return values\")\n\n    START = cur\n    k = cur + 8\n\n    while self.code[k] in \" \\t\":\n        k += 1\n\n    if  self.code[k] not in constants.letters+\"[\":\n        self.syntaxerror(k, \"function name or return values\")\n    start = k\n\n    k = findend.expression(self, k)\n    end = k\n\n    k += 1\n    while self.code[k] in \" \\t\":\n        k += 1\n\n    # with return values\n    if self.code[k] == \"=\":\n\n        k += 1\n        while self.code[k] in \" \\t.\":\n            if self.code[k:k+3] == \"...\":\n                k = findend.dots(self, k)+1\n            else:\n                k += 1\n\n        l = k\n        if  self.code[l] not in constants.letters:\n            self.syntaxerror(l, \"function name\")\n\n        while self.code[l+1] in constants.letters+constants.digits+\"_\":\n            l += 1\n\n        m = l+1\n\n        while self.code[m] in \" \\t\":\n            m += 1\n\n        if self.code[m] == \"(\":\n            m = findend.paren(self, m)\n        else:\n            m = l\n\n        if self.disp:\n            print(\"%4d Function       \" % cur, end=\"\")\n            print(\"%-20s\" % \"functions.function\", end=\"\")\n            print(repr(self.code[START:m+1]))\n\n        name = self.code[k:l+1]\n        func = collection.Func(parent, name, cur=cur)\n        collection.Declares(func, code=\"\")\n        returns = collection.Returns(func, code=self.code[start:end+1])\n\n        # multi-return\n        if self.code[start] == \"[\":\n            if identify.space_delimited(self, start):\n                L = iterate.space_list(self, start)\n            else:\n                L = iterate.comma_list(self, start)\n            end = START\n            for array in L:\n                for s,e in array:\n                    end = s\n\n                    if self.disp:\n                        print(\"%4d   Return       \" % cur, end=\"\")\n                        print(\"%-20s\" % \"functions.function\", end=\"\")\n                        print(repr(self.code[s:e+1]))\n\n                    if not any([a in constants.letters+constants.digits+\"_@\" \\\n                                for a in self.code[s:e+1]]):\n                        self.syntaxerror(s, \"return value\")\n\n                    collection.Var(returns, self.code[s:e+1], cur=s,\n                                   code=self.code[s:e+1])\n\n        # single return\n        else:\n            end = findend.expression(self, start)\n\n            if self.disp:\n                print(\"%4d   Return       \" % cur, end=\"\")\n                print(repr(self.code[start:end+1]))\n\n            collection.Var(returns, self.code[start:end+1], cur=start,\n                           code=self.code[start:end+1])\n\n\n        cur = l+1\n        while self.code[cur] in \" \\t\":\n            cur += 1\n\n    # No returns\n    else:\n        m = k\n        if self.code[m] == \"(\":\n            m = findend.paren(self, m)\n        else:\n            m = end\n\n\n        if self.disp:\n            print(\"%4d Function       \" % cur, end=\"\")\n            print(\"%-20s\" % \"functions.function\", end=\"\")\n            print(repr(self.code[START:m+1]))\n\n        end = start+1\n        while self.code[end] in constants.letters+\"_\":\n            end += 1\n\n        name = self.code[start:end]\n        func = collection.Func(parent, name, cur=cur)\n\n        collection.Declares(func)\n        returns = collection.Returns(func)\n\n        cur = end\n\n    # Parameters\n    params = collection.Params(func, cur=cur)\n    if self.code[cur] == \"(\":\n\n        end = findend.paren(self, cur)\n        params.code = self.code[cur+1:end]\n\n        L = iterate.comma_list(self, cur)\n        for array in L:\n            for s,e in array:\n\n                if self.disp:\n                    print(\"%4d   Param        \" % cur, end=\"\")\n                    print(\"%-20s\" % \"functions.function\", end=\"\")\n                    print(repr(self.code[s:e+1]))\n\n                var = collection.Var(params, self.code[s:e+1], cur=s,\n                                     code=self.code[s:e+1])\n\n        cur = end\n\n    cur += 1\n\n    cur = self.create_codeblock(func, cur)\n\n    # Postfix\n    for var in returns:\n        var.create_declare()\n\n    end = cur\n    func.code = self.code[START:end+1]\n\n    collection.Header(func.program[4], func.name)\n\n    return cur\n\n\ndef main(self, parent, cur):\n    \"\"\"\n    Main script\n\n    Args:\n        self (Builder): Code constructor\n        parent (Node): Parent node\n        cur (int): Current position in code\n\n    Returns:\n        int : Index to end of script\n\n    Example:\n        >>> from matlab2cpp.tree import Builder\n        >>> builder = Builder(True)\n        >>> builder.load(\"unnamed\", \"a\") # doctest: +NORMALIZE_WHITESPACE\n        loading unnamed\n             Program    functions.program\n           0 Main       functions.main\n           0 Codeblock  codeblock.codeblock\n           0   Statement    codeblock.codeblock 'a'\n           0     Expression expression.create   'a'\n           0     Var        variables.variable  'a'\n        >>> builder.configure(suggest=False)\n        >>> print(matlab2cpp.qtree(builder)) # doctest: +NORMALIZE_WHITESPACE\n        Program    program      TYPE    unnamed\n        | Includes   program      TYPE\n        1 1| Funcs      program      TYPE    unnamed\n        1 1| | Main       func_return  TYPE    main\n        1 1| | | Declares   func_return  TYPE\n        1 1| | | Returns    func_return  TYPE\n        1 1| | | Params     func_return  TYPE\n        1 1| | | Block      code_block   TYPE\n        1 1| | | | Statement  code_block   TYPE\n        1 1| | | | | Var        unknown      TYPE    a\n        | Inlines    program      TYPE    unnamed\n        | Structs    program      TYPE    unnamed\n        | Headers    program      TYPE    unnamed\n        | Log        program      TYPE    unnamed\n    \"\"\"\n\n    if self.disp:\n        print(\"%4d Main       \" % cur, end=\"\")\n        print(\"functions.main\")\n\n    func = collection.Main(parent)\n\n    collection.Declares(func)#, backend=\"func_return\")\n    collection.Returns(func)#, backend=\"func_return\")\n    collection.Params(func)#, backend=\"func_return\")\n\n    return self.create_codeblock(func, cur)\n\n\ndef lambda_assign(self, node, cur, eq_loc):\n    \"\"\"\n    Anonymous function constructor\n\n    Args:\n        self (Builder): Code constructor\n        parent (Node): Parent node\n        cur (int): Current position in code\n        eq_loc (int): location of assignment sign ('=')\n\n    Returns:\n        int : Index to end of function line\n\n    Example:\n        >>> from matlab2cpp.tree import Builder\n        >>> builder = Builder(True)\n        >>> builder.load(\"unnamed\", \"f = @(x) 2*x\") # doctest: +NORMALIZE_WHITESPACE\n        loading unnamed\n             Program    functions.program\n           0 Main       functions.main\n           0 Codeblock  codeblock.codeblock\n           0   Assign       'f = @(x) 2*x' functions.lambda_assign\n           0     Var        variables.assign    'f'\n           4   Lambda       functions.lambda_func'@(x) 2*x'\n           6     Expression expression.create   'x'\n           6     Var        variables.variable  'x'\n           9     Expression expression.create   '2*x'\n           9     Expression expression.create   '2'\n           9     Int        misc.number         '2'\n          11     Expression expression.create   'x'\n          11     Var        variables.variable  'x'\n        >>> builder.configure(suggest=False)\n        >>> print(matlab2cpp.qtree(builder)) # doctest: +NORMALIZE_WHITESPACE\n        Program    program      TYPE    unnamed\n        | Includes   program      TYPE\n        1  1| Funcs      program      TYPE    unnamed\n        1  1| | Main       func_return  TYPE    main\n        1  1| | | Declares   func_return  TYPE\n        1  1| | | | Var        func_lambda  TYPE    f\n        1  1| | | Returns    func_return  TYPE\n        1  1| | | Params     func_return  TYPE\n        1  1| | | Block      code_block   TYPE\n        1  1| | | | Assign     func_lambda  func_lambda\n        1  1| | | | | Var        func_lambda  TYPE    f\n        1  1| | | | | Lambda     func_lambda  func_lambda_f\n        1  5| | Func       func_lambda  TYPE    _f\n        1  5| | | Declares   func_lambda  TYPE\n        1  5| | | | Var        unknown      TYPE    _retval\n        1  5| | | Returns    func_lambda  TYPE\n        1  5| | | | Var        unknown      TYPE    _retval\n        1  5| | | Params     func_lambda  TYPE\n        1  7| | | | Var        unknown      TYPE    x\n        1  5| | | Block      code_block   TYPE\n        1  5| | | | Assign     expression   TYPE\n        1  5| | | | | Var        unknown      TYPE    _retval\n        1 10| | | | | Mul        expression   TYPE\n        1 10| | | | | | Int        int          int\n        1 12| | | | | | Var        unknown      TYPE    x\n        | Inlines    program      TYPE    unnamed\n        | Structs    program      TYPE    unnamed\n        | Headers    program      TYPE    unnamed\n        | Log        program      TYPE    unnamed\n    \"\"\"\n\n    if  self.code[cur] not in constants.letters:\n        self.syntaxerror(cur, \"anonymous function name\")\n\n    if  self.code[eq_loc] != \"=\":\n        self.syntaxerror(cur, \"anonymous function assignment (=)\")\n\n    if self.disp:\n        print(\"%4d   Assign       \" % cur, end=\"\")\n        print(repr(self.code[cur:self.code.find(\"\\n\", cur)]), end=\" \")\n        print(\"functions.lambda_assign\")\n\n    assign = collection.Assign(node, cur=cur)#, backend=\"func_lambda\")\n\n    self.create_assign_variable(assign, cur, eq_loc)\n\n    k = eq_loc+1\n    while self.code[k] in \" \\t\":\n        k += 1\n\n    end = self.create_lambda_func(assign, k)\n    assign.code = self.code[cur:end+1]\n\n    return end\n\ndef lambda_func(self, node, cur):\n    \"\"\"\n    Anonymous function content. Support function of `lambda_assign`.\n\n    Args:\n        self (Builder): Code constructor\n        parent (Node): Parent node\n        cur (int): Current position in code\n\n    Returns:\n        int : Index to end of function line\n    \"\"\"\n    if  self.code[cur] != \"@\":\n        self.syntaxerror(cur, \"anonymous function indicator (@)\")\n\n    end = cur +1\n    while self.code[end] in \" \\t\":\n        end += 1\n\n    if  self.code[end] != \"(\":\n        self.syntaxerror(end, \"anonymous function argument list\")\n\n    end = findend.paren(self, end)\n\n    end += 1\n    while self.code[end] in \" \\t\":\n        end += 1\n\n    end = findend.expression(self, end)\n\n    if self.disp:\n        print(\"%4d   Lambda       \" % cur, end=\"\")\n        print(\"%-20s\" % \"functions.lambda_func\", end=\"\")\n        print(repr(self.code[cur:end+1]))\n\n    if node.cls == \"Assign\":\n        name = node[0].name\n    else:\n        name = \"lambda\"\n\n    funcs = node.program[1]\n    name = \"_%s\" % (name)\n    if name in funcs.names:\n        i = 0\n        while name+\"%d\" % i in funcs.names:\n            i += 1\n        name = name + \"%d\" % i\n\n    func = collection.Func(funcs, name, cur=cur, code=self.code[cur:end+1])\n\n    declares = collection.Declares(func)\n    returns = collection.Returns(func)\n    params = collection.Params(func)\n\n    k = cur+1\n    while self.code[k] in \" \\t\":\n        k += 1\n\n    if  self.code[k] != \"(\":\n        self.syntaxerror(k, \"anonymous function argument list\")\n\n    cur = self.create_list(params, k)\n\n    cur += 1\n    while self.code[cur] in \" \\t\":\n        cur += 1\n\n    block = collection.Block(func)\n    assign = collection.Assign(block)\n    var = collection.Var(assign, \"_retval\")\n\n    cur = self.create_expression(assign, cur, end=end)\n\n    for n in assign[1].flatten():\n        if (n.cls in (\"Get\", \"Cget\", \"Var\", \"Fvar\", \"Fget\",\n                      \"Sget\")) and n.name in node.func[0].names + node.func[2].names:\n\n            n.create_declare()\n\n\n    var = collection.Var(returns, \"_retval\")\n    var.create_declare()\n\n    lamb = collection.Lambda(node, name)\n\n    lamb.reference = func\n\n    return cur\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "src/matlab2cpp/tree/identify.py",
    "content": "\"\"\"\nRutines for identifying code structure.\n\n+------------------------------------------------------+-----------------------+\n| Function                                             | Description           |\n+======================================================+=======================+\n| :py:func:`~matlab2cpp.tree.identify.space_delimiter` | Check if at expression|\n|                                                      | space-delimiter       |\n+------------------------------------------------------+-----------------------+\n| :py:func:`~matlab2cpp.tree.identify.string`          | Check if at string    |\n|                                                      | start                 |\n+------------------------------------------------------+-----------------------+\n| :py:func:`~matlab2cpp.tree.identify.space_delimited` | Check if list is      |\n|                                                      | space-delimited       |\n+------------------------------------------------------+-----------------------+\n\"\"\"\nfrom . import constants\n\n\ndef space_delimiter(self, start):\n    \"\"\"\nCheck if mid-expression space-delimiter. This already assumes that position is\nin the middle of a space delimited list. Use `space_delimited` to check if\na list is space or comma delimited.\n\nArgs:\n    self (Builder): Code constructor\n    start (int): Current position in code\n\nReturns:\n\tbool: True if whitespace character classifies as a delimiter\n    \"\"\"\n\n    if self.code[start] not in \" \\t\":\n        self.syntaxerror(start, \"space delimiter\")\n\n    k = start\n\n    while True:\n\n        if self.code[k:k+3] == \"...\":\n            return False\n\n        elif self.code[k] in \" \\t\":\n            pass\n\n        elif self.code[k] in \"+-~\":\n            if self.code[k+1] in \" \\t\":\n                return False\n\n        elif self.code[k:k+2] in constants.op2:\n            return False\n\n        elif self.code[k] in constants.op1:\n            return False\n\n        else:\n            return True\n\n        k += 1\n\n\ndef string(self, k):\n    \"\"\"\nCheck if at string start\n\nArgs:\n    self (Builder): Code constructor\n    k (int): Current position in code\n\nReturns:\n\tbool: True if character classifies as start of string.\n    \"\"\"\n\n    if self.code[k] != \"'\":\n        self.syntaxerror(k, \"start of string character (')\")\n\n    if self.code[k-1] == \".\":\n        return False\n\n    j = k-1\n    while self.code[j] in \" \\t\":\n        j -= 1\n\n    if self.code[j] in constants.letters+constants.digits+\")]}_\":\n\n        # special cases\n        if self.code[j-3:j+1] == \"case\":\n            return True\n\n        return False\n\n    return True\n\n\ndef space_delimited(self, start):\n    \"\"\"\nCheck if list is space-delimited\n\nArgs:\n    self (Builder): Code constructor\n    start (int): Current position in code\n\nReturns:\n\tbool: True if list consists of whitespace delimiters\n    \"\"\"\n    from . import findend\n\n    if  self.code[start] not in constants.l_start:\n        self.syntaxerror(start, \"list start\")\n\n    k = start+1\n    while self.code[k] in \" \\t\":\n        k += 1\n\n    if self.code[k] in constants.l_end:\n        return False\n\n    if  self.code[k] not in constants.e_start:\n        self.syntaxerror(k, \"expression start\")\n\n    if self.code[k] == \"'\":\n        k = findend.string(self, k)+1\n\n        while self.code[k] in \" \\t\":\n            k += 1\n\n    while True:\n\n        if self.code[k] == \"(\":\n            k = findend.paren(self, k)\n\n        elif self.code[k] == \"[\":\n            k = findend.matrix(self, k)\n\n        elif self.code[k] == \"{\":\n            k = findend.cell(self, k)\n\n        elif self.code[k] == \"'\" and string(self, k):\n            #k = findend.string(self, k)\n            #if self.code[k-1] in constants.s_start:\n            return True\n\n        elif self.code[k:k+3] == \"...\":\n            k = findend.dots(self, k)\n\n        elif self.code[k] in \" \\t\":\n            if space_delimiter(self, k):\n                return True\n            while self.code[k+1] in \" \\t\":\n                k += 1\n\n        elif self.code[k] in constants.e_end:\n            if self.code[k] == \",\":\n                return False\n            elif self.code[k] in constants.l_end:\n                return False\n            elif self.code[k] != \";\":\n                return True\n            elif self.code[k] == \"\\n\":\n                return True\n\n            while self.code[k+1] in \" \\t\":\n                k += 1\n\n        elif self.code[k+1] in constants.letters + constants.digits + \"_@\":\n            while self.code[k+1] in constants.letters + constants.digits + \"_@\":\n                k += 1\n        k += 1\n"
  },
  {
    "path": "src/matlab2cpp/tree/iterate.py",
    "content": "\"\"\"\nRutines for iterating lists\n\n+------------------------------------------------+----------------------+\n| Functions                                      | Description          |\n+================================================+======================+\n| :py:func:`~matlab2cpp.tree.iterate.comma_list` | Iterate over a comma |\n|                                                | separated list       |\n+------------------------------------------------+----------------------+\n| :py:func:`~matlab2cpp.tree.iterate.space_list` | Iterate over a space |\n|                                                | delimited list       |\n+------------------------------------------------+----------------------+\n\"\"\"\n\nfrom . import constants as c, findend, identify\n\n\ndef comma_list(self, start):\n    \"\"\"\nIterate over a comma separated list\n\nArgs:\n    self (Builder): Code constructor\n    start (int): Current position in code\n\nReturns:\n    list : A list of 2-tuples that represents index start and end for each\n    expression in list\n    \"\"\"\n\n    if  self.code[start] not in c.l_start:\n        self.syntaxerror(start, \"list start\")\n    k = start+1\n\n    while self.code[k] in \" \\t\":\n        k += 1\n\n    if self.code[k] in \"]}\":\n        return [[]]\n\n    out = [[]]\n    count = False\n\n    while True:\n\n        if self.code[k:k+3] == \"...\":\n            k = findend.dots(self, k)\n\n        elif self.code[k] in c.e_start:\n\n            if count:\n                self.syntaxerror(k, \"comma list indicator\")\n\n            count = True\n            end = findend.expression(self, k)\n            out[-1].append((k, end))\n\n            k = end\n\n        elif self.code[k] == \",\":\n\n            if not count:\n                self.syntaxerror(k, \"comma list indicator\")\n\n            count = False\n\n        elif self.code[k] == \";\":\n\n            if not count:\n                self.syntaxerror(k, \"comma list indicator\")\n\n            count = False\n            out.append([])\n\n        elif self.code[k] in c.l_end:\n            return out\n\n        k += 1\n\n\n\ndef space_list(self, start):\n    \"\"\"\nIterate over a space delimited list\n\nArgs:\n    self (Builder): Code constructor\n    start (int): Current position in code\n\nReturns:\n    list : A list of 2-tuples that represents index start and end for each\n    expression in list\n    \"\"\"\n\n    if  self.code[start] not in c.l_start:\n        self.syntaxerror(start, \"start of list\")\n\n    k = start+1\n    while self.code[k] in \" \\t\":\n        k += 1\n\n    out = [[]]\n    count = False\n    dots = False\n\n    while True:\n\n        if self.code[k:k+3] == \"...\":\n            k = findend.dots(self, k)\n            dots = True\n            \n        if self.code[k] in \";\\n\":\n            if not dots:\n                out.append([])\n                dots = False\n                \n            count = False\n            if self.code[k] == \";\": # and self.code[k+1] == \"\\n\":\n                while self.code[k+1] in \" \\n\":\n                    k += 1\n            \n        if self.code[k] in c.e_start:\n\n            if count:\n                self.syntaxerror(k, \"expression start\")\n\n            count = True\n\n            end = findend.expression_space(self, k)\n            out[-1].append((k, end))\n            k = end\n\n        elif self.code[k] in c.l_end:\n            return out\n\n        elif self.code[k] in \" \\t\":\n            count = False\n\n        k += 1\n"
  },
  {
    "path": "src/matlab2cpp/tree/misc.py",
    "content": "\"\"\"Interpretors that didn't fit other places\"\"\"\nfrom __future__ import print_function\nfrom .. import collection\nfrom . import constants as c, findend, expression, iterate, identify\n\n\ndef number(self, node, start):\n    \"\"\"\n    Verbatim number\n\n    Args:\n        self (Builder): Code constructor\n        node (Node): Parent node\n        start (int): Current position in code\n\n    Returns:\n        int : End of number\n\n    Example:\n        >>> from matlab2cpp.tree import Builder\n        >>> builder = Builder(True)\n        >>> builder.load(\"unnamed\", \"42.\") # doctest: +NORMALIZE_WHITESPACE\n        loading unnamed\n             Program    functions.program\n           0 Main       functions.main\n           0 Codeblock  codeblock.codeblock\n           0   Statement    codeblock.codeblock '42.'\n           0     Expression expression.create   '42.'\n           0     Float      misc.number         '42.'\n        >>> builder.configure()\n        >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n        1 1Block      code_block   TYPE\n        1 1| Statement  code_block   TYPE\n        1 1| | Float      double       double\n    \"\"\"\n\n    if not (self.code[start] in c.digits or\\\n            self.code[start] == \".\" and self.code[start+1] in c.digits):\n        self.syntaxerror(start, \"number\")\n\n    k = start\n\n    while self.code[k] in c.digits:\n        k += 1\n    last = k-1\n\n    integer = True\n    if self.code[k] == \".\" and \\\n            (self.code[k+1:k+3] != \"..\" and self.code[k+1] not in \"*/\"): \n        integer = False\n\n        k += 1\n        while self.code[k] in c.digits:\n            k += 1\n        last = k-1\n\n    if self.code[k] in \"eEdD\":\n\n        exp = k\n\n        k = k+1\n        if self.code[k] in \"+-\":\n            k += 1\n\n        while self.code[k] in c.digits:\n            k += 1\n\n        number = self.code[start:exp] + \"e\" + self.code[exp+1:k]\n\n        last = k-1\n\n        if self.code[k] in \"ij\":\n\n            k += 1\n            node = collection.Imag(node, number, cur=start,\n                                   code=self.code[start:last+1])\n            if self.disp:\n                print(\"%4d     Imag       \" % (start), end=\"\")\n                print(\"%-20s\" % \"misc.number\", end=\"\")\n                print(repr(self.code[start:last+1]))\n\n        else:\n            node = collection.Float(node, number, cur=start,\n                                    code=self.code[start:last+1])\n            if self.disp:\n                print(\"%4d     Float      \" % (start), end=\"\")\n                print(\"%-20s\" % \"misc.number\", end=\"\")\n                print(repr(self.code[start:last+1]))\n\n    elif integer:\n\n        number = self.code[start:k]\n\n        if self.code[k] in \"ij\":\n\n            node = collection.Imag(node, self.code[start:k], cur=start,\n                                   code=self.code[start:last+1])\n            k += 1\n            if self.disp:\n                print(\"%4d     Imag       \" % (start), end=\"\")\n                print(\"%-20s\" % \"misc.number\", end=\"\")\n                print(repr(self.code[start:last+1]))\n\n        else:\n            node = collection.Int(node, self.code[start:k], cur=start,\n                                  code=self.code[start:last+1])\n            if self.disp:\n                print(\"%4d     Int        \" % (start), end=\"\")\n                print(\"%-20s\" % \"misc.number\", end=\"\")\n                print(repr(self.code[start:last+1]))\n\n    else:\n\n        if self.code[k] in \"ij\":\n\n            node = collection.Imag(node, self.code[start:k], cur=start,\n                                   code=self.code[start:last+1])\n            k += 1\n            if self.disp:\n                print(\"%4d     Imag       \" % (start), end=\"\")\n                print(\"%-20s\" % \"misc.number\", end=\"\")\n                print(repr(self.code[start:last+1]))\n\n        else:\n            node = collection.Float(node, self.code[start:k], cur=start,\n                                    code=self.code[start:k])\n            if self.disp:\n                print(\"%4d     Float      \" % (start), end=\"\")\n                print(\"%-20s\" % \"misc.number\", end=\"\")\n                print(repr(self.code[start:last+1]))\n\n    return k-1\n\n\ndef string(self, parent, cur):\n    \"\"\"\n    Verbatim string\n\n    Args:\n        self (Builder): Code constructor\n        parent (Node): Parent node\n        start (int): Current position in code\n\n    Returns:\n        int : End of string\n\n    Example:\n        >>> from matlab2cpp.tree import Builder\n        >>> builder = Builder(True)\n        >>> builder.load(\"unnamed\", \"'abc'\") # doctest: +NORMALIZE_WHITESPACE\n        loading unnamed\n             Program    functions.program\n           0 Main       functions.main\n           0 Codeblock  codeblock.codeblock\n           0   Statement    codeblock.codeblock \"'abc'\"\n           0     String misc.string         \"'abc'\"\n        >>> builder.configure()\n        >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n        1 1Block      code_block   TYPE\n        1 1| Statement  code_block   TYPE\n        1 1| | String     string       string\n    \"\"\"\n\n    end = findend.string(self, cur)\n\n    if  \"\\n\" in self.code[cur:end]:\n        self.syntaxerror(cur, \"no line-feed character in string\")\n\n    collection.String(parent, self.code[cur+1:end], cur=cur,\n                      code=self.code[cur:end+1])\n\n    if self.disp:\n        print(\"%4d     String \" % cur, end=\"\")\n        print(\"%-20s\" % \"misc.string\", end=\"\")\n        print(repr(self.code[cur:end+1]))\n\n    return end\n\n\ndef list(self, parent, cur):\n    \"\"\"\n    A list (both comma or space delimited)\n\n    Args:\n        self (Builder): Code constructor\n        parent (Node): Parent node\n        cur (int): Current position in code\n\n    Returns:\n        int : End of list\n\n    Example:\n        >>> from matlab2cpp.tree import Builder\n        >>> builder = Builder(True)\n        >>> builder.load(\"unnamed\", \"[2 -3]\") # doctest: +NORMALIZE_WHITESPACE\n        loading unnamed\n             Program    functions.program\n           0 Main       functions.main\n           0 Codeblock  codeblock.codeblock\n           0   Statement    codeblock.codeblock '[2 -3]'\n           0     Expression expression.create   '[2 -3]'\n           0     Matrix     misc.matrix         '[2 -3]'\n           1     Vector     misc.matrix         '2 -3'\n           1     Expression expression.create   '2'\n           1     Int        misc.number         '2'\n           3     Expression expression.create   '-3'\n           4     Int        misc.number         '3'\n        >>> builder.configure(suggest=False)\n        >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n        1  1Block      code_block   TYPE\n        1  1| Statement  code_block   TYPE\n        1  1| | Matrix     matrix       irowvec\n        1  2| | | Vector     matrix       irowvec\n        1  2| | | | Int        int          int\n        1  4| | | | Neg        expression   int\n        1  5| | | | | Int        int          int\n    \"\"\"\n\n    if  self.code[cur] not in \"({\":\n        self.syntaxerror(cur, \"start of list character\")\n\n    end = cur\n    for vector in iterate.comma_list(self, cur):\n        for start,end in vector:\n            self.create_expression(parent, start, end)\n\n    end += 1\n    while self.code[end] in \" \\t\":\n        end += 1\n\n    if self.code[end] not in \")}\":\n        self.syntaxerror(cur, \"end of list character\")\n\n    return end\n\ndef pragma_for(self, parent, cur):\n\n    assert parent.cls == \"Block\"\n\n    if self.code[cur:cur+8] != \"%#PARFOR\":\n        self.syntaxerror(cur, \"pragma_for\")\n\n    k = cur+8\n\n    end = findend.pragma_for(self, k)\n\n    if self.disp:\n        print(\"%4d   Pragma_for   \" % cur, end=\"\")\n        print(\"%-20s\" % \"misc.pragma_for\", end=\"\")\n        print(repr(self.code[cur:end]))\n\n    collection.Pragma_for(parent, self.code[cur+1:end], cur=cur)\n\n    return end\n\ndef comment(self, parent, cur):\n    \"\"\"\n    Comments on any form\n\n    Args:\n        self (Builder): Code constructor\n        parent (Node): Parent node\n        cur (int): Current position in code\n\n    Returns:\n        int : End of comment\n\n    Example:\n        >>> from matlab2cpp.tree import Builder\n        >>> builder = Builder(True, comments=True)\n        >>> builder.load(\"unnamed\", \"4 % comment\") # doctest: +NORMALIZE_WHITESPACE\n        loading unnamed\n             Program    functions.program\n           0 Main       functions.main\n           0 Codeblock  codeblock.codeblock\n           0   Statement    codeblock.codeblock '4'\n           0     Expression expression.create   '4'\n           0     Int        misc.number         '4'\n           2   Comment      misc.comment        '% comment'\n        >>> builder.configure(suggest=False)\n        >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n        1  1Block      code_block   TYPE\n        1  1| Statement  code_block   TYPE\n        1  1| | Int        int          int\n        1  3| Ecomment   code_block   TYPE\n    \"\"\"\n    assert parent.cls == \"Block\"\n\n    if  self.code[cur] != \"%\":\n        self.syntaxerror(cur, \"comment\")\n\n    end = findend.comment(self, cur)\n\n    if not self.comments:\n        return end\n\n    if self.disp:\n        print(\"%4d   Comment      \" % cur, end=\"\")\n        print(\"%-20s\" % \"misc.comment\", end=\"\")\n        print(repr(self.code[cur:end]))\n\n    if self.code[cur+1] == \"{\":\n        comment = collection.Bcomment(parent, self.code[cur+2:end-1], cur=cur)\n    else:\n        k = cur-1\n        while self.code[k] in \" \\t\":\n            k -= 1\n        if self.code[k] == \"\\n\":\n            comment = collection.Lcomment(parent, self.code[cur+1:end], cur=cur)\n        else:\n            comment = collection.Ecomment(parent, self.code[cur+1:end], cur=cur)\n\n    comment.code = self.code[cur:end+1]\n    return end\n\ndef verbatim(self, parent, cur):\n    \"\"\"\n    Verbatim, indicated by _\n\n    Args:\n        self (Builder): Code constructor\n        parent (Node): Parent node\n        cur (int): Current position in code\n\n    Returns:\n        int : End of verbatim\n    \"\"\"\n    assert parent.cls == \"Block\"\n\n    end = findend.verbatim(self, cur)\n\n    if self.disp:\n        print(\"%4d   Verbatim     \" % cur, end=\"\")\n        print(\"%-20s\" % \"misc.verbatim\", end=\"\")\n        print(repr(self.code[cur:end+1]))\n\n    keys = self.code[cur:end+1].split(\"___\")\n    name = keys[1]\n    value = \"\\n\".join(keys[2:])\n    verbatim = collection.Verbatim(\n        parent, name, value, cur=cur, code=self.code[cur:end+1])\n\n    return end\n\ndef matrix(self, node, cur):\n    \"\"\"\n    Verbatim matrices\n\n    Args:\n        self (Builder): Code constructor\n        node (Node): Parent node\n        cur (int): Current position in code\n\n    Returns:\n        int : End of matrix\n\n    Example:\n        >>> from matlab2cpp.tree import Builder\n        >>> builder = Builder(True)\n        >>> builder.load(\"unnamed\", \"[[1 2] [3 4]]\") # doctest: +NORMALIZE_WHITESPACE\n        loading unnamed\n             Program    functions.program\n           0 Main       functions.main\n           0 Codeblock  codeblock.codeblock\n           0   Statement    codeblock.codeblock '[[1 2] [3 4]]'\n           0     Expression expression.create   '[[1 2] [3 4]]'\n           0     Matrix     misc.matrix         '[[1 2] [3 4]]'\n           1     Vector     misc.matrix         '[1 2] [3 4]'\n           1     Expression expression.create   '[1 2]'\n           1     Matrix     misc.matrix         '[1 2]'\n           2     Vector     misc.matrix         '1 2'\n           2     Expression expression.create   '1'\n           2     Int        misc.number         '1'\n           4     Expression expression.create   '2'\n           4     Int        misc.number         '2'\n           7     Expression expression.create   '[3 4]'\n           7     Matrix     misc.matrix         '[3 4]'\n           8     Vector     misc.matrix         '3 4'\n           8     Expression expression.create   '3'\n           8     Int        misc.number         '3'\n          10     Expression expression.create   '4'\n          10     Int        misc.number         '4'\n        >>> builder.configure(suggest=False)\n        >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n        1   1Block      code_block   TYPE\n        1   1| Statement  code_block   TYPE\n        1   1| | Matrix     matrix       irowvec\n        1   2| | | Vector     matrix       irowvec\n        1   2| | | | Matrix     matrix       irowvec\n        1   3| | | | | Vector     matrix       irowvec\n        1   3| | | | | | Int        int          int\n        1   5| | | | | | Int        int          int\n        1   8| | | | Matrix     matrix       irowvec\n        1   9| | | | | Vector     matrix       irowvec\n        1   9| | | | | | Int        int          int\n        1  11| | | | | | Int        int          int\n    \"\"\"\n    if  self.code[cur] != \"[\":\n        self.syntaxerror(cur, \"bracket start\")\n\n    end = findend.matrix(self, cur)\n    if self.disp:\n        print(\"%4d     Matrix     \" % cur, end=\"\")\n        print(\"%-20s\" % \"misc.matrix\", end=\"\")\n        print(repr(self.code[cur:end+1]))\n\n    if identify.space_delimited(self, cur):\n        L = iterate.space_list(self, cur)\n    else:\n        L = iterate.comma_list(self, cur)\n    matrix = collection.Matrix(node, cur=cur, code=self.code[cur:end+1])\n\n    for array in L:\n\n        if array:\n            start = array[0][0]\n            end = array[-1][-1]\n        else:\n            start = cur\n\n        vector = collection.Vector(matrix, cur=start,\n                                   code=self.code[start:end+1])\n\n        if self.disp:\n            print(\"%4d     Vector     \" % (start), end=\"\")\n            print(\"%-20s\" % \"misc.matrix\", end=\"\")\n            print(repr(self.code[start:end+1]))\n\n        for start,end in array:\n\n            self.create_expression(vector, start, end)\n\n    if not L:\n\n        if self.disp:\n            print(\"%4d     Vector     \" % cur, end=\"\")\n            print(\"%-20s\" % \"misc.matrix\", end=\"\")\n            print(repr(\"\"))\n        vector = collection.Vector(matrix, cur=cur, code=\"\")\n\n\n    return findend.matrix(self, cur)\n\n\ndef cell(self, node, cur):\n    \"\"\"\n    Verbatim cells\n\n    Args:\n        self (Builder): Code constructor\n        node (Node): Parent node\n        cur (int): Current position in code\n\n    Returns:\n        int : End of cell\n\n    Example:\n        >>> from matlab2cpp.tree import Builder\n        >>> builder = Builder(True)\n        >>> builder.load(\"unnamed\", \"{1, 2}\") # doctest: +NORMALIZE_WHITESPACE\n        loading unnamed\n             Program    functions.program\n           0 Main       functions.main\n           0 Codeblock  codeblock.codeblock\n           0   Statement    codeblock.codeblock '{1, 2}'\n           0     Expression expression.create   '{1, 2}'\n           0     Cell       misc.cell           '{1, 2}'\n           1     Expression expression.create   '1'\n           1     Int        misc.number         '1'\n           4     Expression expression.create   '2'\n           4     Int        misc.number         '2'\n        >>> builder.configure(suggest=False)\n        >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n        1 1Block      code_block   TYPE\n        1 1| Statement  code_block   TYPE\n        1 1| | Cell       cell         TYPE\n        1 2| | | Int        int          int\n        1 5| | | Int        int          int\n    \"\"\"\n    if  self.code[cur] != \"{\":\n        self.syntaxerror(cur, \"curly braces\")\n\n    end = findend.cell(self, cur)\n    if self.disp:\n        print(\"%4d     Cell       \" % cur, end=\"\")\n        print(\"%-20s\" % \"misc.cell\", end=\"\")\n        print(repr(self.code[cur:end+1]))\n\n    if identify.space_delimited(self, cur):\n        L = iterate.space_list(self, cur)\n    else:\n        L = iterate.comma_list(self, cur)\n    cell = collection.Cell(node, cur=cur, code=self.code[cur:end+1])\n\n    for array in L:\n\n        if array:\n            start = array[0][0]\n            end = array[-1][-1]\n        else:\n            start = cur\n\n        for start, end in array:\n\n            self.create_expression(cell, start, end)\n\n    return findend.cell(self, cur)\n\n\ndef reserved(self, node, start):\n    \"\"\"Reserved keywords\"\"\"\n    k = start\n\n    l = k\n\n    while self.code[l] not in \";\\n\":\n        l += 1\n    newline = l\n\n    if self.disp:\n        print(\"%4d     reserved       \" % k, end=\"\")\n        print(\"%-20s\" % \"misc.reserved\", end=\"\")\n        print(repr(self.code[k:newline]))\n\n    if self.code[k:k+4] == \"disp\":\n        statement = collection.Statement(node, cur=start,\n                                         code=self.code[start:newline])\n\n        l = k+4\n        while self.code[l] in \" \\t\":\n            l += 1\n\n        if self.code[l] == \"(\":\n            return expression.create(self, statement, k)\n\n        k += 4\n        while self.code[k] in \" \\t\":\n            k += 1\n\n        name = \"\"\n        if self.code[k] == \"\\'\":\n            l = findend.string(self, k)\n            name = str(self.code[k+1:l])\n        else:\n            l = k\n            while self.code[l] not in \" \\t\\n\":\n                l += 1\n            name = str(self.code[k:l])\n\n        get = collection.Get(statement, name=\"disp\", cur=start, value=self.code[k:l])\n\n        #name = str(self.code[k+1:l])\n        node = collection.String(get, name)\n        #node.create_declare()\n\n        while self.code[k] not in \";\\n\":\n            k += 1\n\n\n        return k\n\n\n    if self.code[k:k+4] == \"load\":\n\n        statement = collection.Statement(node, cur=start,\n                                         code=self.code[start:newline])\n\n        l = k+4\n        while self.code[l] in \" \\t\":\n            l += 1\n\n        if self.code[l] == \"(\":\n            return expression.create(self, statement, k)\n\n        k += 4\n        while self.code[k] in \" \\t\\n'\":\n            k += 1\n\n        l = k\n        while self.code[l] not in \" \\t\\n\":\n            l += 1\n\n        get = collection.Get(statement, name=\"load\", cur=start, value=self.code[k:l])\n\n        name = str(self.code[k:l]).split(\".\")[0]\n        node = collection.Var(get, name)\n        node.create_declare()\n\n        while self.code[k] not in \";\\n\":\n            k += 1\n\n\n        return k\n\n    if self.code[k:k+4] == \"hold\":\n\n        statement = collection.Statement(node, cur=start,\n                                         code=self.code[start:newline])\n\n        l = k+4\n        while self.code[l] in \" \\t\":\n            l += 1\n\n        if self.code[l] == \"(\":\n            return expression.create(self, statement, k)\n\n        k += 4\n        while self.code[k] in \" \\t\":\n            k += 1\n\n        get = collection.Get(statement, name=\"hold\", cur=start)\n\n        if self.code[k:k+2] == \"on\"  and (self.code[k+2] in c.k_end):\n            collection.String(get, \"on\")\n            return k+2\n\n        if self.code[k:k+3] == \"off\"  and (self.code[k+3] in c.k_end):\n            collection.String(get, \"off\")\n            return k+3\n\n        if self.code[k:k+3] == \"all\"  and (self.code[k+3] in c.k_end):\n            collection.String(get, \"all\")\n            return k+3\n\n        while self.code[k] not in \";\\n\":\n            k += 1\n\n        return k\n\n    if self.code[k:k+4] == \"grid\":\n\n        statement = collection.Statement(node, cur=start,\n                                         code=self.code[k:newline])\n\n        l = k+4\n        while self.code[l] in \" \\t\":\n            l += 1\n\n        if self.code[l] == \"(\":\n            return expression.create(self, statement, k)\n\n        k += 4\n        while self.code[k] in \" \\t\":\n            k += 1\n\n        get = collection.Get(statement, name=\"grid\", cur=start)\n\n        if self.code[k:k+2] == \"on\"  and (self.code[k+2] in c.k_end):\n            collection.String(get, \"on\", cur=k)\n            return k+2\n\n        if self.code[k:k+3] == \"off\"  and (self.code[k+3] in c.k_end):\n            collection.String(get, \"off\", cur=k)\n            return k+3\n\n        if self.code[k:k+5] == \"minor\"  and (self.code[k+5] in c.k_end):\n            collection.String(get, \"minor\", cur=k)\n            return k+5\n\n        while self.code[k] not in \";\\n\":\n            k += 1\n\n        return k\n\n    if self.code[k:k+5] == \"clear\":\n        pass\n"
  },
  {
    "path": "src/matlab2cpp/tree/suppliment.py",
    "content": "\nclass Fbuilder(object):\n    \"Same as Ftypes, but placed in builder\"\n    def __get__(self, instance, owner):\n        out = {}\n        for program in instance:\n            out.update(program.ftypes)\n        return out\n    def __set__(self, instance, value):\n        for program in instance:\n            program.ftypes = value\n\n\nclass Ibuilder(object):\n    \"Same as Itypes, but placed in builder\"\n    def __get__(self, instance, owner):\n        out = set()\n        for program in instance:\n            out = out.union(program.itypes)\n        return out\n    def __set__(self, instance, value):\n        for program in instance:\n            program.itypes = value\n\n\nclass Sbuilder(object):\n    \"Same as Stypes, but placed in builder\"\n    def __get__(self, instance, owner):\n        out = {}\n        for program in instance:\n            out.update(program.stypes)\n        return out\n    def __set__(self, instance, value):\n        for program in instance:\n            program.stypes = value\n\n\nclass Vbuilder(object):\n    \"Same as Vtypes, but placed in builder\"\n    def __get__(self, instance, owner):\n        out = {}\n        for program in instance:\n            out.update(program.vtypes)\n        return out\n    def __set__(self, instance, value):\n        for program in instance:\n            program.vtypes = value\n\n\n\n\n"
  },
  {
    "path": "src/matlab2cpp/tree/variables.py",
    "content": "\"\"\"\nVariable interpretor\n\"\"\"\nfrom __future__ import print_function\nfrom . import constants, findend\nfrom .. import collection\n\n\ndef assign(self, parent, cur, end=None):\n    \"\"\"\nVariable left side of an assignment\n\nArgs:\n    self (Builder): Code constructor\n    parent (Node): Parent node\n    cur (int): Current position in code\n\nKwargs:\n    end (int, optional): End of variable\n\nReturns:\n\tint : End of variable\n\nExample:\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder(True)\n    >>> builder.load(\"unnamed\", \"a = 4\") # doctest: +NORMALIZE_WHITESPACE\n    loading unnamed\n         Program    functions.program\n       0 Main       functions.main\n       0 Codeblock  codeblock.codeblock\n       0   Assign     assign.single       'a = 4'\n       0     Var        variables.assign    'a'\n       4     Expression expression.create   '4'\n       4     Int        misc.number         '4'\n    >>> builder.configure(suggest=False)\n    >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n    1 1Block      code_block   TYPE\n    1 1| Assign     int          int \n    1 1| | Var        unknown      (int)   a\n    1 5| | Int        int          int\n    \"\"\"\n\n    if  self.code[cur] not in constants.letters + '~':\n        self.syntaxerror(cur, \"assign variable name\")\n\n\n    k = cur+1\n    while self.code[k] in constants.letters+constants.digits+\"_\":\n        k += 1\n\n    name = self.code[cur:k]\n    last = k\n\n    while self.code[k] in \" \\t\":\n        k += 1\n\n    # Get value of cell\n    if self.code[k] == \"{\":\n\n        end = findend.cell(self, k)\n        end = end+1\n        while self.code[end] in \" \\t\":\n            end += 1\n\n        if self.code[end] == \"(\":\n\n            end = findend.paren(self, end)\n            node = collection.Cset(parent, name, cur=cur,\n                    code=self.code[cur:end+1])\n\n            if self.disp:\n                print(\"%4d     Cset       \" % cur, end=\"\")\n                print(\"%-20s\" % \"variables.assign\", end=\"\")\n                print(repr(self.code[cur:end+1]))\n\n            n_fields = 0\n            while self.code[k] == \"{\":\n\n                #cur = self.iterate_cell(node, k)\n                cur = findend.cell(self, k)\n                #cur = iterate.comma_list(node, k)\n\n                k = cur+1\n                while self.code[k] in \" \\t\":\n                    k += 1\n                n_fields += 1\n\n            while self.code[k] in \" \\t\":\n                k += 1\n\n            if  self.code[k] != \"(\":\n                self.syntaxerror(k, \"parenthesis start\")\n\n            cur = self.create_list(node, k)\n\n            node[\"n_fields\"] = n_fields\n            node[\"n_args\"] = len(node) - n_fields\n\n        else:\n            end = findend.cell(self, k)\n            node = collection.Cvar(parent, name, cur=cur,\n                    code=self.code[cur:end+1])\n\n            if self.disp:\n                print(\"%4d     Cvar       \" % cur, end=\"\")\n                print(\"%-20s\" % \"variables.assign\", end=\"\")\n                print(repr(self.code[cur:end+1]))\n\n            num = 0\n            while self.code[k] == \"{\":\n\n                cur = findend.cell(self, k)\n                #cur = self.iterate_cell(node, k)\n\n                #print(node.code)\n                #print(k)\n                #print(\"\\n\\n\")\n\n                #l = 0\n                #while node.code[l] in constants.letters+constants.digits+\"_\":\n                #    l += 1\n\n                #list = iterate.comma_list(node, l)\n                #for tup in list:\n                #    collection.Var(node, node.code[tup[0]:tup[1]+1])\n\n                #print(list)\n                #print(\"LISTAT\\n\\n\")\n\n                k = cur+1\n                while self.code[k] in \" \\t\":\n                    k += 1\n                num += 1\n\n\n    # Set value of array\n    elif self.code[k] == \"(\":\n\n        end = findend.paren(self, k)\n        if self.code[end+1] == \".\" and self.code[end+2] in constants.letters:\n\n            start = end+2\n            end += 2\n            while self.code[end] in constants.letters+constants.digits+\"_\":\n                end += 1\n            value = self.code[start:end]\n\n            if self.disp:\n                print(\"%4d     Sset        \" % cur)\n                print(\"%-20s\" % \"variables.assign\", end=\"\")\n                print(repr(self.code[cur:end]))\n\n            node = collection.Sset(parent, name, value, cur=cur,\n                    code=self.code[cur:end], pointer=1)\n\n            last = self.create_list(node, k)\n            cur = end-1\n\n        else:\n\n            if self.disp:\n                print(\"%4d     Set        \" % cur)\n                print(\"%-20s\" % \"variables.assign\", end=\"\")\n                print(repr(self.code[cur:end+1]))\n\n            node = collection.Set(parent, name, cur=cur,\n                    code=self.code[cur:end+1])\n\n            last = self.create_list(node, k)\n            cur = last\n\n    elif self.code[k] == \".\":\n\n        k += 1\n\n        # Fieldname of type \"a.() = ...\"\n        if self.code[k] == \"(\":\n\n            end = findend.paren(self, k)\n\n            k += 1\n\n            while self.code[k] in \" \\t\":\n                k += 1\n\n            if self.disp:\n                print(\"%4d     Nset       \" % cur, end=\"\")\n                print(\"%-20s\" % \"variables.assign\", end=\"\")\n                print(repr(self.code[cur:end+1]))\n\n\n            node = collection.Nset(parent, name)\n            node.cur = cur\n            node.code = self.code[cur:end+1]\n\n            cur = self.create_expression(node, cur)\n\n\n        elif self.code[k] in constants.letters:\n\n            j = k+1\n            while self.code[j] in constants.letters+constants.digits+\"_.\":\n                j += 1\n\n            value = self.code[k:j]\n            last = j-1\n\n            while self.code[j] in \" \\t\":\n                j += 1\n\n            # Fieldname of type \"a.b(...) = ...\"\n            if self.code[j] == \"(\":\n\n                end = findend.paren(self, j)\n                if self.disp:\n                    print(\"%4d     Fset       \" % cur, end=\"\")\n                    print(\"%-20s\" % \"variables.assign\", end=\"\")\n                    print(repr(self.code[cur:end+1]))\n\n                node = collection.Fset(parent, name, value=value, cur=cur,\n                        code=self.code[cur:end+1])\n\n                cur = self.create_list(node, j)\n\n            # Fieldname of type \"a.b = ...\"\n            else:\n\n                if self.disp:\n                    print(\"%4d     Fvar       \" % cur, end=\"\")\n                    print(\"%-20s\" % \"variables.assign\", end=\"\")\n                    print(repr(self.code[cur:last+1]))\n\n                node = collection.Fvar(parent, name, value=value, cur=cur,\n                        code=self.code[cur:last+1])\n\n                cur = last\n\n    # Simple variable assignment\n    else:\n        if self.disp:\n            print(\"%4d     Var        \" % cur, end=\"\")\n            print(\"%-20s\" % \"variables.assign\", end=\"\")\n            print(repr(self.code[cur:last]))\n\n\n        node = collection.Var(parent, name, cur=cur,\n                code=self.code[cur:last])\n\n        cur = last-1\n\n    if name != '~':\n        node.create_declare()\n\n    return cur\n\n\ndef variable(self, parent, cur):\n    \"\"\"\nVariable not on the left side of an assignment\n\nArgs:\n    self (Builder): Code constructor\n    node (Node): Parent node\n    cur (int): Current position in code\n\nKwargs:\n    end (int, optional): End of variable\n\nReturns:\n\tint : End of variable\n\nExample:\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder(True)\n    >>> builder.load(\"unnamed\", \"a\") # doctest: +NORMALIZE_WHITESPACE\n    loading unnamed\n         Program    functions.program\n       0 Main       functions.main\n       0 Codeblock  codeblock.codeblock\n       0   Statement    codeblock.codeblock 'a'\n       0     Expression expression.create   'a'\n       0     Var        variables.variable  'a'\n    >>> builder.configure()\n    >>> print(matlab2cpp.qtree(builder, core=True)) #doctest: +NORMALIZE_WHITESPACE\n    1 1Block      code_block   TYPE\n    1 1| Statement  code_block   TYPE\n    1 1| | Var        unknown      TYPE    a\n    \"\"\"\n\n    k = cur\n    if self.code[k] == \"@\":\n        k += 1\n\n    if  self.code[k] not in constants.letters:\n        self.syntaxerror(k, \"variable name\")\n\n    k += 1\n    while self.code[k] in constants.letters+constants.digits+\"_\":\n        k += 1\n\n    name = self.code[cur:k]\n    last = k\n\n    while self.code[k] in \" \\t\":\n        k += 1\n\n    # Get value of cell\n    if self.code[k] == \"{\":\n\n        end = findend.cell(self, k)\n        end = end+1\n        while self.code[end] in \" \\t\":\n            end += 1\n\n        if self.code[end] == \"(\":\n\n            end = findend.paren(self, end)\n            node = collection.Cget(parent, name, cur=cur,\n                    code=self.code[cur:end+1])\n\n            if self.disp:\n                print(\"%4d     Cget       \" % cur, end=\"\")\n                print(\"%-20s\" % \"variables.variable\", end=\"\")\n                print(repr(self.code[cur:end+1]))\n\n            n_fields = 0\n            while self.code[k] == \"{\":\n\n                cur = findend.cell(self, k)\n                #cur = self.iterate_cell(node, k)\n                #cur = iterate.comma_list(node, k)\n\n                k = cur+1\n                while self.code[k] in \" \\t\":\n                    k += 1\n                n_fields += 1\n\n            while self.code[k] in \" \\t\":\n                k += 1\n\n            if  self.code[k] != \"(\":\n                self.syntaxerror(k, \"argument parenthesis\")\n\n            cur = self.create_list(node, k)\n\n            node[\"n_fields\"] = n_fields\n            node[\"n_args\"] = len(node) - n_fields\n\n        else:\n            end = findend.cell(self, k)\n            node = collection.Cvar(parent, name, cur=cur,\n                    code=self.code[cur:end+1])\n\n            if self.disp:\n                print(\"%4d     Cvar       \" % cur, end=\"\")\n                print(\"%-20s\" % \"variables.variable\", end=\"\")\n                print(repr(self.code[cur:end+1]))\n\n            num = 0\n            while self.code[k] == \"{\":\n\n                cur = cell_arg(self, node, k)\n                k = cur+1\n                while self.code[k] in \" \\t\":\n                    k += 1\n                num += 1\n\n\n    # Get value of array\n    elif self.code[k] == \"(\":\n\n        end = findend.paren(self, k)\n        if self.code[end+1] == \".\" and self.code[end+2] in constants.letters:\n\n            start = end+2\n            end += 2\n            while self.code[end] in constants.letters+constants.digits+\"_\":\n                end += 1\n            value = self.code[start:end]\n\n            if self.disp:\n                print(\"%4d     Sget        \" % cur, end=\"\")\n                print(\"%-20s\" % \"variables.variable\", end=\"\")\n                print(repr(self.code[cur:end]))\n\n            node = collection.Sget(parent, name, value, cur=cur,\n                    code=self.code[cur:end], pointer=1)\n\n            last = self.create_list(node, k)\n            cur = end\n\n        else:\n\n            if self.disp:\n                print(\"%4d     Get        \" % cur, end=\"\")\n                print(\"%-20s\" % \"variables.variable\", end=\"\")\n                print(repr(self.code[cur:end+1]))\n\n            node = collection.Get(parent, name, cur=cur,\n                    code=self.code[cur:end+1])\n\n            last = self.create_list(node, k)\n            cur = last\n\n\n\n    elif self.code[k] == \".\" and self.code[k+1] not in \".*/\\\\^'\":\n\n        k += 1\n\n        # Fieldname of type \"a.(..)\"\n        if self.code[k] == \"(\":\n\n            end = findend.paren(self, k)\n\n            if self.disp:\n                print(\"%4d     Nget       \" % cur, end=\"\")\n                print(\"%-20s\" % \"variables.variable\", end=\"\")\n                print(repr(self.code[cur:end+1]))\n\n            k += 1\n\n            while self.code[k] in \" \\t\":\n                k += 1\n\n            node = collection.Nget(parent, name, cur=cur,\n                    code=self.code[cur:end+1])\n\n            cur = self.create_expression(node, k)\n\n\n        elif self.code[k] in constants.letters:\n\n            j = k+1\n            while self.code[j] in constants.letters+constants.digits+\"_\":\n                j += 1\n\n            value = self.code[k:j]\n            last = j\n\n            while self.code[j] in \" \\t\":\n                j += 1\n\n            # Fieldname of type \"a.b(...)\"\n            if self.code[j] == \"(\":\n\n                end = findend.paren(self, j)\n                if self.disp:\n                    print(\"%4d     Fget       \" % cur, end=\"\")\n                    print(\"%-20s\" % \"variables.variable\", end=\"\")\n                    print(repr(self.code[cur:end+1]))\n\n\n                node = collection.Fget(parent, name, cur=cur,\n                        value=value, code=self.code[cur:end+1])\n\n                j += 1\n                while self.code[j] in \" \\t\":\n                    j += 1\n\n                cur = self.create_expression(node, j)\n\n                node.create_declare()\n\n            # Fieldname of type \"a.b\"\n            else:\n\n                if self.disp:\n                    print(\"%4d     Fvar       \" % cur, end=\"\")\n                    print(\"%-20s\" % \"variables.variable\", end=\"\")\n                    print(repr(self.code[cur:last]))\n\n                node = collection.Fvar(parent, name, value=value,\n                        cur=cur, code=self.code[cur:last])\n\n                cur = last-1\n\n                node.create_declare()\n\n\n    # Simple variable\n    else:\n\n        if self.disp:\n            print(\"%4d     Var        \" % cur, end=\"\")\n            print(\"%-20s\" % \"variables.variable\", end=\"\")\n            print(repr(self.code[cur:last]))\n\n        node = collection.Var(parent, name, cur=cur,\n                code=self.code[cur:last])\n\n        cur = last-1\n\n    while self.code[cur] in \" \\t\":\n        cur += 1\n\n    return cur\n\n\ndef cell_arg(self, cset, cur):\n    \"\"\"\nArgument of a cell call. Support function to `assign` and `variable`.\n\nArgs:\n    self (Builder): Code constructor\n    cset (Node): Parent node\n    cur (int): Current position in code\n\nReturns:\n\tint : End of argument\n\nExample:\n    >>> from matlab2cpp.tree import Builder\n    >>> builder = Builder(True)\n    >>> builder.load(\"unnamed\", \"a{b}\") # doctest: +NORMALIZE_WHITESPACE\n    loading unnamed\n         Program    functions.program\n       0 Main       functions.main\n       0 Codeblock  codeblock.codeblock\n       0   Statement    codeblock.codeblock 'a{b}'\n       0     Expression expression.create   'a{b}'\n       0     Cvar       variables.variable  'a{b}'\n       2     Expression expression.create   'b'\n       2     Var        variables.variable  'b'\n    >>> builder.configure()\n    >>> print(matlab2cpp.qtree(builder, core=True)) # doctest: +NORMALIZE_WHITESPACE\n    1 1Block      code_block   TYPE\n    1 1| Statement  code_block   TYPE\n    1 1| | Cvar       cell         TYPE    a\n    1 3| | | Var        unknown      TYPE    b\n    \"\"\"\n\n    if self.code[cur] != \"{\":\n        self.syntaxerror(cur, \"Curly start\")\n\n    cur = cur+1\n\n    while True:\n\n        if self.code[cur] == \"}\":\n            return cur\n\n        elif self.code[cur] in constants.e_start:\n\n            cur = self.create_expression(cset, cur)\n\n            cur += 1\n            while self.code[cur] in \" \\t\":\n                cur += 1\n\n            return cur\n\n        elif self.code[cur] == \" \":\n            pass\n\n        cur += 1\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "test/data/function_reference.hpp",
    "content": "#ifndef F_M_HPP\n#define F_M_HPP\n\n#include <armadillo>\nusing namespace arma ;\n\nirowvec f(irowvec x) ;\nvoid g() ;\n\nirowvec f(irowvec x)\n{\n  irowvec y ;\n  y = x+2 ;\n  return y ;\n}\n\nvoid g()\n{\n  irowvec x, y ;\n  sword _x [] = {1, 2, 3} ;\n  x = irowvec(_x, 3, false) ;\n  y = f(x) ;\n}\n#endif\n"
  },
  {
    "path": "test/data/function_reference.m",
    "content": "function y=f(x)\n    y = x+2\nend\nfunction g()\n    x = [1,2,3]\n    y = f(x)\nend\n"
  },
  {
    "path": "test/data/function_reference_2.hpp",
    "content": "#ifndef F_M_HPP\n#define F_M_HPP\n\n#include <armadillo>\nusing namespace arma ;\n\nvoid f(irowvec a, ivec b, irowvec& y, ivec& z) ;\nvoid g() ;\n\nvoid f(irowvec a, ivec b, irowvec& y, ivec& z)\n{\n  y = a+2 ;\n  z = b-3 ;\n}\n\nvoid g()\n{\n  irowvec a, y ;\n  ivec b, z ;\n  sword _a [] = {1, 2, 3} ;\n  a = irowvec(_a, 3, false) ;\n  sword _b [] = {4, 5, 6} ;\n  b = ivec(_b, 3, false) ;\n  f(a, b, y, z) ;\n}\n#endif\n"
  },
  {
    "path": "test/data/function_reference_2.m",
    "content": "function [y,z]=f(a,b)\n    y = a+2\n    z = b-3\nend\nfunction g()\n    a = [1,2,3]\n    b = [4;5;6]\n    [y,z] = f(a,b)\nend\n"
  },
  {
    "path": "test/data/fx_decon.cpp",
    "content": "#ifndef FX_DECON_M_HPP\n#define FX_DECON_M_HPP\n\n#include <armadillo>\n#include \"mconvert.h\"\n#include <cmath>\nusing namespace arma ;\n\nmat fx_decon(mat DATA, double dt, int lf, double mu, double flow, int fhigh) ;\nvoid ar_modeling(cx_vec x, int lf, double mu, cx_vec& yf, cx_vec& yb) ;\n\nmat fx_decon(mat DATA, double dt, int lf, double mu, double flow, int fhigh)\n{\n  cx_mat DATA_FX, DATA_FX_b, DATA_FX_f ;\n  cx_vec aux_in, aux_out_b, aux_out_f ;\n  int ihigh, ilow, k, nf, nt, ntraces ;\n  mat DATA_b, DATA_f ;\n  nt = DATA.n_rows;\n  ntraces = DATA.n_cols;\n  \n  nf = pow(2, m2cpp::nextpow2(nt)) ;\n  DATA_FX_f = arma::zeros<cx_mat>(nf, ntraces) ;\n  DATA_FX_b = arma::zeros<cx_mat>(nf, ntraces) ;\n  ilow = std::floor(flow*dt*nf)+1 ;\n  if (ilow<1)\n  {\n    ilow = 1 ;\n  }\n  ihigh = std::floor(fhigh*dt*nf)+1 ;\n  if (ihigh>std::floor(nf/2.0)+1)\n  {\n    ihigh = std::floor(nf/2.0)+1 ;\n  }\n  DATA_FX = m2cpp::fft<mat>(DATA, nf, 1) ;\n  for (k=ilow; k<=ihigh; k++)\n  {\n    aux_in = arma::trans(DATA_FX.row(k-1)) ;\n    ar_modeling(aux_in, lf, mu, aux_out_f, aux_out_b) ;\n    DATA_FX_f.row(k-1) = arma::trans(aux_out_f) ;\n    DATA_FX_b.row(k-1) = arma::trans(aux_out_b) ;\n  }\n  for (k=nf/2.0+2; k<=nf; k++)\n  {\n    DATA_FX_f.row(k-1) = arma::conj(DATA_FX_f.row(nf-k+1)) ;\n    DATA_FX_b.row(k-1) = arma::conj(DATA_FX_b.row(nf-k+1)) ;\n  }\n  DATA_f = arma::real(m2cpp::ifft<cx_mat>(DATA_FX_f, 1)) ;\n  DATA_f = DATA_f.rows(arma::span(0, nt-1)) ;\n  DATA_b = arma::real(m2cpp::ifft<cx_mat>(DATA_FX_b, 1)) ;\n  DATA_b = DATA_b.rows(arma::span(0, nt-1)) ;\n  DATA_f = (DATA_f+DATA_b) ;\n  DATA_f.cols(arma::span(lf, ntraces-lf-1)) = DATA_f.cols(arma::span(lf, ntraces-lf-1))/2.0 ;\n  return DATA_f ;\n}\n\nvoid ar_modeling(cx_vec x, int lf, double mu, cx_vec& yf, cx_vec& yb)\n{\n  cx_double beta ;\n  cx_mat B, M, temp ;\n  cx_vec C, R, ab, af, y ;\n  uword nx ;\n  nx = m2cpp::length(x) ;\n  y = x(arma::span(0, nx-lf-1)) ;\n  C = x(arma::span(1, nx-lf)) ;\n  R = x(arma::span(nx-lf, nx-1)) ;\n  M = m2cpp::hankel(C, R) ;\n  B = arma::trans(M)*M ;\n  beta = B(0, 0)*(cx_double) mu/100.0 ;\n  ab = arma::solve((B+beta*arma::eye<cx_mat>(lf, lf)), arma::trans(M), solve_opts::fast)*y ;\n  temp = M*ab ;\n  temp = arma::join_cols(temp, arma::zeros<cx_mat>(lf, 1)) ;\n  yb = temp ;\n  y = x(arma::span(lf, nx-1)) ;\n  C = x(arma::span(lf-1, nx-2)) ;\n  R = arma::flipud(x(arma::span(0, lf-1))) ;\n  M = toeplitz(C, R) ;\n  B = arma::trans(M)*M ;\n  beta = B(0, 0)*(cx_double) mu/100.0 ;\n  af = arma::solve((B+beta*arma::eye<cx_mat>(lf, lf)), arma::trans(M), solve_opts::fast)*y ;\n  temp = M*af ;\n  temp = arma::join_cols(arma::zeros<cx_mat>(lf, 1), temp) ;\n  yf = temp ;\n  return ;\n}\n#endif\n"
  },
  {
    "path": "test/data/fx_decon.m",
    "content": "function [DATA_f] = fx_decon(DATA,dt,lf,mu,flow,fhigh);\n [nt,ntraces] = size(DATA);\n nf = 2^nextpow2(nt);\n DATA_FX_f = zeros(nf,ntraces);\n DATA_FX_b = zeros(nf,ntraces);\n ilow  = floor(flow*dt*nf)+1; \n  if ilow<1; \n   ilow=1; \n  end;\n ihigh = floor(fhigh*dt*nf)+1;\n  if ihigh > floor(nf/2)+1; \n   ihigh=floor(nf/2)+1; \n  end\n DATA_FX = fft(DATA,nf,1);\n for k = ilow:ihigh;\n  aux_in  = DATA_FX(k,:)';\n  [aux_out_f,aux_out_b] = ar_modeling(aux_in,lf,mu);\n  DATA_FX_f(k,:) = aux_out_f';\n  DATA_FX_b(k,:) = aux_out_b';\n end;\n for k=nf/2+2:nf\n  DATA_FX_f(k,:) = conj(DATA_FX_f(nf-k+2,:));\n  DATA_FX_b(k,:) = conj(DATA_FX_b(nf-k+2,:));\n end\n DATA_f = real(ifft(DATA_FX_f,[],1));\n DATA_f = DATA_f(1:nt,:);\n DATA_b = real(ifft(DATA_FX_b,[],1));\n DATA_b = DATA_b(1:nt,:);\n DATA_f = (DATA_f + DATA_b);\n DATA_f(:,lf+1:ntraces-lf)= DATA_f(:,lf+1:ntraces-lf)/2;\nreturn\nfunction [yf,yb] = ar_modeling(x,lf,mu);\n   nx = length(x);\n   y  = x(1:nx-lf,1);\n   C  = x(2:nx-lf+1,1);\n   R  = x(nx-lf+1:nx,1);\n   M = hankel(C,R);\n   B = M'*M;  beta = B(1,1)*mu/100;\n   ab = (B + beta*eye(lf))\\M'*y;\n   temp = M*ab;\n   temp = [temp;zeros(lf,1)];\n   yb = temp;\n   y  = x(lf+1:nx,1);\n   C  = x(lf:nx-1,1);\n   R = flipud(x(1:lf,1));\n   M = toeplitz(C,R);\n   B = M'*M;  beta = B(1,1)*mu/100;\n   af = (B + beta*eye(lf))\\M'*y;\n   temp = M*af;\n   temp = [zeros(lf,1);temp];\n   yf = temp;\nreturn\n"
  },
  {
    "path": "test/data/fx_decon.m.py",
    "content": "functions = {\n  \"ar_modeling\" : {\n       \"B\" : \"cx_mat\",\n       \"C\" : \"cx_vec\",\n       \"M\" : \"cx_mat\",\n       \"R\" : \"cx_vec\",\n      \"ab\" : \"cx_vec\",\n      \"af\" : \"cx_vec\",\n    \"beta\" : \"cx_double\",\n      \"lf\" : \"int\",\n      \"mu\" : \"double\",\n      \"nx\" : \"uword\",\n    \"temp\" : \"cx_mat\",\n       \"x\" : \"cx_vec\",\n       \"y\" : \"cx_vec\",\n      \"yb\" : \"cx_vec\",\n      \"yf\" : \"cx_vec\",\n  },\n  \"fx_decon\" : {\n         \"DATA\" : \"mat\",\n      \"DATA_FX\" : \"cx_mat\",\n    \"DATA_FX_b\" : \"cx_mat\",\n    \"DATA_FX_f\" : \"cx_mat\",\n       \"DATA_b\" : \"mat\",\n       \"DATA_f\" : \"mat\",\n       \"aux_in\" : \"cx_vec\",\n    \"aux_out_b\" : \"cx_vec\",\n    \"aux_out_f\" : \"cx_vec\",\n           \"dt\" : \"double\",\n        \"fhigh\" : \"int\",\n         \"flow\" : \"double\",\n        \"ihigh\" : \"int\",\n         \"ilow\" : \"int\",\n            \"k\" : \"int\",\n           \"lf\" : \"int\",\n           \"mu\" : \"double\",\n           \"nf\" : \"int\",\n           \"nt\" : \"int\",\n      \"ntraces\" : \"int\",\n  },\n}\nincludes = [\n  '#include <armadillo>',\n  'using namespace arma ;',\n]\n"
  },
  {
    "path": "test/data/simple_assignment.cpp",
    "content": "#include <armadillo>\nusing namespace arma ;\n\nint main(int argc, char** argv)\n{\n  double b ;\n  int a ;\n  irowvec d ;\n  ivec e ;\n  std::string c ;\n  a = 1 ;\n  b = 2. ;\n  c = \"3\" ;\n  sword _d [] = {4, 5} ;\n  d = irowvec(_d, 2, false) ;\n  sword _e [] = {6, 7} ;\n  e = ivec(_e, 2, false) ;\n  return 0 ;\n}\n\n"
  },
  {
    "path": "test/data/simple_assignment.m",
    "content": "a = 1\nb = 2.\nc = '3'\nd = [4, 5]\ne = [6; 7]\n"
  },
  {
    "path": "test/test_conversion.py",
    "content": "\"\"\"Test fx_decon script.\"\"\"\nimport os\n\n\ndef test_fx_decon():\n    \"\"\"Test fx_decon script.\"\"\"\n    os.system(\"m2cpp fx_decon.m -s > /dev/null\")\n    with open(\"fx_decon.cpp\", \"r\") as src:\n        reference_code = src.read().strip()\n    with open(\"fx_decon.m.hpp\", \"r\") as src:\n        converted_code = \"\\n\".join(src.read().split(\"\\n\")[2:]).strip()\n    assert converted_code == reference_code\n"
  },
  {
    "path": "test/test_simple_assignment.py",
    "content": "\"\"\"Test simple assignment.\"\"\"\nimport pytest\n\nfrom matlab2cpp import qcpp, qhpp\n\n\n@pytest.fixture(params=[\n    \"simple_assignment\",\n])\ndef cpp_filename(request):\n    return request.param\n\n\ndef test_cpp_executables(cpp_filename):\n    \"\"\"Test basic variable types.\"\"\"\n\n    with open(\"%s.m\" % cpp_filename) as src:\n        source_code = src.read().strip()\n    translation = qcpp(source_code, suggest=True)\n\n    with open(\"%s.cpp\" % cpp_filename) as src:\n        cpp_reference = src.read().strip()\n\n    assert translation == cpp_reference\n\n\n@pytest.fixture(params=[\n    \"function_reference\",\n    \"function_reference_2\",\n])\ndef hpp_filename(request):\n    return request.param\n\n\ndef test_hpp_executables(hpp_filename):\n    \"\"\"Test basic variable types.\"\"\"\n\n    with open(\"%s.m\" % hpp_filename) as src:\n        source_code = src.read().strip()\n    translation = qhpp(source_code, suggest=True)\n\n    with open(\"%s.hpp\" % hpp_filename) as src:\n        hpp_reference = src.read().strip()\n\n    assert translation == hpp_reference\n"
  }
]