OILS / yaks / yaks_main.py View on Github | oilshell.org

156 lines, 55 significant
1#!/usr/bin/env python2
2"""
3yaks_main.py - Generate C++ from Yaks IR.
4
5Uses yaks.asdl. Will this be rewritten as yaks_main.yaks?
6"""
7from __future__ import print_function
8
9import sys
10
11from _devbuild.gen import yaks_asdl
12from asdl import format as fmt
13from core import error
14from data_lang import j8
15from mycpp import mylib
16from yaks import transform
17from yaks import gen_cpp
18
19from typing import List
20"""
21def 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
53def 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
149if __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