class Apricot::SpecialForm::ArgList
Attributes
block_arg[R]
num_optional[R]
num_required[R]
num_total[R]
optional_args[R]
required_args[R]
rest_arg[R]
Public Class Methods
new(args, g)
click to toggle source
# File lib/apricot/special_forms/fn.rb, line 7 def initialize(args, g) state = :required @required_args = [] @optional_args = [] @rest_arg = nil @block_arg = nil args.each do |arg| # Check if we got one of the special identifiers which moves us to a # different part of the argument list. If so, move to the new state # and skip to the next argument. Also check that the current state # is allowed to move to the new state (the arguments must come in a # strict order: required, optional, rest, block). if arg.is_a? Identifier case arg.name # '?' starts the optional arguments section. when :'?' case state when :required state = :start_optional next else g.compile_error "Unexpected '?' in argument list" end # '&' precedes the rest argument. when :& case state when :required, :optional state = :rest next else g.compile_error "Unexpected '&' in argument list" end # '|' precedes the block argument. when :| case state when :required, :optional, :after_rest state = :block next else g.compile_error "Unexpected '|' in argument list" end end end # Deal with the argument based on the current state. case state when :required g.compile_error "Required argument in argument list must be an identifier" unless arg.is_a? Identifier @required_args << arg.name when :optional, :start_optional unless arg.is_a?(Seq) && arg.count == 2 && arg.first.is_a?(Identifier) g.compile_error "Optional argument in argument list must be of the form (name default)" end state = :optional @optional_args << [arg.first.name, arg.rest.first] when :rest g.compile_error "Rest argument in argument list must be an identifier" unless arg.is_a? Identifier @rest_arg = arg.name state = :after_rest when :block g.compile_error "Block argument in argument list must be an identifier" unless arg.is_a? Identifier @block_arg = arg.name state = :after_block when :after_rest g.compile_error "Unexpected argument after rest argument" when :after_block g.compile_error "Unexpected arguments after block argument" end end # Check if we finished in the middle of things without getting an # argument where we expected one. case state when :start_optional g.compile_error "Expected optional arguments after '?' in argument list" when :rest g.compile_error "Expected rest argument after '&' in argument list" when :block g.compile_error "Expected block argument after '|' in argument list" end @num_required = @required_args.length @num_optional = @optional_args.length @num_total = @num_required + @num_optional end
Public Instance Methods
to_array()
click to toggle source
# File lib/apricot/special_forms/fn.rb, line 105 def to_array args = @required_args.map {|id| Identifier.intern(id) } args += @optional_args.map {|name, val| [Identifier.intern(name), val.to_value] } args += [Identifier.intern(:|), Identifier.intern(@block_arg)] if @block_arg args += [Identifier.intern(:&), Identifier.intern(@rest_arg)] if @rest_arg args end