@@ -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 )]
0 commit comments