| 1 | #!/usr/bin/env python2
|
| 2 | """
|
| 3 | yaks_main.py - Generate C++ from Yaks IR.
|
| 4 |
|
| 5 | Uses yaks.asdl. Will this be rewritten as yaks_main.yaks?
|
| 6 | """
|
| 7 | from __future__ import print_function
|
| 8 |
|
| 9 | import sys
|
| 10 |
|
| 11 | from _devbuild.gen import yaks_asdl
|
| 12 | from asdl import format as fmt
|
| 13 | from core import error
|
| 14 | from data_lang import j8
|
| 15 | from mycpp import mylib
|
| 16 | from yaks import transform
|
| 17 | from yaks import gen_cpp
|
| 18 |
|
| 19 | from typing import List
|
| 20 | """
|
| 21 | def Options():
|
| 22 | # type: () -> optparse.OptionParser
|
| 23 | "Returns an option parser instance."
|
| 24 |
|
| 25 | p = optparse.OptionParser()
|
| 26 | p.add_option('--no-pretty-print-methods',
|
| 27 | dest='pretty_print_methods',
|
| 28 | action='store_false',
|
| 29 | default=True,
|
| 30 | help='Whether to generate pretty printing methods')
|
| 31 |
|
| 32 | # Control Python constructors
|
| 33 |
|
| 34 | # for hnode.asdl
|
| 35 | p.add_option('--py-init-N',
|
| 36 | dest='py_init_n',
|
| 37 | action='store_true',
|
| 38 | default=False,
|
| 39 | help='Generate Python __init__ that requires every field')
|
| 40 |
|
| 41 | # The default, which matches C++
|
| 42 | p.add_option(
|
| 43 | '--init-zero-N',
|
| 44 | dest='init_zero_n',
|
| 45 | action='store_true',
|
| 46 | default=True,
|
| 47 | help='Generate 0 arg and N arg constructors, in Python and C++')
|
| 48 |
|
| 49 | return p
|
| 50 | """
|
| 51 |
|
| 52 |
|
| 53 | def main(argv):
|
| 54 | # type: (List[str]) -> int
|
| 55 |
|
| 56 | #o = Options()
|
| 57 | #opts, argv = o.parse_args(argv)
|
| 58 |
|
| 59 | stderr_ = mylib.Stderr()
|
| 60 | try:
|
| 61 | action = argv[1]
|
| 62 | except IndexError:
|
| 63 | raise RuntimeError('Action required')
|
| 64 |
|
| 65 | if action == 'cpp':
|
| 66 | # Usage:
|
| 67 | # - Specify a root file - each file contains a module
|
| 68 | # - this module may or may not contain main()
|
| 69 | # - then it will walk imports, and create a big list of modules
|
| 70 | # - then does it make a SINGLE translation unit for all modules?
|
| 71 | # - and then maybe generate a unit test that links the translation unit
|
| 72 | # and calls a function?
|
| 73 | # - I suppose we could add main() to each module, like core/ and osh/
|
| 74 |
|
| 75 | path = argv[2]
|
| 76 | #with open(path) as f:
|
| 77 | # contents = f.read()
|
| 78 |
|
| 79 | # TODO: could implement mylib.SlurpFile()
|
| 80 | lines = [] # type: List[str]
|
| 81 | f = mylib.open(path)
|
| 82 | while True:
|
| 83 | line = f.readline()
|
| 84 | if len(line) == 0:
|
| 85 | break
|
| 86 | lines.append(line)
|
| 87 |
|
| 88 | #contents = '(print "hi")'
|
| 89 | contents = ''.join(lines)
|
| 90 |
|
| 91 | p = j8.Nil8Parser(contents, True)
|
| 92 |
|
| 93 | try:
|
| 94 | nval = p.ParseNil8()
|
| 95 | except error.Decode as e:
|
| 96 | # print e.SourceLine() ?
|
| 97 |
|
| 98 | # Do we also want ~~~ ^ ~~~ type of hints?
|
| 99 | # Or just ^ and ^~~~~ ?
|
| 100 | #
|
| 101 | # I think the default is the former
|
| 102 | #
|
| 103 | # Data could perhaps use ~~~^
|
| 104 |
|
| 105 | # factor this out of core/ui.py
|
| 106 | # print util.LocationAsciiArt(e.begin_col, e.end_col) ?
|
| 107 |
|
| 108 | # ui._PrintCodeExcerpt()
|
| 109 | # Could also be in error
|
| 110 |
|
| 111 | if mylib.PYTHON:
|
| 112 | print(e.Message(), file=sys.stderr)
|
| 113 | return 1
|
| 114 |
|
| 115 | #print(obj)
|
| 116 |
|
| 117 | # Dump ASDL representation
|
| 118 | # We could also have a NIL8 printer
|
| 119 | pretty_f = fmt.DetectConsoleOutput(stderr_)
|
| 120 | fmt.PrintTree(nval.PrettyTree(), pretty_f)
|
| 121 | stderr_.write('\n')
|
| 122 |
|
| 123 | prog = transform.Transform(nval)
|
| 124 |
|
| 125 | fmt.PrintTree(prog.PrettyTree(), pretty_f)
|
| 126 | stderr_.write('\n')
|
| 127 |
|
| 128 | # TODO: a few mycpp passes over this representation
|
| 129 | # - not sure if we'll need any more IRs
|
| 130 | gen_cpp.GenCpp(prog, mylib.Stdout())
|
| 131 |
|
| 132 | elif action == 'check':
|
| 133 | # Only do type checking?
|
| 134 |
|
| 135 | path = argv[2]
|
| 136 |
|
| 137 | m = yaks_asdl.Module('hi', [])
|
| 138 |
|
| 139 | pretty_f = fmt.DetectConsoleOutput(stderr_)
|
| 140 | fmt.PrintTree(m.PrettyTree(), pretty_f)
|
| 141 | stderr_.write('\n')
|
| 142 |
|
| 143 | else:
|
| 144 | raise RuntimeError('Invalid action %r' % action)
|
| 145 |
|
| 146 | return 0
|
| 147 |
|
| 148 |
|
| 149 | if __name__ == '__main__':
|
| 150 | try:
|
| 151 | main(sys.argv)
|
| 152 | except RuntimeError as e:
|
| 153 | print('%s: FATAL: %s' % (sys.argv[0], e), file=sys.stderr)
|
| 154 | sys.exit(1)
|
| 155 |
|
| 156 | # vim: sw=4
|