Class: Frepl::Classifier

Inherits:
Object
  • Object
show all
Defined in:
lib/frepl/classifier.rb

Constant Summary collapse

VARIABLE_NAME_REGEX =
/[a-zA-Z][a-zA-Z0-9_]{,30}/
ASSIGNABLE_VALUE_REGEX =

TODO this regex seems incorrect, e.g. assignable value can’t start with most punctuation

/[^\s]+/
DERIVED_TYPE_IDENTIFIER_REGEX =
/\(#{VARIABLE_NAME_REGEX}\)/
DERIVED_TYPE_REGEX =
/type\s+(#{VARIABLE_NAME_REGEX})/i
BUILTIN_TYPE_REGEX =
/real|integer|character|logical/i
DECLARABLE_TYPE_REGEX =
/#{BUILTIN_TYPE_REGEX}|type\s\(#{VARIABLE_NAME_REGEX}\)\s/i
DECLARATION_REGEX =

TODO: parameter/dimension order shouldn’t matter here

/\As*(#{DECLARABLE_TYPE_REGEX})\s*(\((?:kind=|len=)*[^\(\)]+\)){,1}+(\s*,?\s*parameter\s*,?\s*)?(\s*,?\s*dimension\([^\)]+\))?(\s*,?\s*target)?(\s*,?\s*pointer)?\s*(?:::)?\s*([^(?:::)]*)/
ASSIGNABLE_REGEX =
/#{VARIABLE_NAME_REGEX}|#{VARIABLE_NAME_REGEX}%#{VARIABLE_NAME_REGEX}/
ASSIGNMENT_REGEX =
/\As*(#{ASSIGNABLE_REGEX})\s*=\s*(#{ASSIGNABLE_VALUE_REGEX})/
OLDSKOOL_ARRAY_VALUE_REGEX =
/\/[^\]]+\//
F2003_ARRAY_VALUE_REGEX =
/\[[^\]]+\]/
ARRAY_VALUE_REGEX =
/#{OLDSKOOL_ARRAY_VALUE_REGEX}|#{F2003_ARRAY_VALUE_REGEX}/
FUNCTION_REGEX =
/(#{BUILTIN_TYPE_REGEX})\s+function\s+(#{VARIABLE_NAME_REGEX})/i
SUBROUTINE_REGEX =
/subroutine\s+(#{VARIABLE_NAME_REGEX})/i
IF_STATEMENT_REGEX =
/if\s+\(.+\)\sthen/i
DO_LOOP_REGEX =
/do\s+[^,]+,.+/i
WHERE_REGEX =
/where\s+\([^\)]+\)\s*/i

Instance Method Summary collapse

Constructor Details

#initializeClassifier

Returns a new instance of Classifier.



23
24
25
26
27
# File 'lib/frepl/classifier.rb', line 23

def initialize
  @all_lines = []
  @current_lines = []
  @current_multiline_obj = nil
end

Instance Method Details

#allocation?Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/frepl/classifier.rb', line 90

def allocation?
  current_line.match(/allocate\(/) != nil
end

#assignment?Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/frepl/classifier.rb', line 98

def assignment?
  current_line.match(ASSIGNMENT_REGEX)
end

#classify(line) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/frepl/classifier.rb', line 29

def classify(line)
  if @current_multiline_obj && !@current_multiline_obj.incomplete?
    @current_multiline_obj = nil
    @current_lines = []
  end

  @all_lines << line
  @current_lines << line

  if multiline?(line)
    Frepl.log("MULTILINE")
    classify_multiline(line)
    return @current_multiline_obj
  else
    return classify_single_line(line)
  end
end

#declaration?Boolean

TODO this is stupid, may need real parser here

Returns:

  • (Boolean)


80
81
82
83
84
85
86
87
88
# File 'lib/frepl/classifier.rb', line 80

def declaration?
  m = current_line.match(DECLARATION_REGEX)
  return false unless m
  if m[7].gsub(ARRAY_VALUE_REGEX, '').count(',') == 0
    true
  else
    false
  end
end

#executable?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/frepl/classifier.rb', line 52

def executable?
  !get_more_lines?
end

#indentation_levelObject



106
107
108
109
110
111
112
# File 'lib/frepl/classifier.rb', line 106

def indentation_level
  if @current_multiline_obj && @current_multiline_obj.incomplete?
    2
  else
    0
  end
end

#interruptObject



47
48
49
50
# File 'lib/frepl/classifier.rb', line 47

def interrupt
  @current_multiline_obj = nil
  @current_lines = []
end

#lines_to_executeObject



56
57
58
# File 'lib/frepl/classifier.rb', line 56

def lines_to_execute
  @current_lines
end

#multi_declaration?Boolean

TODO this is stupid, may need real parser here

Returns:

  • (Boolean)


69
70
71
72
73
74
75
76
77
# File 'lib/frepl/classifier.rb', line 69

def multi_declaration?
  m = current_line.match(DECLARATION_REGEX)
  return false unless m
  if m[7].gsub(ARRAY_VALUE_REGEX, '').count(',') > 0
    true
  else
    false
  end
end

#multiline?(line) ⇒ Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/frepl/classifier.rb', line 60

def multiline?(line)
  line.match(/\Asubroutine|function|(?:#{IF_STATEMENT_REGEX})|(?:#{DO_LOOP_REGEX})|(?:#{DERIVED_TYPE_REGEX})|(?:#{WHERE_REGEX})\z/i) || @current_multiline_obj != nil
end

#repl_command?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/frepl/classifier.rb', line 64

def repl_command?
  current_line.start_with?('f:')
end

#run?Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/frepl/classifier.rb', line 94

def run?
  current_line.match(/\s*write|print|read|call/i) != nil
end

#standalone_variable?Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/frepl/classifier.rb', line 102

def standalone_variable?
  current_line.match(/\A#{VARIABLE_NAME_REGEX}\z/)
end