def main(argv): #print lex_mode_e #print dir(lex_mode_e) app_types = {'id': asdl.UserType(Id)} with open('osh/types.asdl') as f: asdl_module, _ = asdl.LoadSchema(f, app_types) v = gen_cpp.CEnumVisitor(sys.stdout) v.VisitModule(asdl_module)
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] app_types = {'id': asdl.UserType(Id)} with open(schema_path) as input_f: module, type_lookup = asdl.LoadSchema(input_f, app_types) # TODO: gen_cpp.py should be a library and the application should add Id? # Or we should enable ASDL metaprogramming, and let Id be a metaprogrammed # simple sum type. 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)
# TODO: Fold Id into ASDL, which will enforce uniqueness? _ID_INSTANCES = {} # int -> Id def IdInstance(i): return _ID_INSTANCES[i] # # Instantiate osh/types.asdl # f = util.GetResourceLoader().open('osh/types.asdl') _asdl_module, _type_lookup = asdl.LoadSchema(f, {}) # no app_types types = _AsdlModule() if 0: py_meta.MakeTypes(_asdl_module, types, _type_lookup) else: # Exported for the generated code to use TYPES_TYPE_LOOKUP = _type_lookup # Get the types from elsewhere from _devbuild.gen import types_asdl py_meta.AssignTypes(types_asdl, types) f.close() # Id -> bool_arg_type_e
#!/usr/bin/env python """ arith_ast.py """ import sys from asdl import asdl_ as asdl from asdl import py_meta from core import util f = util.GetResourceLoader().open('asdl/arith.asdl') _asdl_module, _type_lookup = asdl.LoadSchema(f, {}) # no app_types f.close() root = sys.modules[__name__] py_meta.MakeTypes(_asdl_module, root, _type_lookup)