# encoding: utf-8 # frozen_string_literal: true module Carbon module Compiler class Parser # Parses common items, such as module names and types. module Common protected Parser.first(:name, [:IDENTIFIER, :module, :struct, :enum, :trait, :def, :self, :_]) def parse_name error(first(:name)) unless first(:name).include?(peek.type) Node::Name.new([shift]) end # TODO: pointer Parser.first(:type, [:MNAME, :"("]) def parse_type type = case peek.type when :MNAME then parse_module_name when :"(" then parse_unit_type else error first(:type) end end def parse_unit_type expect :"(" children = [] until peek? :")" children << parse_type break unless peek? :"," expect :"," end expect :")" Node::Type::Unit.new(children) end def parse_module_name base = parse_module_name_part children = [base] while peek? :"::" expect :"::" children << parse_module_name_part end location = children.map(&:location).inject(:|) Concrete::Type.new(Concrete::Type::Name.new(children, nil), location: location) end def parse_module_name_part root = expect :MNAME generics = peek?(:<) ? parse_module_generics : [] location = [root].concat(generics).map(&:location).inject(:|) Concrete::Type::Part.new(root.value, generics, location: location) end def parse_module_generics children = [] expect :< until peek? :> name = parse_module_name children << Concrete::Type::Generic.new(name, [], location: name.location) break unless peek? :"," expect :"," end expect :> children end end end end end