Skip to content

Commit 0b256f4

Browse files
committed
wip
1 parent c0a2e6e commit 0b256f4

File tree

2 files changed

+156
-35
lines changed

2 files changed

+156
-35
lines changed

open_fortran_parser/ast_transformer.py

Lines changed: 90 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -365,19 +365,11 @@ def _if(self, node: ET.Element):
365365

366366
def _statement(self, node: ET.Element):
367367
details = self.transform_all_subnodes(
368-
node, ignored={
368+
node, warn=False, ignored={
369+
'format',
369370
'action-stmt', 'executable-construct', 'execution-part-construct',
370371
'execution-part'})
371372
flatten_sequence(details)
372-
if len(details) == 0:
373-
args = [
374-
typed_ast3.Str(s=ET.tostring(node).decode().rstrip()),
375-
typed_ast3.Num(n=len(node))]
376-
return [
377-
typed_ast3.Expr(value=typed_ast3.Call(
378-
func=typed_ast3.Name(id='print', ctx=typed_ast3.Load()),
379-
args=args, keywords=[])),
380-
typed_ast3.Pass()]
381373
return [
382374
detail if isinstance(detail, (typed_ast3.Expr, typed_ast3.Assign, typed_ast3.AnnAssign))
383375
else typed_ast3.Expr(value=detail)
@@ -435,14 +427,10 @@ def _write(self, node) -> t.Union[typed_ast3.Expr, typed_ast3.Assign]:
435427
written = []
436428
io_controls_node = node.find('./io-controls')
437429
if io_controls_node is not None:
438-
args = self.transform_all_subnodes(
439-
io_controls_node, skip_empty=True,
440-
ignored={'io-control-spec-list__begin', 'io-control-spec-list'})
430+
args = self.transform(io_controls_node, warn=False)
441431
outputs_node = node.find('./outputs')
442432
if outputs_node is not None:
443-
written = self.transform_all_subnodes(
444-
outputs_node, skip_empty=True,
445-
ignored={'output-item-list__begin', 'output-item', 'output-item-list'})
433+
written = self.transform(outputs_node, warn=False)
446434
if len(written) > 1 or len(args) > 1:
447435
# file
448436
pass
@@ -454,35 +442,101 @@ def _write(self, node) -> t.Union[typed_ast3.Expr, typed_ast3.Assign]:
454442
func=typed_ast3.Name(id='write', ctx=typed_ast3.Load()),
455443
args=args, keywords=[]))
456444

445+
def _read(self, node: ET.Element):
446+
io_controls = self.transform(node.find('./io-controls'), warn=False)
447+
inputs = self.transform(node.find('./inputs'), warn=False)
448+
raise NotImplementedError()
449+
450+
def _print(self, node):
451+
outputs_node = node.find('./outputs')
452+
args = []
453+
if outputs_node is not None:
454+
args = self.transform(outputs_node, warn=False)
455+
return typed_ast3.Expr(value=typed_ast3.Call(
456+
func=typed_ast3.Name(id='print', ctx=typed_ast3.Load()),
457+
args=args, keywords=[]))
458+
459+
def _io_controls(self, node: ET.Element):
460+
return self.transform_all_subnodes(
461+
node, warn=False, skip_empty=True,
462+
ignored={'io-control-spec-list__begin', 'io-control-spec-list'})
463+
457464
def _io_control(self, node) -> typed_ast3.AST:
458465
io_control = self.transform_all_subnodes(node)
459466
if len(node) == 0 and not node.attrib['argument-name']:
460467
return [] # TODO: TMP
461468
if len(io_control) != 1:
462-
_LOG.warning('%s', ET.tostring(node).decode().rstrip())
463-
raise NotImplementedError()
469+
raise NotImplementedError('exactly one I/O control expected but {} found in:/n{}'.format(
470+
len(io_control), ET.tostring(node).decode().rstrip()))
464471
if node.attrib['argument-name']:
465472
return typed_ast3.keyword(arg=node.attrib['argument-name'], value=io_control[0])
466473
return io_control[0]
467474

468-
def _print(self, node):
469-
outputs_node = node.find('./outputs')
470-
args = []
471-
if outputs_node is not None:
472-
args = self.transform_all_subnodes(
473-
outputs_node, skip_empty=True,
474-
ignored={'output-item-list__begin', 'output-item', 'output-item-list'})
475-
return typed_ast3.Expr(value=typed_ast3.Call(
476-
func=typed_ast3.Name(id='print', ctx=typed_ast3.Load()),
477-
args=args, keywords=[]))
475+
def _outputs(self, node: ET.Element):
476+
return self.transform_all_subnodes(
477+
node, warn=False, skip_empty=True,
478+
ignored={'output-item-list__begin', 'output-item', 'output-item-list'})
478479

