elvish/parse/boilerplate.py
2016-02-02 18:39:44 +00:00

67 lines
2.0 KiB
Python
Executable File

#!/usr/bin/python2.7
import re
def put_set(out, parent, field, child):
print >>out, '''
func (n *{parent}) set{field}(ch *{child}) {{
n.{field} = ch
addChild(n, ch)
}}'''.format(parent=parent, field=field, child=child)
def put_addto(out, parent, field, child):
print >>out, '''
func (n *{parent}) addTo{field}(ch *{child}) {{
n.{field} = append(n.{field}, ch)
addChild(n, ch)
}}'''.format(parent=parent, field=field, child=child)
def put_parse(out, typename, extraargs):
extranames = ', '.join(a.split(' ')[0] for a in extraargs.split(', ')) if extraargs else ''
print >>out, '''
func parse{typename}(ps *parser{extraargs}) *{typename} {{
n := &{typename}{{node: node{{begin: ps.pos}}}}
n.parse(ps{extranames})
n.end = ps.pos
n.sourceText = ps.src[n.begin:n.end]
return n
}}'''.format(typename=typename, extraargs=extraargs, extranames=extranames)
def main():
types = []
in_type = ''
out = open('boilerplate.go', 'w')
print >>out, 'package parse'
for line in file('parse.go'):
if in_type:
if line == '}\n':
in_type = ''
continue
m = re.match(r'^\t(\w+(?:, \w+)*) +(\S+)', line)
if m:
fields = m.group(1).split(', ')
typename = m.group(2)
if typename.startswith('*'):
# Single child
[put_set(out, in_type, f, typename[1:]) for f in fields]
elif typename.startswith('[]*'):
# Children list
[put_addto(out, in_type, f, typename[3:]) for f in fields]
continue
m = re.match(r'^type (.*) struct', line)
if m:
in_type = m.group(1)
continue
m = re.match(
r'^func \(.* \*(.*)\) parse\(ps \*parser(.*?)\) {$', line)
if m:
typename, extraargs = m.groups()
put_parse(out, typename, extraargs)
if __name__ == '__main__':
main()