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
|