# encoding: utf-8 # frozen_string_literal: true module Carbon module Compiler class Parser module Root # Parses a function. module Function protected def parse_function expect :def name = parse_function_name parameters = parse_function_parameters type = parse_function_type body = parse_function_body if peek?(:do) Node::Definition::Function.new([name, parameters, type, body]) end def parse_function_name name = parse_name generics = peek?(:"<") ? parse_module_generics : [] Node::Definition::Function::Name.new([name, generics]) end def parse_function_parameters l = expect :"(" parameters = [] until peek? :")" parameters << parse_function_parameter break unless peek? :"," expect :"," end r = expect :")" Node::Definition::Function::Parameters.new(parameters, components: [l, r]) end def parse_function_parameter case peek.type when :self then parse_function_argument_self when :_ then parse_function_argument_ignore else parse_function_argument_normal end end def parse_function_argument_self Node::Definition::Function::Argument.new([expect(:self)]) end def parse_function_argument_ignore under = expect :_ expect :":" type = parse_type Node::Definition::Function::Argument.new([under, type]) end def parse_function_argument_normal name = parse_name expect :":" type = parse_type Node::Definition::Function::Argument.new([name, type]) end def parse_function_type expect :":" parse_type end def parse_function_body start = expect :do statements = [] statements << parse_statement until peek? :end stop = expect :end Node::Definition::Function::Body.new(statements, components: [start, stop]) end end end end end end