Class: Fort::Src::Code

Inherits:
String
  • Object
show all
Extended by:
RubyPatch::AutoLoad
Defined in:
lib/fort/src/code.rb,
lib/fort/src/code/program_unit.rb,
lib/fort/src/code/depended_module.rb

Overview

Add Fortran source code specific utilities for String.

Defined Under Namespace

Classes: DependedModule, ProgramUnit

Constant Summary collapse

STRING_OR_COMMENT_REG =

$1: quote, $2: string, $3: comment. We don’t need $2 and $3.

/[^"'!]*(?:(["'])(.*?)\1|(!.*?)(?:\n|\z))/mi
CONTINUATION_AMPERSAND_REG =
/& *\n+ *&?/
ONE_LINER_REG =
/;/
START_SECTION_REG =

$1: “program” or “module”. $2: program or module name.

/\A(program|module) +([A-Za-z]\w*)\z/i
END_SECTION_REG =
/\Aend +(program|module) +([A-Za-z]\w*)\z/i
USE_REG =

$1: “non_intrinsic” or “intrinsic” or nil. $2: module name.

/\Ause(?:(?: *, *((?:non_)?intrinsic) *:: *)|(?: *::)? +)([A-Za-z]\w*)/i
ParseError =
Class.new(StandardError)

Instance Method Summary collapse

Instance Method Details

#clean_codeArray

Returns Lines without empty lines.

Returns:

  • (Array)

    Lines without empty lines.



66
67
68
69
70
71
72
73
74
# File 'lib/fort/src/code.rb', line 66

def clean_code
  @clean_code ||= without_comments_and_strings\
    .without_continuation_ampersand\
    .without_one_line_semicolon\
    .split("\n")\
    .map(&:strip)\
    .delete_if(&:empty?)\
    .map(&:downcase)
end

#contentsObject



61
62
63
# File 'lib/fort/src/code.rb', line 61

def contents
  @contents ||= parse
end

#parseArray<ProgramUnit>

Returns:



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/fort/src/code.rb', line 27

def parse
  mode = nil
  name = nil
  program_unit = nil
  program_unit_list = []
  clean_code.each do |line|
    case line
    when START_SECTION_REG
      raise ParseError unless mode.nil? && name.nil?

      mode = low_sym($1)
      name = low_sym($2)
      program_unit = ProgramUnit.new(name, mode)
      next
    when END_SECTION_REG
      raise ParseError unless low_sym($1) == mode && low_sym($2) == name

      mode = nil
      name = nil
      program_unit_list << program_unit
      next
    end

    case mode
    when :program, :module
      next unless line =~ USE_REG

      program_unit.deps << DependedModule.new(low_sym($2), if $1.nil? then nil else low_sym($1) end)
    end
  end

  program_unit_list
end

#without_comments_and_stringsObject



76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/fort/src/code.rb', line 76

def without_comments_and_strings()
  self.gsub(STRING_OR_COMMENT_REG) do |s|
    if $2
      s[STRING_OR_COMMENT_REG, 2] = ''
    elsif $3
      s[STRING_OR_COMMENT_REG, 3] = ''
    else
      raise MustNotHappen
    end

    s
  end
end

#without_continuation_ampersandObject



90
91
92
# File 'lib/fort/src/code.rb', line 90

def without_continuation_ampersand()
  self.gsub(CONTINUATION_AMPERSAND_REG, '')
end

#without_one_line_semicolonObject



94
95
96
# File 'lib/fort/src/code.rb', line 94

def without_one_line_semicolon()
  self.gsub(ONE_LINER_REG, "\n")
end