예제 #1
0
def _MyPyType(typ):
    type_name = typ.name

    if type_name == 'map':
        k_type = _MyPyType(typ.children[0])
        v_type = _MyPyType(typ.children[1])
        return 'Dict[%s, %s]' % (k_type, v_type)

    if type_name == 'array':
        return 'List[%s]' % _MyPyType(typ.children[0])

    if type_name == 'maybe':
        # TODO: maybe[int] and maybe[simple_sum] are invalid
        return 'Optional[%s]' % _MyPyType(typ.children[0])

    if typ.resolved:
        if isinstance(typ.resolved, asdl_.Sum):  # includes SimpleSum
            return '%s_t' % typ.name
        if isinstance(typ.resolved, asdl_.Product):
            return typ.name
        if isinstance(typ.resolved, asdl_.Use):
            return asdl_.TypeNameHeuristic(type_name)

    # 'id' falls through here
    return _PRIMITIVES[type_name]
예제 #2
0
파일: gen_cpp.py 프로젝트: o11c/oil
def _GetCppType(typ):
    type_name = typ.name

    if type_name == 'map':
        k_type = _GetCppType(typ.children[0])
        v_type = _GetCppType(typ.children[1])
        return 'Dict<%s, %s>*' % (k_type, v_type)

    elif type_name == 'array':
        c_type = _GetCppType(typ.children[0])
        return 'List<%s>*' % (c_type)

    elif type_name == 'maybe':
        c_type = _GetCppType(typ.children[0])
        # TODO: maybe[int] and maybe[simple_sum] are invalid
        return c_type

    elif typ.resolved:
        if isinstance(typ.resolved, asdl_.SimpleSum):
            return '%s_t' % typ.name
        if isinstance(typ.resolved, asdl_.Sum):
            return '%s_t*' % typ.name
        if isinstance(typ.resolved, asdl_.Product):
            return '%s*' % typ.name
        if isinstance(typ.resolved, asdl_.Use):
            return '%s_asdl::%s*' % (typ.resolved.mod_name,
                                     asdl_.TypeNameHeuristic(type_name))

    # 'id' falls through here
    return _PRIMITIVES[typ.name]
