Class: Stone::AST::RecordDefinition

Inherits:
Expression show all
Defined in:
lib/stone/ast/record_definition.rb

Overview

TODO: Records should be first-class Type objects, not AST nodes. When the type system is refactored:

  • Record types should be instances of a RecordType class
  • Record types should be global constants with properties
  • Record types should have vtables for polymorphic operations
  • Record instantiation should work like any other function call

Instance Attribute Summary collapse

Attributes inherited from Stone::AST

#children, #name

Instance Method Summary collapse

Constructor Details

#initialize(fields) ⇒ RecordDefinition

fields is an array of { name: "field_name", type: "TypeName" } hashes



20
21
22
23
24
# File 'lib/stone/ast/record_definition.rb', line 20

def initialize(fields)
  @name = :record_definition
  @fields = fields
  @assigned_name = nil
end

Instance Attribute Details

#assigned_nameObject

Returns the value of attribute assigned_name.



17
18
19
# File 'lib/stone/ast/record_definition.rb', line 17

def assigned_name
  @assigned_name
end

#fieldsObject (readonly)

Returns the value of attribute fields.



16
17
18
# File 'lib/stone/ast/record_definition.rb', line 16

def fields
  @fields
end

Instance Method Details

#field_index(field_name) ⇒ Object



89
90
91
# File 'lib/stone/ast/record_definition.rb', line 89

def field_index(field_name)
  field_names.index(field_name)
end

#field_namesObject



76
77
78
# File 'lib/stone/ast/record_definition.rb', line 76

def field_names
  @fields.map { |f| f[:name] }
end

#field_type_annotation(field_name) ⇒ Object



84
85
86
87
# File 'lib/stone/ast/record_definition.rb', line 84

def field_type_annotation(field_name)
  field = @fields.find { |f| f[:name] == field_name }
  field&.dig(:type)
end

#field_typesObject



80
81
82
# File 'lib/stone/ast/record_definition.rb', line 80

def field_types
  @fields.map { |f| Stone::AST::FieldHelpers.field_type_name(f) }
end

#llvm_type(mod = nil, scope = Stone::Scope.top_level) ⇒ Object



93
94
95
96
97
# File 'lib/stone/ast/record_definition.rb', line 93

def llvm_type(mod = nil, scope = Stone::Scope.top_level)
  # Convert field types to LLVM types
  llvm_field_types = @fields.map { |field| llvm_type_for_field(field, mod, scope) }
  LLVM::Type.struct(llvm_field_types, false)
end

#to_llir(_builder, mod, scope = Stone::Scope.top_level) ⇒ Object



26
27
28
29
30
31
32
33
# File 'lib/stone/ast/record_definition.rb', line 26

def to_llir(_builder, mod, scope = Stone::Scope.top_level)
  # Validate all field types resolve in current scope
  validate_field_types(scope, mod)
  # Generate the type constant for this record
  generate_type_constant(mod, scope) if @assigned_name
  # Generate and return a constructor function that creates instances of this record
  generate_constructor_function(mod, scope)
end

#to_sObject



99
100
101
102
# File 'lib/stone/ast/record_definition.rb', line 99

def to_s
  field_strs = @fields.map { |f| "#{f[:name]} :: #{f[:type_name]}" }
  "Record(#{field_strs.join(', ')})"
end

#type(_context = nil) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
# File 'lib/stone/ast/record_definition.rb', line 104

def type(_context = nil)
  return nil unless @assigned_name

  record_type = Stone::Type::Registry.lookup(@assigned_name)
  return nil unless record_type

  param_types = @fields.map { |f| resolve_field_stone_type(f) }
  return nil if param_types.any?(&:nil?)

  Stone::Type.function(param_types:, return_type: record_type)
end