class Parser::Lexer

Constants

TOKENS

Attributes

lines[RW]

Public Class Methods

lex(code) click to toggle source
# File lib/sdx/compiler/parser.rb, line 50
        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