summaryrefslogtreecommitdiffstats
path: root/vendor/gems/coderay-0.9.7/test/functional/vhdl.rb
blob: c7e3824365c545877a6f7c5362b1d75ea00939d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
class VHDL < CodeRay::Scanners::Scanner

  register_for :vhdl

  RESERVED_WORDS = [
    'access','after','alias','all','assert','architecture','begin',
    'block','body','buffer','bus','case','component','configuration','constant',
    'disconnect','downto','else','elsif','end','entity','exit','file','for',
    'function','generate','generic','group','guarded','if','impure','in',
    'inertial','inout','is','label','library','linkage','literal','loop',
    'map','new','next','null','of','on','open','others','out','package',
    'port','postponed','procedure','process','pure','range','record','register',
    'reject','report','return','select','severity','signal','shared','subtype',
    'then','to','transport','type','unaffected','units','until','use','variable',
    'wait','when','while','with','note','warning','error','failure','and',
    'or','xor','not','nor',
    'array'
  ]

  PREDEFINED_TYPES = [
    'bit','bit_vector','character','boolean','integer','real','time','string',
    'severity_level','positive','natural','signed','unsigned','line','text',
    'std_logic','std_logic_vector','std_ulogic','std_ulogic_vector','qsim_state',
    'qsim_state_vector','qsim_12state','qsim_12state_vector','qsim_strength',
    'mux_bit','mux_vector','reg_bit','reg_vector','wor_bit','wor_vector'
  ]

  PREDEFINED_CONSTANTS = [

  ]

  IDENT_KIND = CodeRay::CaseIgnoringWordList.new(:ident).
    add(RESERVED_WORDS, :reserved).
    add(PREDEFINED_TYPES, :pre_type).
    add(PREDEFINED_CONSTANTS, :pre_constant)

  ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x
  UNICODE_ESCAPE =  / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x

  def scan_tokens tokens, options

    state = :initial

    until eos?

      kind = nil
      match = nil

      case state

      when :initial

        if scan(/ \s+ | \\\n /x)
          kind = :space

        elsif scan(/-- .*/x)
          kind = :comment

        elsif scan(/ [-+*\/=<>?:;,!&^|()\[\]{}~%]+ | \.(?!\d) /x)
          kind = :operator

        elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
          kind = IDENT_KIND[match.downcase]

        elsif match = scan(/[a-z]?"/i)
          tokens << [:open, :string]
          state = :string
          kind = :delimiter

        elsif scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox)
          kind = :char

        elsif scan(/(?:\d+)(?![.eEfF])/)
          kind = :integer

        elsif scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
          kind = :float

        else
          getch
          kind = :error

        end

      when :string
        if scan(/[^\\\n"]+/)
          kind = :content
        elsif scan(/"/)
          tokens << ['"', :delimiter]
          tokens << [:close, :string]
          state = :initial
          next
        elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
          kind = :char
        elsif scan(/ \\ | $ /x)
          tokens << [:close, :string]
          kind = :error
          state = :initial
        else
          raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
        end

      else
        raise_inspect 'Unknown state', tokens

      end

      match ||= matched
      if $DEBUG and not kind
        raise_inspect 'Error token %p in line %d' %
          [[match, kind], line], tokens
      end
      raise_inspect 'Empty token', tokens unless match

      tokens << [match, kind]

    end

    if state == :string
      tokens << [:close, :string]
    end

    tokens
  end

end