# encoding: utf-8 # frozen_string_literal: true module Carbon module Compiler class Parser module Expressions # Parses primary expressions, e.g. literals, module calls, etc. module Primary protected FUNCTION_NAMES = Set[:|, :&, :"^", :===, :==, :<, :>, :<=, :>=, :<=>, :<<, :>>, :+, :-, :*, :/, :%, :[], :[]=] Parser.first(:module, [:MNAME]) Parser.first(:literal, [:NUMBER, :FLOAT, :STRING]) Parser.first(:unit, [:"("]) Parser.first(:expression, Parser.first(:module) | Parser.first(:literal) | Parser.first(:unit) | Parser.first(:name)) Parser.first(:call, Parser.first(:name)) def parse_expression_primary if first(:module).include?(peek.type) parse_expression_module elsif first(:literal).include?(peek.type) parse_expression_literal elsif first(:unit).include?(peek.type) parse_expression_unit elsif first(:name).include?(peek.type) parse_expression_name else error(first(:expression)) end end def parse_expression_module mname = parse_module_name case peek.type when :"." parse_expression_call(mname) else error([:"."]) end end def parse_expression_name name = parse_name return name unless peek? :"(" l = expect :"(" children = [] until peek? :")" children << parse_expression break unless peek? :"," expect :"," end r = expect :")" arguments = Node::Expression::Call::Parameters.new(children, components: [l, r]) Node::Expression::Call::Self.new([name, arguments]) end def parse_expression_call_name if first(:name).include?(peek.type) parse_name elsif peek?(:MNAME) expect :MNAME else error(first(:name) | [:MNAME]) end end def parse_expression_call(mname) expect :"." name = parse_expression_call_name generics = peek?(:<) ? parse_module_generics : [] l = expect :"(" children = [] until peek? :")" children << parse_expression break unless peek? :"," expect :"," end r = expect :")" arguments = Node::Expression::Call::Parameters.new(children, components: [l, r]) Node::Expression::Call::Module.new([mname, name, arguments, generics]) end def parse_expression_unit expect :"(" children = [] until peek? :")" children << parse_expression break unless peek? :"," expect :"," end expect :")" Node::Expression::Unit.new(children) end def parse_expression_literal case peek.type when :NUMBER Node::Expression::Literal.new([expect(:NUMBER)]) when :FLOAT Node::Expression::Literal.new([expect(:FLOAT)]) when :STRING Node::Expression::Literal.new([expect(:STRING)]) else error first(:literal) end end end end end end end