Sha256: b1fa9e1f54fcbed903d7adf41fcebb4f0abc601485917db874c85a2f37e49735

Contents?: true

Size: 1.94 KB

Versions: 1

Compression:

Stored size: 1.94 KB

Contents

# encoding: utf-8
# frozen_string_literal: true

module Carbon
  module Compiler
    class Scanner
      # Performs the scanning.
      module Main
      protected

        def scan
          false ||
            scan_keywords ||
            scan_identifiers ||
            scan_operators ||
            scan_comment ||
            scan_whitespace ||
            error!
        end

        # rubocop:disable Metrics/CyclomaticComplexity
        def scan_identifiers
          false ||
            match(/[a-z][A-Za-z0-9_-]*[!?=]?/, :IDENTIFIER) ||
            match(/(0[xX][0-9a-fA-F]+)(_?[ui][0-9]+)?/, :NUMBER) ||
            match(/(0|[1-9][0-9]*)(_?[ui][0-9]+)?/, :NUMBER) ||
            match(/[A-Z][A-Za-z0-9_-]*/, :MNAME) ||
            match(/"(([^"\\]|\\.)*)"/, :STRING) ||
            false
        end

        KEYWORDS = %i(
          finally return struct module catch elsif match trait while
          self else enum for def end let try do if _
        ).sort_by(&:size).reverse.freeze

        def scan_keywords
          KEYWORDS.find do |keyword|
            m = match(/#{Regexp.escape(keyword)}(?![a-zA-Z0-9!?=_-])/, keyword)
            return m if m
          end || false
        end

        OPERATORS = %w(
          === :: => == && || != << >> <= >= + - ~ ! * / % : ; & | [ ] ( ) { } <
          > . , = ^ [] []=
        ).sort_by(&:size).reverse.freeze

        def scan_operators
          OPERATORS.find do |operator|
            m = match(operator)
            return m if m
          end || false
        end

        def scan_comment
          if @scanner.scan(/\#.+?(\r\n|\r|\n)/)
            @line += 1
            @last = @scanner.charpos - 1
            true
          end
        end

        def scan_whitespace
          if @scanner.scan(/\r\n|\r|\n/)
            @line += 1
            @last = @scanner.charpos - 1
            true
          elsif @scanner.scan(/[ \v\t\f]/)
            true
          end
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
carbon-compiler-0.2.0 lib/carbon/compiler/scanner/main.rb