# encoding: utf-8 # frozen_string_literal: true module Carbon module Compiler module Node module Expression # A literal expression. Contains information about how the literal # expression should be represented. class Literal < Base # Replacements for strings. # # @return [{String => String}] REPLACE = { '\"' => '"', '\\\\' => '\\', '\/' => "/", '\b' => "\b", '\f' => "\f", '\n' => "\n", '\r' => "\r", '\t' => "\t" }.freeze # Yields a LLVM value representing the literal. # # @return [::Numeric, ::String] def value case @children.first.type when :NUMBER then number_value # LLVM.Int(@children.first.value.to_i) when :FLOAT LLVM.Float(@children.first.value.to_f) when :STRING fail @children.first.value[1..-2] .gsub(%r{\\["\\/bfnrt]}, REPLACE) else fail end end # Yields the Carbon type representing the literal. # # @return [Carbon::Concrete::Type] def type case @children.first.type # when :NUMBER then Carbon::Type("Carbon::Int32") when :NUMBER then number_type when :FLOAT then Carbon::Type("Carbon::Float") when :STRING then Carbon::Type("Carbon::String") else fail end end private def raw @children.first.value end def postfix raw.match(/(?:0x[a-f0-9]+|(?:0|[1-9][0-9]*))(?:_?([ui][0-9]+))?/)[1] || "i32" end def number raw.match(/(0x[a-f0-9]+|(?:0|[1-9][0-9]*))(?:_?(?:[ui][0-9]+))?/)[1] end def number_value LLVM.const_get("Int#{postfix[1..-1]}").from_i(number.to_i, postfix[0] == "i") end def number_type sign = postfix[0] == "i" ? :signed : :unsigned size = postfix[1..-1].to_i Core::Int.find(sign: sign, size: size).name end end end end end end