Class: Lisp::Format::Directives::FFFP

Inherits:
Directive show all
Defined in:
lib/carat/lisp-format.rb

Overview

Represents the ~F (Fixed-format floating-point) directive. This outputs floating point values with various kinds of padding and such.

Instance Attribute Summary

Attributes inherited from Directive

#pos

Instance Method Summary collapse

Methods inherited from Directive

#initialize, #join

Constructor Details

This class inherits a constructor from Lisp::Format::Directives::Directive

Instance Method Details

#execute(state) ⇒ Object

Outputs the given argument using a floating-point representation. The full form is

~w,d,k,overflowchar,padchar@F

with the following interpretations

w (nil)

if non-nil, the output will be exactly w characters long,

d (nil)

if non-nil, this is the number of digits output after the decimal point (.),

k (0)

scaling factor - the number is first scaled using this value,

overflowchar (nil)

if non-nil, this character is used when this directive would produce output longer than that specified with the w directive,

padchar (?s)

character to pad with if w is non-nil and output isn’t wide enough yet,

@

numbers are always output with sign prepended.

An ArgumentError is raised if the argument is not a number or a string that can be converted to a number.



996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
# File 'lib/carat/lisp-format.rb', line 996

def execute(state)
  width = param(0, state, nil)
  digits = param(1, state, nil)
  scale = param(2, state, 0)
  overflowchar = param(3, state, nil)
  padchar = param(4, state, ?\s)
  arg = state.next_arg
  if arg.respond_to? :to_f
    num = arg.to_f * (10 ** scale)
    str = (at_mod? and num >= 0) ? '+' : ''
    str = sign + (digits.nil? ? num.to_s : sprintf("%.#{digits}f",num))
    str = sign + sprintf("%.#{$1}f", num) if str =~ /e-([0-9]+)$/
    unless width.nil?
      if not digits.nil? and width == digits + 1
        str.sub!(/^([+-]?)0\./, '\1.')
      end
      str = str.rjust(width, padchar.chr) if str.length < width
      if str.length > width and digits.nil?
        prec = width - (str.index(/\./) + 1) 
        str = sign + sprintf("%#.#{prec}f", num)
      end
      str.sub!(/\.$/, '') if str.length > width and digits.nil?
      if str.length > width and not overflowchar.nil?
        str = overflowchar.chr * width
      end
    end
    state.output str
  elsif arg.respond_to? :to_int
    state.push_back_arg
    parameters = @params[0].nil? ? [] : [@params[0]]
    Factory.build(parameters, [], ?D, nil, @pos).execute(state)
  else
    arg_error 'argument is not a number or a number string'
  end
end