From c63fa2bbbdde21fb45ea98e3c69bbddbf25097a5 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Thu, 29 Oct 2020 17:26:20 -0600 Subject: start to elaborate on syntax --- _ext/crowbar_domain.py | 110 ++++++++++++++++++++++++++++++++++++++++++++++ conf.py | 4 ++ index.rst | 3 ++ language/flow-control.rst | 6 +++ language/index.rst | 26 +++++++++++ language/scanning.rst | 42 ++++++++++++++++++ todo.rst | 4 ++ 7 files changed, 195 insertions(+) create mode 100644 _ext/crowbar_domain.py create mode 100644 language/flow-control.rst create mode 100644 language/index.rst create mode 100644 language/scanning.rst create mode 100644 todo.rst diff --git a/_ext/crowbar_domain.py b/_ext/crowbar_domain.py new file mode 100644 index 0000000..a5f2570 --- /dev/null +++ b/_ext/crowbar_domain.py @@ -0,0 +1,110 @@ +from collections import defaultdict + +from docutils.parsers.rst import directives + +from sphinx import addnodes +from sphinx.directives import ObjectDescription +from sphinx.domains import Domain +from sphinx.domains import Index +from sphinx.roles import XRefRole +from sphinx.util.nodes import make_refnode + + +class KeywordDirective(ObjectDescription): + has_content = True + required_arguments = 1 + + def handle_signature(self, sig, signode): + signode += addnodes.desc_name(text=sig) + return sig + + def add_target_and_index(self, name_cls, sig, signode): + signode['ids'].append('keyword' + '-' + sig) + if 'noindex' not in self.options: + crowbar = self.env.get_domain('crowbar') + crowbar.add_keyword(sig) + + +class KeywordIndex(Index): + name = 'keyword' + localname = 'Keyword Index' + shortname = 'Keyword' + + def generate(self, docnames=None): + content = defaultdict(list) + + # sort the list of recipes in alphabetical order + recipes = self.domain.get_objects() + recipes = sorted(recipes, key=lambda recipe: recipe[0]) + + # generate the expected output, shown below, from the above using the + # first letter of the recipe as a key to group thing + # + # name, subtype, docname, anchor, extra, qualifier, description + for name, dispname, typ, docname, anchor, _ in recipes: + content[dispname[0].lower()].append( + (dispname, 0, docname, anchor, docname, '', typ)) + + # convert the dict to the sorted list of tuples expected + content = sorted(content.items()) + + return content, True + + +class CrowbarDomain(Domain): + name = 'crowbar' + label = 'Crowbar' + roles = { + 'ref': XRefRole() + } + directives = { + 'keyword': KeywordDirective, + } + indices = { + KeywordIndex, + } + initial_data = { + 'keywords': [], + } + + def get_full_qualified_name(self, node): + return '{}.{}'.format('keyword', node.arguments[0]) + + def get_objects(self): + for obj in self.data['keywords']: + yield(obj) + + def resolve_xref(self, env, fromdocname, builder, typ, target, node, + contnode): + match = [(docname, anchor) + for name, sig, typ, docname, anchor, prio + in self.get_objects() if sig == target] + + if len(match) > 0: + todocname = match[0][0] + targ = match[0][1] + + return make_refnode(builder, fromdocname, todocname, targ, + contnode, targ) + else: + print('Awww, found nothing') + return None + + def add_keyword(self, signature): + """Add a new keyword to the domain.""" + name = '{}.{}'.format('keyword', signature) + anchor = 'keyword-{}'.format(signature) + + # name, dispname, type, docname, anchor, priority + self.data['keywords'].append( + (name, signature, 'Keyword', self.env.docname, anchor, 0)) + + +def setup(app): + app.add_domain(CrowbarDomain) + + return { + 'version': '0.1', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + } diff --git a/conf.py b/conf.py index 9aa2aa3..97209db 100644 --- a/conf.py +++ b/conf.py @@ -31,6 +31,8 @@ extensions = [ 'recommonmark', 'crowbar_lexer', 'gemtext_builder', + 'crowbar_domain', + 'sphinx.ext.todo', ] # Add any paths that contain templates here, relative to this directory. @@ -43,6 +45,8 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] highlight_language = 'crowbar' +todo_include_todos = True + # -- Options for HTML output ------------------------------------------------- diff --git a/index.rst b/index.rst index 1b6f429..99f5d44 100644 --- a/index.rst +++ b/index.rst @@ -57,7 +57,9 @@ Chapters safety errors syntax + language/index LICENSE + todo .. only:: html @@ -65,4 +67,5 @@ Chapters ================== * :ref:`genindex` + * :ref:`crowbar-keyword` * :ref:`search` diff --git a/language/flow-control.rst b/language/flow-control.rst new file mode 100644 index 0000000..853b5bd --- /dev/null +++ b/language/flow-control.rst @@ -0,0 +1,6 @@ +Flow Control +============ + +.. crowbar:keyword:: break + + This keyword exits the containing loop. diff --git a/language/index.rst b/language/index.rst new file mode 100644 index 0000000..79702c5 --- /dev/null +++ b/language/index.rst @@ -0,0 +1,26 @@ +Language +======== + +The syntax of Crowbar is designed to be similar to the syntax of C. + +A Crowbar source file is UTF-8. +Crowbar source files can come in two varieties: + +.. glossary:: + + header file + A Crowbar source file declaring types and functions. + Can be intended for internal use within a project, or to define the public API of a library. + Conventionally has the ``.hro`` file extension. + + implementation file + A Crowbar source file providing function definitions, and sometimes its own type declarations. + Conventionally has the ``.cro`` file extension. + +A Crowbar source file is read into memory in two phases: *scanning* (which converts text into an unstructured sequence of tokens) and *parsing* (which converts an unstructured sequence of tokens into a parse tree). + +.. toctree:: + :maxdepth: 1 + + scanning + flow-control diff --git a/language/scanning.rst b/language/scanning.rst new file mode 100644 index 0000000..7a7b7d3 --- /dev/null +++ b/language/scanning.rst @@ -0,0 +1,42 @@ +Scanning +-------- + +.. glossary:: + + keyword + One of the literal words ``bool``, :crowbar:ref:`break`, ``case``, + ``char``, ``const``, ``continue``, ``default``, ``do``, ``double``, + ``else``, ``enum``, ``extern``, ``float``, ``for``, ``fragile``, + ``function``, ``if``, ``include``, ``int``, ``long``, ``return``, + ``short``, ``signed``, ``sizeof``, ``struct``, ``switch``, + ``unsigned``, ``void``, or ``while``. + + identifier + A nonempty sequence of characters blah blah blah + + .. todo:: + + figure out https://www.unicode.org/reports/tr31/tr31-33.html + + decimal constant + A sequence of characters matching the regular expression ``[0-9_]+``. + Denotes the numeric value of the given sequence of decimal digits. + Underscores are ignored by the compiler, but may be useful separators for other readers. + + binary constant + A sequence of characters matching the regular expression ``0[bB][01_]+``. + Denotes the numeric value of the given sequence of binary digits (after the ``0[bB]`` prefix has been removed). + Underscores are ignored by the compiler, but may be useful separators for other readers. + + octal constant + A sequence of characters matching the regular expression ``0o[0-7_]+``. + Denotes the numeric value of the given sequence of octal digits (after the ``0o`` prefix has been removed). + Underscores are ignored by the compiler, but may be useful separators for other readers. + + token + A single atomic unit in a Crowbar source file. + Has one (and exactly one) of the following types. + +.. todo:: + + finish transcribing token definitions diff --git a/todo.rst b/todo.rst new file mode 100644 index 0000000..7f4d178 --- /dev/null +++ b/todo.rst @@ -0,0 +1,4 @@ +TODO +==== + +.. todolist:: -- cgit v1.2.3