Hong Minhee avatar Hong Minhee committed c06249d

Initial commit.

Comments (0)

Files changed (11)

+syntax:glob
+docs/_build
+*.pyc
+*.egg-info
+.*.swp
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Kong.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Kong.qhc"
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/Kong"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Kong"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	make -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
+# -*- coding: utf-8 -*-
+#
+# Kong documentation build configuration file, created by
+# sphinx-quickstart on Tue Jul  5 02:34:36 2011.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+sys.path.insert(0, os.path.abspath('..'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Kong'
+copyright = u'2011, Hong Minhee'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.1'
+# The full version, including alpha/beta/rc tags.
+release = '0.1'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Kongdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'Kong.tex', u'Kong Documentation',
+   u'Hong Minhee', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'kong', u'Kong Documentation',
+     [u'Hong Minhee'], 1)
+]
+
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {'http://docs.python.org/': None}
+
+
+autodoc_member_order = 'bysource'
+.. Kong documentation master file, created by
+   sphinx-quickstart on Tue Jul  5 02:34:36 2011.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to Kong's documentation!
+================================
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   kong
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
+
+.. automodule:: kong
+   :members:
+
+   .. toctree::
+      :maxdepth: 2
+
+      kong/ast
+

docs/kong/ast.rst

+
+.. automodule:: kong.ast
+   :members:
+   :show-inheritance:
+
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+	:help
+	echo.Please use `make ^<target^>` where ^<target^> is one of
+	echo.  html       to make standalone HTML files
+	echo.  dirhtml    to make HTML files named index.html in directories
+	echo.  singlehtml to make a single large HTML file
+	echo.  pickle     to make pickle files
+	echo.  json       to make JSON files
+	echo.  htmlhelp   to make HTML files and a HTML help project
+	echo.  qthelp     to make HTML files and a qthelp project
+	echo.  devhelp    to make HTML files and a Devhelp project
+	echo.  epub       to make an epub
+	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  text       to make text files
+	echo.  man        to make manual pages
+	echo.  changes    to make an overview over all changed/added/deprecated items
+	echo.  linkcheck  to check all external links for integrity
+	echo.  doctest    to run all doctests embedded in the documentation if enabled
+	goto end
+)
+
+if "%1" == "clean" (
+	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+	del /q /s %BUILDDIR%\*
+	goto end
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+	goto end
+)
+
+if "%1" == "singlehtml" (
+	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Kong.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Kong.ghc
+	goto end
+)
+
+if "%1" == "devhelp" (
+	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished.
+	goto end
+)
+
+if "%1" == "epub" (
+	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The epub file is in %BUILDDIR%/epub.
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "text" (
+	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The text files are in %BUILDDIR%/text.
+	goto end
+)
+
+if "%1" == "man" (
+	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The manual pages are in %BUILDDIR%/man.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.The overview file is in %BUILDDIR%/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+	goto end
+)
+
+:end
+""":mod:`kong`
+~~~~~~~~~~~~~~
+
+"""
+""":mod:`kong.ast` --- Abstract Syntax Tree
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+"""
+import numbers
+import collections
+import itertools
+
+
+class Node(object):
+    """An abstract base class for syntax tree."""
+
+
+class ExpressionList(tuple):
+    """An abstract base class for :class:`Expression` list."""
+
+    def __new__(cls, expressions):
+        def arg():
+            for expr in expressions:
+                if isinstance(expr, Expression):
+                    yield expr
+                else:
+                    args = cls.__module__, cls.__name__, expr
+                    raise TypeError('{0}.{1} accepts only '
+                                    'kong.ast.Expression objects as elements, '
+                                    'not {2!r}'.format(*args))
+        return tuple.__new__(cls, arg())
+
+    def __repr__(self):
+        r = tuple.__repr__(self)[1:-1]
+        if r.endswith(','):
+            r = r[:-1]
+        cls = type(self)
+        return '{0}.{1}([{2}])'.format(cls.__module__, cls.__name__, r)
+
+
+class Program(Node, ExpressionList):
+    r"""A program node.
+
+    .. productionlist::
+       program: (`expr` `terminate`)* [`expr`]
+       terminate: (";" | `newline`)+
+       newline: ["\r"] "\n"
+
+    .. sourcecode:: pycon
+
+       >>> Program([Identifier(u'abc')])
+       kong.ast.Program([kong.ast.Identifier(u'abc')])
+       >>> print unicode(_)
+       abc
+
+    :param expressions: :class:`Expression` list
+    :type expressions: :class:`collections.Iterable`
+
+    """
+
+    def __unicode__(self):
+        return u'\n'.join(itertools.imap(unicode, self))
+
+
+class Expression(Node):
+    """An expression node. It is an abstract class.
+
+    .. productionlist::
+       expr: "(" `expr` ")" | `literal` | `id` | `attr` |
+             `apply` | `operator` | `define`
+
+    """
+
+
+class Identifier(Expression, unicode):
+    """An identifier node.
+
+    .. productionlist::
+       id: /[^[:digit:][:space:]][^[:space:]]*/ except "<-"
+
+    :param identifier: an identifier string
+
+    """
+
+    __slots__ = ()
+
+    def __repr__(self):
+        cls = type(self)
+        repr = unicode.__repr__(self)
+        return '{0}.{1}({2})'.format(cls.__module__, cls.__name__, repr)
+
+
+class Application(Expression):
+    """An application (call) node.
+
+    .. productionlist::
+       apply: `expr` "(" `args` ")" | `expr` `args`
+       args: (`expr` ",")* [`expr`]
+
+    .. sourcecode:: pycon
+
+       >>> app = Application(Identifier('func'),
+       ...                   [Identifier('a'), Identifier('b')])
+       >>> app  # doctest: +NORMALIZE_WHITESPACE
+       kong.ast.Application(kong.ast.Identifier(u'func'),
+                            [kong.ast.Identifier(u'a'),
+                             kong.ast.Identifier(u'b')])
+       >>> print unicode(app)
+       func(a, b)
+
+    :param function: a function to apply
+    :type function: :class:`Expression`
+    :param arguments: a :class:`Expresion` list
+    :type arguments: :class:`collections.Iterable`
+
+    """
+
+    __slots__ = 'function', 'arguments'
+
+    def __init__(self, function, arguments):
+        if not isinstance(function, Expression):
+            raise TypeError('function must be a kong.ast.Expression object, '
+                            'not ' + repr(function))
+        elif not isinstance(arguments, collections.Iterable):
+            raise TypeError('arguments must be iterable')
+        def args():
+            for arg in arguments:
+                if isinstance(arg, Expression):
+                    yield arg
+                else:
+                    raise TypeError('arguments must consist of only kong.'
+                                    'ast.Expression, not ' + repr(arg))
+        self.function = function
+        self.arguments = tuple(args())
+
+    def __unicode__(self):
+        args = u', '.join(itertools.imap(unicode, self.arguments))
+        return u'{0}({1})'.format(unicode(self.function), args)
+
+    def __repr__(self):
+        cls = type(self)
+        args = repr(self.arguments)[1:-1]
+        if args.endswith(','):
+            args = args[:-1]
+        vals = cls.__module__, cls.__name__, self.function, args
+        return '{0}.{1}({2!r}, [{3}])'.format(*vals)
+
+
+class Attribute(Application):
+    """A pseudo-attribute node.
+
+    .. productionlist::
+       attr: `expr` "." (`id` | `number`)
+
+    .. sourcecode:: pycon
+
+       >>> attr = Attribute(Identifier('obj'), attribute=Identifier('attr'))
+       >>> attr  # doctest: +NORMALIZE_WHITESPACE
+       kong.ast.Attribute(kong.ast.Identifier(u'obj'),
+                          attribute=kong.ast.Identifier(u'attr'))
+       >>> print unicode(attr)
+       obj.attr
+
+    :param function: a function to apply
+    :type function: :class:`Expression`
+    :param arguments: a :class:`Expresion` list
+    :type arguments: :class:`collections.Iterable`
+    :param attribute: an attribute name
+    :type attribute: :class:`Identifier`, :class:`numbers.Integral`
+
+    Arguments ``attribute`` and ``arguments`` are exclusive but one of them
+    is required.
+
+    """
+
+    def __init__(self, function, arguments=None, attribute=None):
+        if arguments is None and attribute is None:
+            raise TypeError('one of arguments or attribute must be passed')
+        elif arguments is not None and attribute is not None:
+            raise TypeError('only one of arguments or attribute are accepted')
+        elif isinstance(attribute, (numbers.Integral, Identifier)):
+            arguments = StringLiteral(attribute),
+        elif attribute is not None:
+            raise TypeError('attribute must be an integer or kong.ast.'
+                            'Identifier, not ' + repr(attribute))
+        else:
+            try:
+                arguments = tuple(arguments)
+            except TypeError:
+                raise TypeError('arguments must be iterable')
+        if len(arguments) != 1:
+            raise TypeError('attribute takes only one string argument')
+        elif not isinstance(arguments[0], StringLiteral):
+            raise TypeError('argument must be a kong.ast.StringLiteral, not ' +
+                            repr(arguments[0]))
+        Application.__init__(self, function, arguments)
+
+    @property
+    def attribute(self):
+        """(:class:`Identifier`, :class:`numbers.Integral`) Attribute name.
+
+        .. sourcecode:: pycon
+
+           >>> attr = Attribute(Identifier('a'), [StringLiteral(12)])
+           >>> attr.attribute
+           12
+           >>> attr2 = Attribute(Identifier('a'), [StringLiteral(u'b')])
+           >>> attr2.attribute
+           kong.ast.Identifier(u'b')
+
+        """
+        s = self.arguments[0].string
+        return int(s) if s.isdigit() else Identifier(s)
+
+    def __unicode__(self):
+        return u'{0}.{1}'.format(self.function, self.arguments[0].string)
+
+    def __repr__(self):
+        cls = type(self)
+        attr = Identifier(self.arguments[0].string)
+        f = u'{0}.{1}({2!r}, attribute={3!r})'
+        return f.format(cls.__module__, cls.__name__, self.function, attr)
+
+
+class Operator(Application):
+    """A pseudo-operator node.
+
+    .. productionlist::
+       operator: `expr` `id` `expr`
+
+    .. sourcecode:: pycon
+
+       >>> op = Operator(operator=Identifier('+'),
+       ...               operands=[StringLiteral(1), StringLiteral(2)])
+       >>> op.function  # doctest: +NORMALIZE_WHITESPACE
+       kong.ast.Attribute(kong.ast.StringLiteral(1),
+                          attribute=kong.ast.Identifier(u'+'))
+       >>> op.arguments
+       (kong.ast.StringLiteral(2),)
+       >>> print unicode(op)
+       1 + 2
+
+    There are two signatures. One is the same to :class:`Application`'s:
+
+    :param function: a function to apply
+    :type function: :class:`Expression`
+    :param arguments: a :class:`Expresion` list
+    :type arguments: :class:`collections.Iterable`
+
+    Other one takes ``operator`` and ``operands`` (by keywords only):
+
+    :param operator: an operator name
+    :type operator: :class:`Identifier`
+    :param operands: pair of :class:`Expression`
+    :type operands: :class:`collections.Iterable`
+
+    """
+
+    def __init__(self, function=None, arguments=None,
+                 operator=None, operands=None):
+        if not (function is not None and arguments is not None or
+                operator is not None and operands is not None):
+            raise TypeError('it takes function and arguments both or '
+                            'operator and operands both')
+        if (function is not None or arguments is not None) and \
+           (operator is not None or operands is not None):
+            raise TypeError('two available signatures (function, arguments) '
+                            'and (operator, operands) are exclusive')
+        if operator is not None:
+            if operands is None:
+                raise TypeError('operands are required')
+            elif not isinstance(operator, Identifier):
+                raise TypeError('operator must be a kong.ast.Identifier, not '
+                                + repr(operator))
+            if not isinstance(operands, list):
+                try:
+                    operands = list(operands)
+                except TypeError:
+                    raise TypeError('operands must be iterable')
+            if len(operands) != 2:
+                raise TypeError('binary operator takes only two arguments')
+            function = Attribute(operands.pop(0), attribute=operator)
+            arguments = operands
+        if not (isinstance(function, Attribute) or
+                isinstance(function, Application) and
+                len(function.arguments) == 1 and
+                isinstance(function.arguments[0], StringLiteral)):
+            raise TypeError('function must be kong.ast.Attribute or '
+                            'equivalent kong.ast.Application, not ' +
+                            repr(function))
+        if isinstance(arguments, (tuple, list)):
+            try:
+                arguments = tuple(arguments)
+            except TypeError:
+                raise TypeError('arguments must be iterable')
+        if len(arguments) != 1:
+            raise TypeError('operator takes only one argument')
+        Application.__init__(self, function, arguments)
+
+    @property
+    def operator(self):
+        """(:class:`Identifier`) Operator name.
+
+        .. sourcecode:: pycon
+
+           >>> op = Operator(Attribute(Identifier('a'),
+           ...                         attribute=Identifier('-')),
+           ...               [StringLiteral(123)])
+           >>> op.operator
+           kong.ast.Identifier(u'-')
+
+        """
+        return Identifier(self.function.arguments[0].string)
+
+    @property
+    def operands(self):
+        """(:class:`tuple`) Pair of two operands.
+
+        .. sourcecode:: pycon
+
+           >>> op = Operator(Attribute(Identifier('a'),
+           ...                         attribute=Identifier('-')),
+           ...               [StringLiteral(123)])
+           >>> op.operands
+           (kong.ast.Identifier(u'a'), kong.ast.StringLiteral(123))
+
+        """
+        return self.function.function, self.arguments[0]
+
+    def __unicode__(self):
+        a, b = self.operands
+        forms = a, self.operator, b
+        return u' '.join(itertools.imap(unicode, forms))
+
+
+class Definition(Expression):
+    """An abstract class for definition nodes.
+
+    .. productionlist::
+       define: `lvalue` "<-" `expr`
+       lvalue: ["."] `id` | `attr`
+
+    """
+
+    #: (:class:`Identifier`, :class:`Attribute`) Lvalue expression.
+    lvalue = NotImplemented
+
+    #: (:class:`Expression`) Rvalue expression.
+    rvalue = NotImplemented
+
+    def __unicode__(self):
+        args = self.lvalue, '<-', self.rvalue
+        return u' '.join(itertools.imap(unicode, args))
+
+    def __repr__(self):
+        cls = type(self)
+        args = cls.__module__, cls.__name__, self.lvalue, self.rvalue
+        return '{0}.{1}(lvalue={2!r}, rvalue={3!r})'.format(*args)
+
+
+class IdentifierDefinition(Definition):
+    """An abstract class for identifier definition nodes."""
+
+    __slots__ = 'lvalue', 'rvalue'
+
+    def __init__(self, lvalue, rvalue):
+        if not isinstance(lvalue, Identifier):
+            raise TypeError('lvalue must be a kong.ast.Identifier, not ' +
+                            repr(lvalue))
+        elif not isinstance(rvalue, Expression):
+            raise TypeError('rvalue must be a kong.ast.Expression, not ' +
+                            repr(rvalue))
+        self.lvalue = lvalue
+        self.rvalue = rvalue
+
+
+class IdentifierLocalDefinition(IdentifierDefinition):
+    """Local identifier definition node.
+
+    .. sourcecode:: pycon
+
+       >>> set = IdentifierLocalDefinition(lvalue=Identifier('abc'),
+       ...                                 rvalue=Identifier('def'))
+       >>> print unicode(set)
+       abc <- def
+
+    :param lvalue: lvalue identifier
+    :type lvalue: :class:`Identifier`
+    :param rvalue: rvalue expression
+    :type rvalue: :class:`Expression`
+
+    """
+
+
+class IdentifierAssignment(IdentifierDefinition):
+    """Identifier assignment node.
+
+    .. sourcecode:: pycon
+
+       >>> set = IdentifierAssignment(lvalue=Identifier('abc'),
+       ...                            rvalue=Identifier('def'))
+       >>> print unicode(set)
+       .abc <- def
+
+    :param lvalue: lvalue identifier
+    :type lvalue: :class:`Identifier`
+    :param rvalue: rvalue expression
+    :type rvalue: :class:`Expression`
+
+    """
+
+    def __unicode__(self):
+        return '.' + IdentifierDefinition.__unicode__(self)
+
+
+class AttributeDefinition(Definition, Application):
+    """A definition node of attribute. Attribute definitions are just
+    two arguments application under the hood. For example, following
+    two expressions are equivalent:
+
+    .. sourcecode:: tofu
+
+       obj.attr = value
+       obj('attr', value)
+
+    .. sourcecode:: pycon
+
+       >>> attr = Attribute(Identifier('abc'), attribute=Identifier('def'))
+       >>> set = AttributeDefinition(lvalue=attr, rvalue=StringLiteral(123))
+       >>> set.function
+       kong.ast.Identifier(u'abc')
+       >>> set.arguments
+       (kong.ast.StringLiteral(u'def'), kong.ast.StringLiteral(123))
+       >>> print unicode(set)
+       abc.def <- 123
+
+    There are two signatures. One is the same to :class:`Application`'s:
+
+    :param function: a function to apply
+    :type function: :class:`Expression`
+    :param arguments: a :class:`Expresion` list
+    :type arguments: :class:`collections.Iterable`
+
+    Other one is the same to :class:`Definition` or :class:`Assignment`'s
+    (but only by keywords):
+
+    :param lvalue: lvalue attribute
+    :type lvalue: :class:`Attribute`, :class:`Application`
+    :param rvalue: rvalue expression
+    :type rvalue: :class:`Expression`
+
+    """
+
+    def __init__(self, function=None, arguments=None, lvalue=None, rvalue=None):
+        if not (function is not None and arguments is not None or
+                lvalue is not None and lvalue is not None):
+            raise TypeError('it takes function and arguments both or '
+                            'lvalue and rvalue both')
+        if (function is not None or arguments is not None) and \
+           (lvalue is not None or rvalue is not None):
+            raise TypeError('two available signatures (function, arguments) '
+                            'and (lvalue, rvalue) are exclusive')
+        if lvalue is not None:
+            if rvalue is None:
+                raise TypeError('rvalue is required')
+            elif not (isinstance(lvalue, Attribute) or
+                      isinstance(lvalue, Application) and
+                      len(lvalue.arguments) == 1 and
+                      isinstance(lvalue.arguments[0], StringLiteral)):
+                raise TypeError('lvalue must be a kong.ast.Attribute or an '
+                                'equivalent kong.ast.Application, not ' +
+                                repr(lvalue))
+            elif not isinstance(rvalue, Expression):
+                raise TypeError('rvalue must be a kong.ast.Expression, not '
+                                + repr(rvalue))
+            function = lvalue.function
+            arguments = lvalue.arguments[0], rvalue
+        if len(arguments) != 2:
+            raise TypeError('only two arguments are accepted')
+        elif not isinstance(arguments[0], StringLiteral):
+            raise TypeError('arguments[0] must be a kong.ast.StringLiteral, '
+                            'not ' + repr(arguments[0]))
+        Application.__init__(self, function, arguments)
+
+    @property
+    def lvalue(self):
+        """(:class:`Attribute`) Lvalue attribute.
+
+        .. sourcecode:: pycon
+
+           >>> args = StringLiteral(u'attr'), StringLiteral(u'value')
+           >>> set = AttributeDefinition(Identifier('obj'), args)
+           >>> set.lvalue  # doctest: +NORMALIZE_WHITESPACE
+           kong.ast.Attribute(kong.ast.Identifier(u'obj'),
+                              attribute=kong.ast.Identifier(u'attr'))
+
+        """
+        return Attribute(self.function, self.arguments[:1])
+
+    @property
+    def rvalue(self):
+        """(:class:`Expression`) Rvalue expression.
+
+        .. sourcecode:: pycon
+
+           >>> args = StringLiteral(u'attr'), StringLiteral(u'value')
+           >>> set = AttributeDefinition(Identifier('obj'), args)
+           >>> set.rvalue
+           kong.ast.StringLiteral(u'value')
+
+        """
+        return self.arguments[1]
+
+
+class Literal(Expression):
+    """A literal node. It is an abstract class.
+
+    .. productionlist::
+       literal: `str_literal` | `dict_literal` | `func_def` | `list_literal`
+
+    """
+
+
+class ListLiteral(Literal, ExpressionList):
+    """A list literal node.
+
+    .. productionlist::
+       list_literal: "[" (`expr` ",")* [`expr`] "]"
+
+    :param expressions: :class:`Expression` list
+    :type expressions: :class:`collections.Iterable`
+
+    """
+
+    def __unicode__(self):
+        return u'[{0}]'.format(u', '.join(itertools.imap(unicode, self)))
+
+
+class DictionaryLiteral(Literal):
+    """A dictionary literal node.
+
+    .. productionlist::
+       dict_literal: "{" `program` "}"
+
+    .. sourcecode:: pycon
+
+       >>> prog = Program([
+       ...     IdentifierLocalDefinition(Identifier('a'), StringLiteral(123)),
+       ...     IdentifierLocalDefinition(Identifier('b'), StringLiteral(456))
+       ... ])
+       >>> d = DictionaryLiteral(prog)
+       >>> print unicode(d)
+       { a <- 123; b <- 456 }
+       >>> print unicode(DictionaryLiteral([]))
+       {}
+
+    :param program: :class:`Expression` list
+    :type program: :class:`Program`, :class:`ExpressionList`,
+                   :class:`collections.Iterable`
+
+    """
+
+    __slots__ = 'program',
+
+    def __init__(self, program):
+        if not isinstance(program, collections.Iterable):
+            raise TypeError('program must be iterable')
+        elif not isinstance(program, Program):
+            program = Program(program)
+        self.program = program
+
+    def __unicode__(self):
+        if self.program:
+            blk = u'; '.join(itertools.imap(unicode, self.program))
+            return u'{{ {0} }}'.format(blk)
+        return u'{}'
+
+
+class FunctionLiteral(Literal):
+    """A function literal node.
+
+    .. productionlist::
+       func_def: "(" `params` ")" ":" `dict_literal`
+       params: (`id` ",")* [`id`]
+
+    .. sourcecode:: pycon
+
+       >>> params = Identifier('a'), Identifier('b')
+       >>> prog = Program([Operator(operator=Identifier('+'),
+       ...                          operands=params)])
+       >>> f = FunctionLiteral(params, prog)
+       >>> print unicode(f)
+       (a, b): { a + b }
+
+    :param parameters: :class:`Identifier` list
+    :type parameters: :class:`collections.Iterable`
+    :param program: a program body :class:`Expression` list
+    :type program: :class:`Program`, :class:`ExpressionList`,
+                   :class:`collections.Iterable`
+
+    """
+
+    __slots__ = 'parameters', 'program'
+
+    def __init__(self, parameters, program):
+        if not isinstance(parameters, collections.Iterable):
+            raise TypeError('parameters must be iterable')
+        elif not isinstance(program, collections.Iterable):
+            raise TypeError('program must be iterable')
+        elif not isinstance(program, Program):
+            program = Program(program)
+        self.parameters = tuple(parameters)
+        self.program = program
+
+    def __unicode__(self):
+        params = u', '.join(itertools.imap(unicode, self.parameters))
+        blk = u'; '.join(itertools.imap(unicode, self.program))
+        return u'({0}): {{ {1} }}'.format(params, blk)
+
+
+class StringLiteral(Literal):
+    """A string literal node.
+
+    .. sourcecode:: pycon
+
+       >>> s = StringLiteral(u'string literal')
+       >>> s
+       kong.ast.StringLiteral(u'string literal')
+       >>> print unicode(s)
+       "string literal"
+       >>> n = StringLiteral(u'123')
+       >>> n
+       kong.ast.StringLiteral(123)
+       >>> print unicode(n)
+       123
+
+    .. productionlist::
+       str_literal: `number` | /"([^"]|\\.)*"/
+       number: `digit`+
+       digit: "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
+
+    :param string: a string
+    :type string: :class:`unicode`, :class:`numbers.Integral`
+
+    """
+
+    __slots__ = 'string',
+
+    def __init__(self, string):
+        if isinstance(string, numbers.Integral):
+            string = unicode(string)
+        elif not isinstance(string, unicode):
+            raise TypeError('string must be an unicode string or an integer, '
+                            'not ' + repr(string))
+        self.string = string if type(string) is unicode else unicode(string)
+
+    def __unicode__(self):
+        if self.string.isdigit():
+            return self.string
+        s = u''.join(u'\\\\' if c == u'\\' else c for c in self.string)
+        return u'"{0}"'.format(s)
+
+    def __repr__(self):
+        cls = type(self)
+        s = self.string if self.string.isdigit() else repr(self.string)
+        return '{0}.{1}({2})'.format(cls.__module__, cls.__name__, s)
+
+import doctest
+import unittest
+import pkgutil
+import kong
+
+
+def find_modules(module):
+    path = getattr(module, '__path__')
+    basename = module.__name__ + '.'
+    for _, modname, ispkg in pkgutil.iter_modules(path):
+        modname = basename + modname
+        yield modname
+        if ispkg:
+            mod = reduce(getattr, modname.split('.')[1:], __import__(modname))
+            for item in find_modules(mod):
+                yield item
+
+
+def suite():
+    suite = unittest.TestSuite()
+    for mod in find_modules(kong):
+        suite.addTest(doctest.DocTestSuite(mod))
+    return suite
+
+try:
+    from setuptools import setup
+except ImportError:
+    from distutils.core import setup
+
+
+setup(name='Kong',
+      version='0.1',
+      author='Hong Minhee',
+      author_email='minhee' '@' 'dahlia.kr',
+      packages=['kong'],
+      install_requires=['LEPL'],
+      extras_require={'docs': ['Sphinx >=1.0']},
+      test_suite='kongtests.suite')
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.