Class: Parser::Lexer

Inherits:
Object
  • Object
show all
Defined in:
lib/sdx/compiler/parser.rb

Constant Summary collapse

TOKENS =
{
    /\A#.*/ => :comment,
    /\Aif/ => :if,
    /\Aelse/ => :else,
    /\Awhile/ => :while,
    /\Afor/ => :for,
    /\Ain/ => :in,
    /\Afn/ => :fn,
    /\Aobject/ => :object,
    /\Anew/ => :new,
    /\Arequire/ => :require,
    /\A(true|false)/ => :bool,
    /\A-?[0-9]+\.[0-9]+/ => :float,
    /\A-?[0-9]+/ => :number,
    /\A(\+|-)/ => :l1op,
    /\A(\/|\*|%|\^)/ => :l2op,
    /\A(<|>|<=|>=|==|!=)/ => :l1op,
    /\A(\+|-|\*|\/|%)?=/ => :eq,
    /\A"([^"]|\\")*"/ => :string,
    /\Anil/ => :nil,
    /\A\(/ => :lpar,
    /\A\)/ => :rpar,
    /\A\[/ => :lbrack,
    /\A\]/ => :rbrack,
    /\A\{/ => :lbrace,
    /\A\}/ => :rbrace,
    /\A,/ => :comma,
    /\A[A-Za-z_][A-Za-z0-9_]*([:.][A-Za-z_][A-Za-z0-9_]*)*/ => :name
}

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.linesObject

Returns the value of attribute lines.



46
47
48
# File 'lib/sdx/compiler/parser.rb', line 46

def lines
  @lines
end

Class Method Details

.lex(code) ⇒ Object



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
# File 'lib/sdx/compiler/parser.rb', line 49

def self.lex(code)
    @@lines = code.split "\n"
    lexed = []
    comment = false
    line = col = 0
    State::state = :ok
    while State::state == :ok and code.size > 0
        while true
            if code.size != 0 and code[0] == "\n"
                col = 0
                line += 1
                code = code[1..-1]
            elsif code.size != 0 and code[0].strip.empty?
                if State::state == :ok
                    col += 1
                end
                code = code[1..-1]
            else
                break
            end
        end
        if !comment && (code.start_with? "#>")
            comment = true
            code = code[2..-1]
        elsif comment && (code.start_with? "<#")
            comment = false
            code = code[2..-1]
        elsif comment
            code = code[1..-1]
        else
            found = false
            TOKENS.each { |re, tag|
                if (code =~ re) != nil
                    found = true
                    m = (re.match code)
                    if tag != :comment
                        lexed << [ m[0], tag, line, col ]
                    end
                    code = code[(m.end 0)..-1]
                    col += (m.end 0)
                    while true
                        if code.size != 0 and code[0] == "\n"
                            col = 0
                            line += 1
                            code = code[1..-1]
                        elsif code.size != 0 and code[0].strip.empty?
                            if State::state == :ok
                                col += 1
                            end
                            code = code[1..-1]
                        else
                            break
                        end
                    end
                    break
                end
            }
            if !found
                error %{
Invalid code at #{line}:#{col}
#{" " * line.to_s.size} |
#{line} | #{@@lines[line].rstrip}
#{" " * line.to_s.size} | #{" " * col}^ here}
                State::state = :error
            end
        end
    end
    [ lexed, @@lines ]
end