aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
author1138-4EB <1138-4EB@users.noreply.github.com>2019-06-17 07:57:59 +0200
committertgingold <tgingold@users.noreply.github.com>2019-06-17 07:57:59 +0200
commitf6379989022c1e71017f4151392a300534d2007a (patch)
tree783ba27543a32a5c009a5cdc92952809a1436728 /src
parent159e0bfdbb135e74aac10e54c7a499e9e34aa5a2 (diff)
downloadghdl-f6379989022c1e71017f4151392a300534d2007a.tar.gz
ghdl-f6379989022c1e71017f4151392a300534d2007a.tar.bz2
ghdl-f6379989022c1e71017f4151392a300534d2007a.zip
fix: move src/xtools to python/xtools (#846)
* fix: move src/xtools to python/xtools * fix Makefiles affected by xtools and pnodes being moved
Diffstat (limited to 'src')
-rw-r--r--src/edif/Makefile2
-rw-r--r--src/psl/Makefile2
-rw-r--r--src/vhdl/Makefile4
-rwxr-xr-xsrc/xtools/pnodes.py929
4 files changed, 4 insertions, 933 deletions
diff --git a/src/edif/Makefile b/src/edif/Makefile
index 7d2fa6980..3a3cb4a8b 100644
--- a/src/edif/Makefile
+++ b/src/edif/Makefile
@@ -6,7 +6,7 @@ ortho_srcdir=../ortho
GEN_SRCS=edif-nodes.adb edif-nodes_meta.ads edif-nodes_meta.adb
CC=gcc
-PNODES=../xtools/pnodes.py
+PNODES=../../python/xtools/pnodes.py
PNODES_ARGS=--field-file=edif-nodes.adb.in --kind-file=edif-nodes.ads --node-file=edif-nodes.ads --template-file=edif-nodes.adb.in --meta-basename=edif-nodes_meta --kind-type=Nkind --kind-range-prefix=Nkinds_ --kind-prefix=N_ --node-type=Node
all: dump_edif
diff --git a/src/psl/Makefile b/src/psl/Makefile
index 472a82b01..fdcfccaf7 100644
--- a/src/psl/Makefile
+++ b/src/psl/Makefile
@@ -20,7 +20,7 @@
# be committed and distribued with the sources, so that users don't need to
# regenerate them (and don't need to have python installed).
-PNODES=../xtools/pnodes.py
+PNODES=../../python/xtools/pnodes.py
DEPS=psl-nodes.ads psl-nodes.adb.in $(PNODES)
diff --git a/src/vhdl/Makefile b/src/vhdl/Makefile
index 425563a18..3f09c855f 100644
--- a/src/vhdl/Makefile
+++ b/src/vhdl/Makefile
@@ -20,8 +20,8 @@
# be committed and distribued with the sources, so that users don't need to
# regenerate them (and don't need to have python installed).
-PNODES=../xtools/pnodes.py
-PNODESPY=python/pnodespy.py
+PNODES=../../python/xtools/pnodes.py
+PNODESPY=../../python/pnodes/pnodespy.py
DEPS=vhdl-nodes.ads vhdl-nodes.adb.in $(PNODES)
diff --git a/src/xtools/pnodes.py b/src/xtools/pnodes.py
deleted file mode 100755
index 62d5362d3..000000000
--- a/src/xtools/pnodes.py
+++ /dev/null
@@ -1,929 +0,0 @@
-#!/usr/bin/env python
-
-import re
-import sys
-import argparse
-
-field_file = "nodes.ads"
-kind_file = "iirs.ads"
-node_file = "iirs.ads"
-template_file = "iirs.adb.in"
-meta_base_file = "nodes_meta"
-prefix_name = "Iir_Kind_"
-prefix_range_name = "Iir_Kinds_"
-type_name = "Iir_Kind"
-node_type = "Iir"
-conversions = ['uc', 'pos', 'grp']
-
-
-class FuncDesc:
- def __init__(self, name, fields, conv, acc,
- pname, ptype, rname, rtype):
- self.name = name
- self.fields = fields # List of physical fields used
- self.conv = conv
- self.acc = acc # access: Chain, Chain_Next, Ref, Of_Ref, Maybe_Ref,
- # Forward_Ref, Maybe_Forward_Ref
- self.pname = pname # Parameter mame
- self.ptype = ptype # Parameter type
- self.rname = rname # value name (for procedure)
- self.rtype = rtype # value type
-
-
-class NodeDesc:
- def __init__(self, name, format, fields, attrs):
- self.name = name
- self.format = format
- self.fields = fields # {field: FuncDesc} dict, defined for all fields
- self.attrs = attrs # A {attr: FuncDesc} dict
- self.order = [] # List of fields name, in order of appearance.
-
-
-class line:
- def __init__(self, string, no):
- self.l = string
- self.n = no
-
-
-class EndOfFile(Exception):
- def __init__(self, filename):
- self.filename = filename
-
- def __str__(self):
- return "end of file " + self.filename
-
-
-class linereader:
- def __init__(self, filename):
- self.filename = filename
- self.f = open(filename)
- self.lineno = 0
- self.l = ''
-
- def get(self):
- self.l = self.f.readline()
- if not self.l:
- raise EndOfFile(self.filename)
- self.lineno = self.lineno + 1
- return self.l
-
-
-class ParseError(Exception):
- def __init__(self, lr, msg):
- self.lr = lr
- self.msg = msg
-
- def __str__(self):
- return 'Error: ' + self.msg
- return 'Parse error at ' + self.lr.filname + ':' + self.lr.lineno + \
- ': ' + self.msg
-
-
-# Return fields description.
-# This is a dictionary. The keys represent the possible format of a node.
-# The values are dictionnaries representing fields. Keys are fields name, and
-# values are fields type.
-def read_fields(file):
- fields = {}
- formats = []
- lr = linereader(file)
-
- # Search for 'type Format_Type is'
- while lr.get() != ' type Format_Type is\n':
- pass
-
- # Skip '('
- if lr.get() != ' (\n':
- raise 'no open parenthesis after Format_Type'
-
- # Read formats
- l = lr.get()
- pat_field_name = re.compile(' Format_(\w+),?\n')
- while l != ' );\n':
- m = pat_field_name.match(l)
- if m is None:
- print l
- raise 'bad literal within Format_Type'
- name = m.group(1)
- formats.append(name)
- fields[name] = {}
- l = lr.get()
-
- # Read fields
- l = lr.get()
- pat_fields = re.compile(' -- Fields of Format_(\w+):\n')
- pat_field_desc = re.compile(' -- (\w+) : (\w+).*\n')
- format_name = ''
- common_desc = {}
-
- # Read until common fields.
- while l != ' -- Common fields are:\n':
- l = lr.get()
- format_name = 'Common'
- nbr_formats = 0
-
- while True:
- # 1) Read field description
- l = lr.get()
- desc = common_desc.copy()
- while True:
- m = pat_field_desc.match(l)
- if m is None:
- break
- desc[m.group(1)] = m.group(2)
- l = lr.get()
- # print 'For: ' + format_name + ': ' + m.group(1)
-
- # 2) Disp
- if format_name == 'Common':
- common_desc = desc
- else:
- fields[format_name] = desc
-
- # 3) Read next format
- if l == '\n':
- if nbr_formats == len(fields):
- break
- else:
- l = lr.get()
-
- # One for a format
- m = pat_fields.match(l)
- if m is not None:
- format_name = m.group(1)
- if format_name not in fields:
- raise ParseError(
- lr, 'Format ' + format_name + ' is unknown')
- nbr_formats = nbr_formats + 1
- else:
- raise ParseError(lr, 'unhandled format line')
-
- return (formats, fields)
-
-
-# Read kinds and kinds ranges.
-def read_kinds(filename):
- lr = linereader(filename)
- kinds = []
- # Search for 'type Iir_Kind is'
- while lr.get() != ' type ' + type_name + ' is\n':
- pass
- # Skip '('
- if lr.get() != ' (\n':
- raise ParseError(
- lr, 'no open parenthesis after "type ' + type_name + '"')
-
- # Read literals
- pat_node = re.compile(' ' + prefix_name + '(\w+),?( +-- .*)?\n')
- pat_comment = re.compile('( +-- .*)?\n')
- while True:
- l = lr.get()
- if l == ' );\n':
- break
- m = pat_node.match(l)
- if m:
- kinds.append(m.group(1))
- continue
- m = pat_comment.match(l)
- if not m:
- raise ParseError(lr, 'Unknown line within kind declaration')
-
- # Check subtypes
- pat_subtype = re.compile(' subtype ' + r'(\w+) is '
- + type_name + ' range\n')
- pat_first = re.compile(' ' + prefix_name + r'(\w+) ..\n')
- pat_last = re.compile(' ' + prefix_name + r'(\w+);\n')
- pat_middle = re.compile(' --' + prefix_name + r'(\w+)\n')
- kinds_ranges = {}
- while True:
- l = lr.get()
- # Start of methods is also end of subtypes.
- if l == ' -- General methods.\n':
- break
- # Found a subtype.
- m = pat_subtype.match(l)
- if m:
- # Check first bound
- name = m.group(1)
- if not name.startswith(prefix_range_name):
- raise ParseError(lr, 'incorrect prefix for subtype')
- name = name[len(prefix_range_name):]
- l = lr.get()
- mf = pat_first.match(l)
- if not mf:
- raise ParseError(lr, 'badly formated first bound of subtype')
- first = kinds.index(mf.group(1))
- idx = first
- has_middle = None
- # Read until last bound
- while True:
- l = lr.get()
- ml = pat_middle.match(l)
- if ml:
- # Check element in the middle
- n = ml.group(1)
- if n not in kinds:
- raise ParseError(
- lr, "unknown kind " + n + " in subtype")
- if kinds.index(n) != idx + 1:
- raise ParseError(
- lr, "missing " + kinds[idx + 1] + " in subtype")
- has_middle = True
- idx = idx + 1
- else:
- # Check last bound
- ml = pat_last.match(l)
- if ml:
- last = kinds.index(ml.group(1))
- if last != idx + 1 and has_middle:
- raise ParseError(
- lr, "missing " + kinds[idx] + " in subtype")
- break
- raise ParseError(lr, "unhandled line in subtype")
- kinds_ranges[name] = kinds[first:last+1]
- return (kinds, kinds_ranges)
-
-# Read functions
-def read_methods(filename):
- lr = linereader(filename)
- funcs = []
- pat_field = re.compile(r' -- Field: ([\w,]+)( \w+)?( \(\w+\))?\n')
- pat_conv = re.compile(r'^ \((\w+)\)$')
- pat_func = re.compile(
- r' function Get_(\w+) \((\w+) : (\w+)\) return (\w+);\n')
- pat_proc = re.compile(
- r' procedure Set_(\w+) \((\w+) : (\w+); (\w+) : (\w+)\);\n')
- pat_end = re.compile('end [A-Za-z.]+;\n')
- while True:
- l = lr.get()
- # Start of methods
- if l == ' -- General methods.\n':
- break
- while True:
- l = lr.get()
- if pat_end.match(l):
- break
- m = pat_field.match(l)
- if m:
- fields = m.group(1).split(',')
- # Extract access modifier
- acc = m.group(2)
- if acc:
- acc = acc.strip()
- # Extract conversion
- conv = m.group(3)
- if conv:
- mc = pat_conv.match(conv)
- if not mc:
- raise ParseError(lr, 'conversion ill formed')
- conv = mc.group(1)
- if conv not in conversions:
- raise ParseError(lr, 'unknown conversion ' + conv)
- else:
- conv = None
- if len(fields) > 1 and conv != 'grp':
- raise ParseError(lr, 'bad conversion for multiple fields')
- # Read function
- l = lr.get()
- mf = pat_func.match(l)
- if not mf:
- raise ParseError(
- lr, 'function declaration expected after Field')
- # Read procedure
- l = lr.get()
- mp = pat_proc.match(l)
- if not mp:
- raise ParseError(
- lr, 'procedure declaration expected after function')
- # Consistency check between function and procedure
- if mf.group(1) != mp.group(1):
- raise ParseError(lr, 'function and procedure name mismatch')
- if mf.group(2) != mp.group(2):
- raise ParseError(lr, 'parameter name mismatch with function')
- if mf.group(3) != mp.group(3):
- raise ParseError(lr, 'parameter type mismatch with function')
- if mf.group(4) != mp.group(5):
- raise ParseError(lr, 'result type mismatch with function')
- funcs.append(FuncDesc(mf.group(1), fields, conv, acc,
- mp.group(2), mp.group(3),
- mp.group(4), mp.group(5)))
-
- return funcs
-
-
-# Read description for one node
-# LR is the line reader. NAMES is the list of (node name, format)
-# (one description may describe several nodes).
-def read_nodes_fields(lr, names, fields, nodes, funcs_dict):
- pat_only = re.compile(' -- Only for ' + prefix_name + '(\w+):\n')
- pat_only_bad = re.compile (' -- *Only for.*\n')
- pat_field = re.compile(' -- Get/Set_(\w+) \((Alias )?([\w,]+)\)\n')
- pat_comment = re.compile(' --.*\n')
- pat_start = re.compile(' -- \w.*\n')
-
- # Create nodes
- cur_nodes = []
- for (nm, fmt) in names:
- if fmt not in fields:
- raise ParseError(lr, 'unknown format "{}"'.format(fmt))
- n = NodeDesc(nm, fmt, {x: None for x in fields[fmt]}, {})
- nodes[nm] = n
- cur_nodes.append(n)
-
- # Look for fields
- only_nodes = cur_nodes
- l = lr.l
- while l != '\n':
- # Handle 'Only ...'
- while True:
- m = pat_only.match(l)
- if not m:
- break
- name = m.group(1)
- if name not in [x.name for x in cur_nodes]:
- raise ParseError(lr, 'node not currently described')
- if only_nodes == cur_nodes:
- only_nodes = []
- only_nodes.append(nodes[name])
- l = lr.get()
- # Handle field: '-- Get/Set_FUNC (Alias? FIELD)'
- m = pat_field.match(l)
- if m:
- # 1) Check the function exists
- func = m.group(1)
- alias = m.group(2)
- fields = m.group(3).split(',')
- if func not in funcs_dict:
- raise ParseError(lr, 'unknown function')
- func = funcs_dict[func]
- if func.fields != fields:
- raise ParseError(lr, 'fields mismatch')
- for c in only_nodes:
- for f in fields:
- if f not in c.fields:
- raise ParseError(
- lr, 'field ' + f + ' does not exist in node')
- if not alias:
- for f in fields:
- if c.fields[f]:
- raise ParseError(
- lr, 'field ' + f + ' already used')
- c.fields[f] = func
- c.order.append(f)
- c.attrs[func.name] = func
- only_nodes = cur_nodes
- elif pat_start.match(l):
- raise ParseError(lr, 'bad line in node description')
- elif pat_only_bad.match(l):
- raise ParseError(lr, "misleading 'Only for' comment")
- elif not pat_comment.match(l):
- raise ParseError(lr, 'bad line in node description')
- l = lr.get()
-
-
-def read_nodes(filename, kinds, kinds_ranges, fields, funcs):
- """Read description for all nodes."""
- lr = linereader(filename)
- funcs_dict = {x.name: x for x in funcs}
- nodes = {}
-
- # Skip until start
- while lr.get() != ' -- Start of ' + type_name + '.\n':
- pass
-
- pat_decl = re.compile(' -- ' + prefix_name + '(\w+) \((\w+)\)\n')
- pat_decls = re.compile(' -- ' + prefix_range_name + '(\w+) \((\w+)\)\n')
- pat_comment_line = re.compile(' --+\n')
- pat_comment_box = re.compile(' --( .*)?\n')
- while True:
- l = lr.get()
- if l == ' -- End of ' + type_name + '.\n':
- break
- if l == '\n':
- continue
- m = pat_decl.match(l)
- if m:
- # List of nodes being described by the current description.
- names = []
-
- # Declaration of the first node
- while True:
- name = m.group(1)
- if name not in kinds:
- raise ParseError(lr, 'unknown node')
- fmt = m.group(2)
- names.append((name, fmt))
- if name in nodes:
- raise ParseError(
- lr, 'node {} already described'.format(name));
- # There might be several nodes described at once.
- l = lr.get()
- m = pat_decl.match(l)
- if not m:
- break
- read_nodes_fields(lr, names, fields, nodes, funcs_dict)
- continue
- m = pat_decls.match(l)
- if m:
- # List of nodes being described by the current description.
- name = m.group(1)
- fmt = m.group(2)
- names = [(k, fmt) for k in kinds_ranges[name]]
- l = lr.get()
- read_nodes_fields(lr, names, fields, nodes, funcs_dict)
- continue
- if pat_comment_line.match(l) or pat_comment_box.match(l):
- continue
- raise ParseError(lr, 'bad line in node description')
-
- for k in kinds:
- if k not in nodes:
- raise ParseError(lr, 'no desription for "{}"'.format(k))
- return nodes
-
-
-def gen_choices(choices):
- """Generate a choice 'when A | B ... Z =>' using elements of CHOICES."""
- is_first = True
- for c in choices:
- if is_first:
- print ' ',
- print 'when',
- else:
- print
- print ' ',
- print ' |',
- print prefix_name + c,
- is_first = False
- print '=>'
-
-
-def gen_get_format(formats, nodes, kinds):
- """Generate the Get_Format function."""
- print ' function Get_Format (Kind : ' + type_name + ') ' + \
- 'return Format_Type is'
- print ' begin'
- print ' case Kind is'
- for f in formats:
- choices = [k for k in kinds if nodes[k].format == f]
- gen_choices(choices)
- print ' return Format_' + f + ';'
- print ' end case;'
- print ' end Get_Format;'
-
-
-def gen_subprg_header(decl):
- if len(decl) < 76:
- print decl + ' is'
- else:
- print decl
- print ' is'
- print ' begin'
-
-
-def gen_assert(func):
- print ' pragma Assert (' + func.pname + ' /= Null_' + node_type + ');'
- cond = '(Has_' + func.name + ' (Get_Kind (' + func.pname + ')),'
- msg = '"no field ' + func.name + '");'
- if len(cond) < 60:
- print ' pragma Assert ' + cond
- print ' ' + msg
- else:
- print ' pragma Assert'
- print ' ' + cond
- print ' ' + msg
-
-
-def get_field_type(fields, f):
- for fld in fields.values():
- if f in fld:
- return fld[f]
- return None
-
-
-def gen_get_set(func, nodes, fields):
- """Generate Get_XXX/Set_XXX subprograms for FUNC."""
- rtype = func.rtype
- # If the function needs several fields, it must be user defined
- if func.conv == 'grp':
- print ' type %s_Conv is record' % rtype
- for f in func.fields:
- print ' %s: %s;' % (f, get_field_type(fields, f))
- print ' end record;'
- print ' pragma Pack (%s_Conv);' % rtype
- print " pragma Assert (%s_Conv'Size = %s'Size);" % (rtype, rtype)
- print
- else:
- f = func.fields[0]
- g = 'Get_' + f + ' (' + func.pname + ')'
-
- s = func.rname
- if func.conv:
- if func.conv == 'uc':
- field_type = get_field_type(fields, f)
- g = field_type + '_To_' + rtype + ' (' + g + ')'
- s = rtype + '_To_' + field_type + ' (' + s + ')'
- elif func.conv == 'pos':
- g = rtype + "'Val (" + g + ')'
- s = rtype + "'Pos (" + s + ')'
-
- subprg = ' function Get_' + func.name + ' (' + func.pname \
- + ' : ' + func.ptype + ') return ' + rtype
- if func.conv == 'grp':
- print subprg
- print ' is'
- print ' function To_%s is new Ada.Unchecked_Conversion' % \
- func.rtype
- print ' (%s_Conv, %s);' % (rtype, rtype)
- print ' Conv : %s_Conv;' % rtype
- print ' begin'
- else:
- gen_subprg_header(subprg)
- gen_assert(func)
- if func.conv == 'grp':
- for f in func.fields:
- print ' Conv.%s := Get_%s (%s);' % (f, f, func.pname)
- g = 'To_%s (Conv)' % rtype
- print ' return ' + g + ';'
- print ' end Get_' + func.name + ';'
- print
-
- subprg = ' procedure Set_' + func.name + ' (' \
- + func.pname + ' : ' + func.ptype + '; ' \
- + func.rname + ' : ' + func.rtype + ')'
- if func.conv == 'grp':
- print subprg
- print ' is'
- print ' function To_%s_Conv is new Ada.Unchecked_Conversion' % \
- func.rtype
- print ' (%s, %s_Conv);' % (rtype, rtype)
- print ' Conv : %s_Conv;' % rtype
- print ' begin'
- else:
- gen_subprg_header(subprg)
- gen_assert(func)
- if func.conv == 'grp':
- print ' Conv := To_%s_Conv (%s);' % (rtype, func.rname)
- for f in func.fields:
- print ' Set_%s (%s, Conv.%s);' % (f, func.pname, f)
- else:
- print ' Set_' + f + ' (' + func.pname + ', ' + s + ');'
- print ' end Set_' + func.name + ';'
- print
-
-
-def funcs_of_node(n):
- return sorted([fv.name for fv in n.fields.values() if fv])
-
-
-def gen_has_func_spec(name, suff):
- spec = ' function Has_' + name + ' (K : ' + type_name + ')'
- ret = ' return Boolean' + suff
- if len(spec) < 60:
- print spec + ret
- else:
- print spec
- print ' ' + ret
-
-
-def do_disp_formats():
- for fmt in fields:
- print "Fields of Format_"+fmt
- fld = fields[fmt]
- for k in fld:
- print ' ' + k + ' (' + fld[k] + ')'
-
-
-def do_disp_kinds():
- print "Kinds are:"
- for k in kinds:
- print ' ' + prefix_name + k
-
-
-def do_disp_funcs():
- print "Functions are:"
- for f in funcs:
- s = '{0} ({1}: {2}'.format(f.name, f.field, f.rtype)
- if f.acc:
- s += ' acc:' + f.acc
- if f.conv:
- s += ' conv:' + f.conv
- s += ')'
- print s
-
-
-def do_disp_types():
- print "Types are:"
- s = set([])
- for f in funcs:
- s |= set([f.rtype])
- for t in sorted(s):
- print ' ' + t
-
-
-def do_disp_nodes():
- for k in kinds:
- v = nodes[k]
- print prefix_name + k + ' (' + v.format + ')'
- flds = [fk for fk, fv in v.fields.items() if fv]
- for fk in sorted(flds):
- print ' ' + fk + ': ' + v.fields[fk].name
-
-
-def do_get_format():
- gen_get_format(formats, nodes)
-
-
-def do_body():
- lr = linereader(template_file)
- while True:
- l = lr.get().rstrip()
- print l
- if l == ' -- Subprograms':
- gen_get_format(formats, nodes, kinds)
- print
- for f in funcs:
- gen_get_set(f, nodes, fields)
- if l[0:3] == 'end':
- break
-
-
-def get_types():
- s = set([])
- for f in funcs:
- s |= set([f.rtype])
- return [t for t in sorted(s)]
-
-
-def get_attributes():
- s = set([])
- for f in funcs:
- if f.acc:
- s |= set([f.acc])
- res = [t for t in sorted(s)]
- res.insert(0, 'None')
- return res
-
-
-def gen_enum(prefix, vals):
- last = None
- for v in vals:
- if last:
- print last + ','
- last = prefix + v
- print last
-
-
-def do_meta_specs():
- lr = linereader(meta_base_file + '.ads.in')
- types = get_types()
- while True:
- l = lr.get().rstrip()
- if l == ' -- TYPES':
- gen_enum(' Type_', types)
- elif l == ' -- FIELDS':
- gen_enum(' Field_', [f.name for f in funcs])
- elif l == ' -- ATTRS':
- gen_enum(' Attr_', get_attributes())
- elif l == ' -- FUNCS':
- for t in types:
- print ' function Get_' + t
- print ' (N : ' + node_type + '; F : Fields_Enum) return '\
- + t + ';'
- print ' procedure Set_' + t
- print ' (N : ' + node_type + '; F : Fields_Enum; V: ' \
- + t + ');'
- print
- for f in funcs:
- gen_has_func_spec(f.name, ';')
- elif l[0:3] == 'end':
- print l
- break
- else:
- print l
-
-
-def do_meta_body():
- lr = linereader(meta_base_file + '.adb.in')
- while True:
- l = lr.get().rstrip()
- if l == ' -- FIELDS_TYPE':
- last = None
- for f in funcs:
- if last:
- print last + ','
- last = ' Field_' + f.name + ' => Type_' + f.rtype
- print last
- elif l == ' -- FIELD_IMAGE':
- for f in funcs:
- print ' when Field_' + f.name + ' =>'
- print ' return "' + f.name.lower() + '";'
- elif l == ' -- IIR_IMAGE':
- for k in kinds:
- print ' when ' + prefix_name + k + ' =>'
- print ' return "' + k.lower() + '";'
- elif l == ' -- FIELD_ATTRIBUTE':
- for f in funcs:
- print ' when Field_' + f.name + ' =>'
- if f.acc:
- attr = f.acc
- else:
- attr = 'None'
- print ' return Attr_' + attr + ';'
- elif l == ' -- FIELDS_ARRAY':
- last = None
- nodes_types = [node_type,
- node_type + '_List', node_type + '_Flist']
- for k in kinds:
- v = nodes[k]
- if last:
- print last + ','
- last = None
- print ' -- ' + prefix_name + k
- # Get list of physical fields for V, in some order.
- if flag_keep_order:
- flds = v.order
- else:
- # First non Iir and no Iir_List.
- flds = sorted([fk for fk, fv in v.fields.items()
- if fv and fv.rtype not in nodes_types])
- # Then Iir and Iir_List in order of appearance
- flds += (fv for fv in v.order
- if v.fields[fv].rtype in nodes_types)
- # Print the corresponding node field, but remove duplicate due
- # to 'grp'.
- fldsn = []
- for fk in flds:
- if last:
- print last + ','
- # Remove duplicate
- fn = v.fields[fk].name
- if fn not in fldsn:
- last = ' Field_' + fn
- fldsn.append(fn)
- else:
- last = None
- if last:
- print last
- elif l == ' -- FIELDS_ARRAY_POS':
- pos = -1
- last = None
- for k in kinds:
- v = nodes[k]
- # Create a set to remove duplicate for 'grp'.
- flds = set([fv.name for fk, fv in v.fields.items() if fv])
- pos += len(flds)
- if last:
- print last + ','
- last = ' ' + prefix_name + k + ' => {}'.format(pos)
- print last
- elif l == ' -- FUNCS_BODY':
- # Build list of types
- s = set([])
- for f in funcs:
- s |= set([f.rtype])
- types = [t for t in sorted(s)]
- for t in types:
- print ' function Get_' + t
- print ' (N : ' + node_type + '; F : Fields_Enum) return '\
- + t + ' is'
- print ' begin'
- print ' pragma Assert (Fields_Type (F) = Type_' + t + ');'
- print ' case F is'
- for f in funcs:
- if f.rtype == t:
- print ' when Field_' + f.name + ' =>'
- print ' return Get_' + f.name + ' (N);'
- print ' when others =>'
- print ' raise Internal_Error;'
- print ' end case;'
- print ' end Get_' + t + ';'
- print
- print ' procedure Set_' + t
- print ' (N : ' + node_type + '; F : Fields_Enum; V: ' \
- + t + ') is'
- print ' begin'
- print ' pragma Assert (Fields_Type (F) = Type_' + t + ');'
- print ' case F is'
- for f in funcs:
- if f.rtype == t:
- print ' when Field_' + f.name + ' =>'
- print ' Set_' + f.name + ' (N, V);'
- print ' when others =>'
- print ' raise Internal_Error;'
- print ' end case;'
- print ' end Set_' + t + ';'
- print
- for f in funcs:
- gen_has_func_spec(f.name, ' is')
- choices = [k for k in kinds if f.name in nodes[k].attrs]
- if len(choices) == 0:
- print ' pragma Unreferenced (K);'
- print ' begin'
- if len(choices) == 0:
- print ' return False;'
- elif len(choices) == 1:
- print ' return K = ' + prefix_name + choices[0] + ';'
- else:
- print ' case K is'
- gen_choices(choices)
- print ' return True;'
- print ' when others =>'
- print ' return False;'
- print ' end case;'
- print ' end Has_' + f.name + ';'
- print
- elif l[0:3] == 'end':
- print l
- break
- else:
- print l
-
-
-actions = {'disp-nodes': do_disp_nodes,
- 'disp-kinds': do_disp_kinds,
- 'disp-formats': do_disp_formats,
- 'disp-funcs': do_disp_funcs,
- 'disp-types': do_disp_types,
- 'get_format': do_get_format,
- 'body': do_body,
- 'meta_specs': do_meta_specs,
- 'meta_body': do_meta_body}
-
-
-def main():
- parser = argparse.ArgumentParser(description='Meta-grammar processor')
- parser.add_argument('action', choices=actions.keys(),
- default='disp-nodes')
- parser.add_argument('--field-file', dest='field_file',
- default='nodes.ads',
- help='specify file which defines fields')
- parser.add_argument('--kind-file', dest='kind_file',
- default='iirs.ads',
- help='specify file which defines nodes kind')
- parser.add_argument('--node-file', dest='node_file',
- default='iirs.ads',
- help='specify file which defines nodes and methods')
- parser.add_argument('--template-file', dest='template_file',
- default='iirs.adb.in',
- help='specify template body file')
- parser.add_argument('--meta-basename', dest='meta_basename',
- default='nodes_meta',
- help='specify base name of meta files')
- parser.add_argument('--kind-type', dest='kind_type',
- default='Iir_Kind',
- help='name of kind type')
- parser.add_argument('--kind-prefix', dest='kind_prefix',
- default='Iir_Kind_',
- help='prefix for kind literals')
- parser.add_argument('--kind-range-prefix', dest='kind_range_prefix',
- default='Iir_Kinds_',
- help='prefix for kind subtype (range)')
- parser.add_argument('--node-type', dest='node_type',
- default='Iir',
- help='name of the node type')
- parser.add_argument('--keep-order', dest='flag_keep_order',
- action='store_true',
- help='keep field order of nodes')
- parser.set_defaults(flag_keep_order=False)
- args = parser.parse_args()
-
- # At some point, it would be simpler to create a class...
- global formats, fields, nodes, kinds, kinds_ranges, funcs
-
- global type_name, prefix_name, template_file, node_type, meta_base_file
- global prefix_range_name, flag_keep_order, kind_file
-
- type_name = args.kind_type
- prefix_name = args.kind_prefix
- prefix_range_name = args.kind_range_prefix
- template_file = args.template_file
- node_type = args.node_type
- meta_base_file = args.meta_basename
- flag_keep_order = args.flag_keep_order
-
- field_file = args.field_file
- kind_file = args.kind_file
- node_file = args.node_file
-
- try:
- (formats, fields) = read_fields(field_file)
- (kinds, kinds_ranges) = read_kinds(kind_file)
- funcs = read_methods(node_file)
- nodes = read_nodes(node_file, kinds, kinds_ranges, fields, funcs)
-
- except ParseError as e:
- print >> sys.stderr, e
- print >> sys.stderr, \
- "in {0}:{1}:{2}".format(e.lr.filename, e.lr.lineno, e.lr.l)
- sys.exit(1)
-
- f = actions.get(args.action, None)
- if not f:
- print >> sys.stderr, "Action {0} is unknown".format(args.action)
- sys.exit(1)
- f()
-
-
-if __name__ == '__main__':
- main()