479480
def _output(self, node):
480481
output = self.transform_all_subnodes(node)
481482
if len(output) != 1:
482-
_LOG.warning('%s', ET.tostring(node).decode().rstrip())
483-
raise NotImplementedError()
483+
raise NotImplementedError('exactly one output expected but {} found in:/n{}'.format(
484+
len(output), ET.tostring(node).decode().rstrip()))
484485
return output[0]
485486

487+
def _inputs(self, node: ET.Element):
488+
return self.transform_all_subnodes(
489+
node, warn=False, skip_empty=True,
490+
ignored={'input-item-list__begin', 'input-item', 'input-item-list'})
491+
492+
def _input(self, node):
493+
input_ = self.transform_all_subnodes(node)
494+
if len(input_) != 1:
495+
raise NotImplementedError('exactly one input expected but {} found in:/n{}'.format(
496+
len(input_), ET.tostring(node).decode().rstrip()))
497+
return input_[0]
498+
499+
def _open(self, node: ET.Element) -> typed_ast3.AnnAssign:
500+
file_handle = typed_ast3.Subscript(
501+
value=typed_ast3.Attribute(value=typed_ast3.Name(id='Fortran', ctx=typed_ast3.Load()),
502+
attr='file_handles', ctx=typed_ast3.Load()),
503+
slice=typed_ast3.Index(value=None), ctx=typed_ast3.Load())
504+
505+
kwargs = self.transform(node.find('./keyword-arguments'), warn=False)
506+
file_handle.slice.value = kwargs.pop(0)
507+
self._ensure_top_level_import('typing', 't')
508+
return typed_ast3.AnnAssign(
509+
target=file_handle, value=typed_ast3.Call(
510+
func=typed_ast3.Name(id='open', ctx=typed_ast3.Load()),
511+
args=[], keywords=kwargs),
512+
annotation=typed_ast3.parse('t.IO[bytes]', mode='eval'), simple=1)
513+
514+
def _close(self, node: ET.Element) -> typed_ast3.AnnAssign:
515+
file_handle = typed_ast3.Subscript(
516+
value=typed_ast3.Attribute(value=typed_ast3.Name(id='Fortran', ctx=typed_ast3.Load()),
517+
attr='file_handles', ctx=typed_ast3.Load()),
518+
slice=typed_ast3.Index(value=None), ctx=typed_ast3.Load())
519+
520+
kwargs = self.transform(node.find('./keyword-arguments'), warn=False)
521+
file_handle.slice.value = kwargs.pop(0)
522+
self._ensure_top_level_import('typing', 't')
523+
return typed_ast3.Call(
524+
func=typed_ast3.Attribute(value=file_handle, attr='close', ctx=typed_ast3.Load()),
525+
args=[], keywords=kwargs)
526+
527+
def _keyword_arguments(self, node: ET.Element):
528+
kwargs = self.transform_all_subnodes(
529+
node, warn=False, skip_empty=True, ignored={
530+
'connect-spec-list__begin', 'equiv-op', 'connect-spec-list',
531+
'close-spec-list__begin', 'close-spec-list'})
532+
return kwargs
533+
534+
def _keyword_argument(self, node: ET.Element):
535+
name = node.attrib['argument-name']
536+
value = self.transform_all_subnodes(node, warn=False, skip_empty=True, ignored={})
537+
assert len(value) == 1, value
538+
return typed_ast3.keyword(arg=name, value=value[0])
539+
486540
def _transform_mpi_call(
487541
self, tree: typed_ast3.Call) -> t.Union[typed_ast3.Call, typed_ast3.Assign]:
488542
assert isinstance(tree, typed_ast3.Call)
@@ -494,7 +548,7 @@ def _transform_mpi_call(
494548
# extract last arg -- it's error var
495549
error_var = tree.args.pop(-1)
496550
assert isinstance(error_var, typed_ast3.Name), (type(error_var), error_var)
497-
if mpi_function_name in ['Comm_size', 'Comm_rank', 'Barrier']:
551+
if mpi_function_name in ('Comm_size', 'Comm_rank', 'Barrier'):
498552
# extract 1st arg - in some cases it's the MPI scope
499553
mpi_comm = tree.args.pop(0)
500554
assert isinstance(mpi_comm, typed_ast3.Name)
@@ -504,9 +558,12 @@ def _transform_mpi_call(
504558
value=core_name, attr=mpi_comm.id[4:], ctx=typed_ast3.Load())
505559
tree.func = typed_ast3.Attribute(
506560
value=core_name, attr=mpi_function_name, ctx=typed_ast3.Load())
507-
# create assignment of call result to its current 1st var
561+
# create assignment of call result to its current 1st var (or 2nd var in some cases)
508562
if tree.args:
509-
var = tree.args.pop(0)
563+
arg_num = 0
564+
if mpi_function_name in ('Allreduce',):
565+
arg_num = 1
566+
var = tree.args.pop(arg_num)
510567
tree = typed_ast3.Assign(targets=[var], value=tree, type_comment=None)
511568
return [tree, typed_ast3.AnnAssign(
512569
target=error_var, value=None, annotation=typed_ast3.Str(s='MPI error code'), simple=1)]

src/fortran/ofp/XMLPrinter.java

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,6 +1622,13 @@ public void forall_triplet_spec_list(int count) {
16221622
contextClose("index-variables");
16231623
}
16241624

1625+
public void forall_assignment_stmt(boolean isPointerAssignment) {
1626+
context = contextNode(-1); // temporarily reopen previously-closed context
1627+
if (verbosity >= 100)
1628+
super.forall_assignment_stmt(isPointerAssignment);
1629+
contextClose(); // re-close previously closed context
1630+
}
1631+
16251632
public void forall_stmt__begin() {
16261633
contextRename("statement", "loop");
16271634
setAttribute("type", "forall");
@@ -1920,11 +1927,22 @@ public void continue_stmt(Token label, Token continueKeyword, Token eos) {
19201927
super.continue_stmt(label, continueKeyword, eos);
19211928
}
19221929

1930+
public void open_stmt(Token label, Token openKeyword, Token eos) {
1931+
Element outerContext = context;
1932+
Element args = contextNode(-1);
1933+
contextOpen("open");
1934+
outerContext.removeChild(args);
1935+
context.appendChild(args);
1936+
super.open_stmt(label, openKeyword, eos);
1937+
contextClose();
1938+
}
1939+
19231940
public void connect_spec(Token id) {
19241941
contextCloseAllInner("keyword-argument");
19251942
setAttribute("argument-name", id);
19261943
contextClose("keyword-argument");
1927-
super.connect_spec(id);
1944+
if (verbosity >= 100)
1945+
super.connect_spec(id);
19281946
contextOpen("keyword-argument");
19291947
}
19301948

@@ -1944,9 +1962,55 @@ public void connect_spec_list(int count) {
19441962
contextClose("keyword-arguments");
19451963
}
19461964

1965+
public void close_stmt(Token label, Token closeKeyword, Token eos) {
1966+
Element outerContext = context;
1967+
Element args = contextNode(-1);
1968+
contextOpen("close");
1969+
outerContext.removeChild(args);
1970+
context.appendChild(args);
1971+
super.close_stmt(label, closeKeyword, eos);
1972+
contextClose();
1973+
}
1974+
1975+
public void close_spec(Token closeSpec) {
1976+
contextCloseAllInner("keyword-argument");
1977+
setAttribute("argument-name", closeSpec);
1978+
contextClose("keyword-argument");
1979+
if (verbosity >= 100)
1980+
super.close_spec(closeSpec);
1981+
contextOpen("keyword-argument");
1982+
}
1983+
1984+
public void close_spec_list__begin() {
1985+
contextOpen("keyword-arguments");
1986+
if (verbosity >= 100)
1987+
super.close_spec_list__begin();
1988+
contextOpen("keyword-argument");
1989+
}
1990+
1991+
public void close_spec_list(int count) {
1992+
contextClose("keyword-argument");
1993+
contextCloseAllInner("keyword-arguments");
1994+
if (verbosity >= 100)
1995+
super.close_spec_list(count);
1996+
setAttribute("count", count);
1997+
contextClose("keyword-arguments");
1998+
}
1999+
19472000
public void read_stmt(Token label, Token readKeyword, Token eos, boolean hasInputItemList) {
1948-
// TODO Auto-generated method stub
2001+
Element outerContext = context;
2002+
contextOpen("read");
2003+
Element value = null;
2004+
if (hasInputItemList) {
2005+
value = contextNode(outerContext, -3);
2006+
outerContext.removeChild(value);
2007+
context.appendChild(value);
2008+
}
2009+
value = contextNode(outerContext, -2);
2010+
outerContext.removeChild(value);
2011+
context.appendChild(value);
19492012
super.read_stmt(label, readKeyword, eos, hasInputItemList);
2013+
contextClose();
19502014
}
19512015

19522016
public void write_stmt(Token label, Token writeKeyword, Token eos, boolean hasOutputItemList) {

0 commit comments

Comments
 (0)