Beispiel #1
0
def main(argv):
  try:
    action = argv[1]
  except IndexError:
    raise RuntimeError('Action required')

  if action == 'py':  # Prints the module
    schema_path = argv[2]

    with open(schema_path) as f:
      module = asdl.parse(f)

    app_types = {'id': asdl.UserType(Id)}
    type_lookup = asdl.ResolveTypes(module, app_types)

    # Note this is a big tree.  But we really want a graph of pointers to
    # instances.
    # Type(name, Product(...))
    # Type(name, Sum([Constructor(...), ...]))
    #print(module)

    root = sys.modules[__name__]
    # NOTE: We shouldn't pass in app_types for arith.asdl, but this is just a
    # demo.
    py_meta.MakeTypes(module, root, type_lookup)

    print('Dynamically created a Python module with these types:')
    for name in dir(root):
      print('\t' + name)

  elif action == 'arith-encode':  # oheap encoding
    expr = argv[2]
    out_path = argv[3]

    obj = arith_parse.ParseShell(expr)
    print('Encoding %r into binary:' % expr)
    print(obj)

    enc = encode.Params()
    with open(out_path, 'wb') as f:
      out = encode.BinOutput(f)
      encode.EncodeRoot(obj, enc, out)

  elif action == 'arith-format':  # pretty printing
    expr = argv[2]

    obj = arith_parse.ParseShell(expr)
    #out = fmt.TextOutput(sys.stdout)
    tree = fmt.MakeTree(obj)
    #treee= ['hi', 'there', ['a', 'b'], 'c']
    f = fmt.DetectConsoleOutput(sys.stdout)
    fmt.PrintTree(tree, f)
    print()

    # Might need to print the output?
    # out.WriteToFile?

  else:
    raise RuntimeError('Invalid action %r' % action)
Beispiel #2
0
def _LoadSchema(f):
    module = asdl.parse(f)

    app_types = {'id': asdl.UserType(Id)}
    type_lookup = asdl.ResolveTypes(module, app_types)

    # Check for type errors
    if not asdl.check(module, app_types):
        raise AssertionError('ASDL file is invalid')
    return module, type_lookup
Beispiel #3
0
def LoadSchema(f):
    app_types = {'id': asdl.UserType(Id)}

    asdl_module = asdl.parse(f)

    if not asdl.check(asdl_module, app_types):
        raise AssertionError('ASDL file is invalid')

    type_lookup = asdl.ResolveTypes(asdl_module, app_types)
    return asdl_module, type_lookup
Beispiel #4
0
def main(argv):
    try:
        action = argv[1]
    except IndexError:
        raise RuntimeError('Action required')

    # TODO: Also generate a switch/static_cast<> pretty printer in C++!  For
    # debugging.  Might need to detect cycles though.
    if action == 'cpp':
        schema_path = argv[2]
        with open(schema_path) as input_f:
            module = asdl.parse(input_f)
        type_lookup = asdl.ResolveTypes(module)

        f = sys.stdout

        # How do mutation of strings, arrays, etc.  work?  Are they like C++
        # containers, or their own?  I think they mirror the oil language
        # semantics.
        # Every node should have a mirror.  MutableObj.  MutableRef (pointer).
        # MutableArithVar -- has std::string.  The mirrors are heap allocated.
        # All the mutable ones should support Dump()/Encode()?
        # You can just write more at the end... don't need to disturb existing
        # nodes?  Rewrite pointers.

        alignment = 4
        enc = encode.Params(alignment)
        d = {'pointer_type': enc.pointer_type}

        f.write("""\
#include <cstdint>

class Obj {
 public:
  // Decode a 3 byte integer from little endian
  inline int Int(int n) const;

  inline const Obj& Ref(const %(pointer_type)s* base, int n) const;

  inline const Obj* Optional(const %(pointer_type)s* base, int n) const;

  // NUL-terminated
  inline const char* Str(const %(pointer_type)s* base, int n) const;

 protected:
  uint8_t bytes_[1];  // first is ID; rest are a payload
};

""" % d)

        # Id should be treated as an enum.
        c = ChainOfVisitors(
            ForwardDeclareVisitor(f),
            ClassDefVisitor(f, enc, type_lookup, enum_types=['Id']))
        c.VisitModule(module)

        f.write("""\
inline int Obj::Int(int n) const {
  return bytes_[n] + (bytes_[n+1] << 8) + (bytes_[n+2] << 16);
}

inline const Obj& Obj::Ref(const %(pointer_type)s* base, int n) const {
  int offset = Int(n);
  return reinterpret_cast<const Obj&>(base[offset]);
}

inline const Obj* Obj::Optional(const %(pointer_type)s* base, int n) const {
  int offset = Int(n);
  if (offset) {
    return reinterpret_cast<const Obj*>(base + offset);
  } else {
    return nullptr;
  }
}

inline const char* Obj::Str(const %(pointer_type)s* base, int n) const {
  int offset = Int(n);
  return reinterpret_cast<const char*>(base + offset);
}
""" % d)
    # uint32_t* and char*/Obj* aren't related, so we need to use
    # reinterpret_cast<>.
    # http://stackoverflow.com/questions/10151834/why-cant-i-static-cast-between-char-and-unsigned-char

    else:
        raise RuntimeError('Invalid action %r' % action)
Beispiel #5
0
#!/usr/bin/env python
"""
arith_ast.py
"""

import os
import sys

from asdl import asdl_ as asdl
from asdl import py_meta

this_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
schema_path = os.path.join(this_dir, 'arith.asdl')

with open(schema_path) as f:
  module = asdl.parse(f)
type_lookup = asdl.ResolveTypes(module)
root = sys.modules[__name__]
py_meta.MakeTypes(module, root, type_lookup)