예제 #3
0
def main(argv):
    try:
        action = argv[1]
    except IndexError:
        raise RuntimeError('Action required')

    try:
        schema_path = argv[2]
    except IndexError:
        raise RuntimeError('Schema path required')

    schema_filename = os.path.basename(schema_path)
    if schema_filename in ('syntax.asdl', 'runtime.asdl'):
        app_types = {'id': UserType('id_kind_asdl', 'Id_t')}
    else:
        app_types = {}

    if action == 'c':  # Generate C code for the lexer
        with open(schema_path) as f:
            schema_ast = front_end.LoadSchema(f, app_types)

        v = gen_cpp.CEnumVisitor(sys.stdout)
        v.VisitModule(schema_ast)

    elif action == 'cpp':  # Generate C++ code for ASDL schemas
        out_prefix = argv[3]
        pretty_print_methods = bool(os.getenv('PRETTY_PRINT_METHODS', 'yes'))

        with open(schema_path) as f:
            schema_ast = front_end.LoadSchema(f, app_types)

        # asdl/typed_arith.asdl -> typed_arith_asdl
        ns = os.path.basename(schema_path).replace('.', '_')

        with open(out_prefix + '.h', 'w') as f:
            guard = ns.upper()
            f.write("""\
// %s.h is generated by asdl/tool.py

#ifndef %s
#define %s

""" % (out_prefix, guard, guard))

            f.write("""\
#include <cstdint>
#include "mylib.h"  // for Str, List, etc.

""")

            if pretty_print_methods:
                f.write("""\
#include "hnode_asdl.h"
using hnode_asdl::hnode_t;

""")

            if app_types:
                f.write("""\
#include "id_kind_asdl.h"
using id_kind_asdl::Id_t;

""")

            for use in schema_ast.uses:
                # Forward declarations in the header, like
                # namespace syntax_asdl { class command_t; }
                # must come BEFORE namespace, so it can't be in the visitor.

                # assume sum type for now!
                cpp_names = [
                    'class %s;' % asdl_.TypeNameHeuristic(n)
                    for n in use.type_names
                ]
                f.write('namespace %s_asdl { %s }\n' %
                        (use.mod_name, ' '.join(cpp_names)))
                f.write('\n')

            f.write("""\
namespace %s {

""" % ns)

            v = gen_cpp.ForwardDeclareVisitor(f)
            v.VisitModule(schema_ast)

            debug_info = {}
            v2 = gen_cpp.ClassDefVisitor(
                f,
                pretty_print_methods=pretty_print_methods,
                simple_int_sums=_SIMPLE,
                debug_info=debug_info)
            v2.VisitModule(schema_ast)

            f.write("""
}  // namespace %s

#endif  // %s
""" % (ns, guard))

            try:
                debug_info_path = argv[4]
            except IndexError:
                pass
            else:
                with open(debug_info_path, 'w') as f:
                    from pprint import pformat
                    f.write('''\
cpp_namespace = %r
tags_to_types = \\
%s
''' % (ns, pformat(debug_info)))

            with open(out_prefix + '.cc', 'w') as f:
                f.write("""\
// %s.cc is generated by asdl/tool.py

#include "%s.h"
#include <assert.h>
#include "asdl_runtime.h"  // generated code uses wrappers here

""" % (out_prefix, ns))

                # To call pretty-printing methods
                for use in schema_ast.uses:
                    f.write('#include "%s_asdl.h"  // ASDL use\n' %
                            use.mod_name)

                f.write("""\

// Generated code uses these types
using hnode_asdl::hnode__Record;
using hnode_asdl::hnode__Array;
using hnode_asdl::hnode__External;
using hnode_asdl::hnode__Leaf;
using hnode_asdl::field;
using hnode_asdl::color_e;

""")

                if app_types:
                    f.write('using id_kind_asdl::Id_str;\n')

                f.write("""
namespace %s {

""" % ns)

                v3 = gen_cpp.MethodDefVisitor(
                    f,
                    pretty_print_methods=pretty_print_methods,
                    simple_int_sums=_SIMPLE)
                v3.VisitModule(schema_ast)

                f.write("""
}  // namespace %s
""" % ns)

    elif action == 'mypy':  # Generated typed MyPy code
        with open(schema_path) as f:
            schema_ast = front_end.LoadSchema(f, app_types)

        try:
            abbrev_module_name = argv[3]
        except IndexError:
            abbrev_mod = None
        else:
            # Weird Python rule for importing: fromlist needs to be non-empty.
            abbrev_mod = __import__(abbrev_module_name, fromlist=['.'])

        f = sys.stdout

        # TODO: Remove Any once we stop using it
        f.write("""\
from asdl import pybase
from typing import Optional, List, Tuple, Dict, Any, cast, TYPE_CHECKING
""")

        if schema_ast.uses:
            f.write('\n')
            f.write('if TYPE_CHECKING:\n')
        for use in schema_ast.uses:
            py_names = [asdl_.TypeNameHeuristic(n) for n in use.type_names]
            # indented
            f.write('  from _devbuild.gen.%s_asdl import %s\n' %
                    (use.mod_name, ', '.join(py_names)))
        f.write('\n')

        for typ in app_types.itervalues():
            if isinstance(typ, UserType):
                f.write('from _devbuild.gen.%s import %s\n' %
                        (typ.mod_name, typ.type_name))
                # HACK
                f.write('from _devbuild.gen.%s import Id_str\n' % typ.mod_name)
                f.write('\n')

        pretty_print_methods = bool(os.getenv('PRETTY_PRINT_METHODS', 'yes'))
        optional_fields = bool(os.getenv('OPTIONAL_FIELDS', 'yes'))

        if pretty_print_methods:
            f.write("""
from asdl import runtime  # For runtime.NO_SPID
from asdl.runtime import NewRecord, NewLeaf
from _devbuild.gen.hnode_asdl import color_e, hnode, hnode_e, hnode_t, field

""")

        abbrev_mod_entries = dir(abbrev_mod) if abbrev_mod else []
        v = gen_python.GenMyPyVisitor(
            f,
            abbrev_mod_entries,
            pretty_print_methods=pretty_print_methods,
            optional_fields=optional_fields,
            simple_int_sums=_SIMPLE)
        v.VisitModule(schema_ast)

        if abbrev_mod:
            f.write("""\
#
# CONCATENATED FILE
#

""")
            package, module = abbrev_module_name.split('.')
            path = os.path.join(package, module + '.py')
            with open(path) as in_f:
                f.write(in_f.read())

    else:
        raise RuntimeError('Invalid action %r' % action)