StringPhysicalCast

Changes how a string is represented, not what it holds.

Declaration

Syntax

StringPhysicalCast(expr arg, string_physical_type old,
    string_physical_type new, ttype type, expr? value)

Arguments

Argument

Description

arg

the string expression to re-describe.

old

its current representation; see string_physical_type.

new

the representation to produce.

type

the type of the result, whose physical_type is new.

value

the compile time value of the expression, when the frontend could fold it; nil otherwise.

Return values

The value of the expression.

Description

A string is stored either as a descriptor, {char* data, int64 size, int64 capacity}, or as a bare char*. The logical type does not change here: only the representation does.

Casting a descriptor to CChar hands the runtime the data pointer, which is what the string runtime functions take. Casting the other way wraps a pointer in a descriptor whose size and capacity are set to -1, marking a string that must not be extended.

The verifier requires the result type of the cast to have len_kind=ImplicitLength, since the length of the re-described value is not a property of the cast.

Examples

(StringPhysicalCast
  :arg (Var
    :v (SymbolRef 1 "s")
  )
  :old :DescriptorString
  :new :CChar
  :type (String
    :kind 1
    :len nil
    :len_kind :ImplicitLength
    :physical_type :CChar
  )
  :value nil
)

It comes from this complete ASR text document:

(TranslationUnit
  :symtab (SymbolTable
    :id 0
    :symbols {
      "main" (Program
        :symtab (SymbolTable
          :id 1
          :symbols {
            "puts" (Function
              :symtab (SymbolTable
                :id 2
                :symbols {
                  "x" (Variable
                    :parent_symtab 2
                    :name "x"
                    :dependencies []
                    :intent :In
                    :symbolic_value nil
                    :value nil
                    :storage :Default
                    :type (String
                      :kind 1
                      :len nil
                      :len_kind :AssumedLength
                      :physical_type :CChar
                    )
                    :type_declaration nil
                    :abi :Source
                    :access :Public
                    :presence :Required
                    :value_attr false
                    :target_attr false
                    :contiguous_attr false
                    :bindc_name nil
                    :is_volatile false
                    :is_protected false
                    :pass_attr :NotMethod
                    :self_argument nil
                    :codims []
                  )
                }
              )
              :name "puts"
              :function_signature (FunctionType
                :arg_types [
                  (String
                    :kind 1
                    :len nil
                    :len_kind :AssumedLength
                    :physical_type :CChar
                  )
                ]
                :return_var_type nil
                :abi :BindC
                :deftype :Interface
                :bindc_name nil
                :elemental false
                :pure false
                :module false
                :inline false
                :static false
                :restrictions []
                :is_restriction false
              )
              :dependencies []
              :args [
                (Var
                  :v (SymbolRef 2 "x")
                )
              ]
              :body []
              :return_var nil
              :access :Public
              :deterministic false
              :side_effect_free false
              :module_file nil
            )
            "s" (Variable
              :parent_symtab 1
              :name "s"
              :dependencies []
              :intent :Local
              :symbolic_value nil
              :value nil
              :storage :Default
              :type (String
                :kind 1
                :len (IntegerConstant
                  :n 5
                  :type (Integer
                    :kind 4
                  )
                  :intboz_type :Decimal
                )
                :len_kind :ExpressionLength
                :physical_type :DescriptorString
              )
              :type_declaration nil
              :abi :Source
              :access :Public
              :presence :Required
              :value_attr false
              :target_attr false
              :contiguous_attr false
              :bindc_name nil
              :is_volatile false
              :is_protected false
              :pass_attr :NotMethod
              :self_argument nil
              :codims []
            )
          }
        )
        :name "main"
        :dependencies []
        :body [
          (SubroutineCall
            :name (SymbolRef 1 "puts")
            :original_name nil
            :args [
              (call_arg
                :value (StringPhysicalCast
                  :arg (Var
                    :v (SymbolRef 1 "s")
                  )
                  :old :DescriptorString
                  :new :CChar
                  :type (String
                    :kind 1
                    :len nil
                    :len_kind :ImplicitLength
                    :physical_type :CChar
                  )
                  :value nil
                )
              )
            ]
            :dt nil
            :strict_bounds_checking false
          )
        ]
      )
    }
  )
  :items []
)

See Also

StringPhysicalType, String, Cast, ArrayPhysicalCast