Class: Stone::AST::PropertyAccess
- Inherits:
-
Expression
- Object
- Stone::AST
- Expression
- Stone::AST::PropertyAccess
- Defined in:
- lib/stone/ast/property_access.rb
Defined Under Namespace
Classes: TypeDispatchBuilder
Constant Summary collapse
- TYPE_PROPERTIES =
%w[as_String record? primitive? kind size fields].freeze
- FIELD_LIST_PROPERTIES =
%w[first name type rest].freeze
- TYPE_PROPERTY_GENERATORS =
{ "as_String" => :generate_type_as_string, "size" => :generate_type_size, "kind" => :generate_type_kind, "record?" => :generate_type_record_check, "primitive?" => :generate_type_primitive_check, "fields" => :generate_type_fields }.freeze
- FIELD_LIST_PROPERTY_GENERATORS =
{ "name" => :generate_field_list_name, "type" => :generate_field_list_type, "rest" => :generate_field_list_rest }.freeze
Instance Attribute Summary collapse
-
#property ⇒ Object
readonly
Returns the value of attribute property.
-
#receiver ⇒ Object
readonly
Returns the value of attribute receiver.
Attributes inherited from Stone::AST
Instance Method Summary collapse
-
#extract_union_type_tag(builder, mod, scope) ⇒ Object
Extract the type tag from a union field (for Type.of() support).
- #get_record_type_name(mod) ⇒ Object
-
#initialize(receiver, property) ⇒ PropertyAccess
constructor
A new instance of PropertyAccess.
- #returns_string_field?(mod) ⇒ Boolean
- #to_llir(builder, mod, scope = Stone::Scope.top_level) ⇒ Object
- #type(context = nil) ⇒ Object
-
#union_field_access?(mod) ⇒ Boolean
Check if this property access is on a union-typed field (for Type.of() support).
Constructor Details
#initialize(receiver, property) ⇒ PropertyAccess
15 16 17 18 19 |
# File 'lib/stone/ast/property_access.rb', line 15 def initialize(receiver, property) @receiver = receiver @property = property @name = :property_access end |
Instance Attribute Details
#property ⇒ Object (readonly)
Returns the value of attribute property.
13 14 15 |
# File 'lib/stone/ast/property_access.rb', line 13 def property @property end |
#receiver ⇒ Object (readonly)
Returns the value of attribute receiver.
13 14 15 |
# File 'lib/stone/ast/property_access.rb', line 13 def receiver @receiver end |
Instance Method Details
#extract_union_type_tag(builder, mod, scope) ⇒ Object
Extract the type tag from a union field (for Type.of() support)
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 |
# File 'lib/stone/ast/property_access.rb', line 497 def extract_union_type_tag(builder, mod, scope) record_type_name = get_record_type_name(mod) record_def = lookup_record_definition(mod, record_type_name) field_index = get_field_index(record_def, record_type_name) # Evaluate the receiver to get the record struct receiver_value = @receiver.to_llir(builder, mod, scope) # If receiver is a pointer (recursive field), load the struct first if receiver_value.type.kind == :pointer struct_type = record_def.llvm_type(mod) receiver_value = builder.load2(struct_type, receiver_value, "loaded_struct") end # Extract the union struct from the record union_value = builder.extract_value(receiver_value, field_index, "#{@property}_union") # Extract the type tag (index 0) from the union struct builder.extract_value(union_value, 0, "union_type_tag") end |
#get_record_type_name(mod) ⇒ Object
529 530 531 532 533 534 535 536 537 538 539 |
# File 'lib/stone/ast/property_access.rb', line 529 def get_record_type_name(mod) case @receiver when Reference mod.record_instance_type(@receiver.identifier) when FunctionCall @receiver.function_name when PropertyAccess # Receiver is a PropertyAccess - get the field type it returns get_receiver_field_type(mod) end end |
#returns_string_field?(mod) ⇒ Boolean
518 519 520 521 522 523 524 525 526 527 |
# File 'lib/stone/ast/property_access.rb', line 518 def returns_string_field?(mod) return false unless record_field_access?(mod) record_type_name = get_record_type_name(mod) record_def = mod.record_types[record_type_name] return false unless record_def field_def = record_def.fields.find { |f| f[:name] == @property } field_def && field_def[:type_name] == "String" end |
#to_llir(builder, mod, scope = Stone::Scope.top_level) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/stone/ast/property_access.rb', line 31 def to_llir(builder, mod, scope = Stone::Scope.top_level) # 1. Check if this is a record field access (highest priority) return access_record_field(builder, mod, scope) if record_field_access?(mod) # 2. Check if receiver is a union containing record(s) - enables chained access like o.value.x return access_field_on_union_record(builder, mod, scope) if receiver_is_union_with_record?(mod) # Resolve the receiver type for subsequent checks receiver_type = resolve_node_type(@receiver, mod) # Try different property access strategies handle_type_property(builder, mod, scope, receiver_type) || handle_field_list_property(builder, mod, scope, receiver_type) || handle_byte_count(mod) || handle_computed_property(builder, mod, scope, receiver_type) || fail_property_not_found(receiver_type) end |
#type(context = nil) ⇒ Object
21 22 23 24 25 26 27 28 29 |
# File 'lib/stone/ast/property_access.rb', line 21 def type(context = nil) receiver_type = @receiver.type(context) return nil unless receiver_type return_type = receiver_type.property_return_type(@property) fail Stone::PropertyError, "Property '#{@property}' not found for type '#{receiver_type.name}'" unless return_type return_type end |
#union_field_access?(mod) ⇒ Boolean
Check if this property access is on a union-typed field (for Type.of() support)
485 486 487 488 489 490 491 492 493 494 |
# File 'lib/stone/ast/property_access.rb', line 485 def union_field_access?(mod) return false unless record_field_access?(mod) record_type_name = get_record_type_name(mod) record_def = mod.record_types[record_type_name] return false unless record_def field_annotation = record_def.field_type_annotation(@property) Stone::AST::FieldHelpers.union_annotation?(field_annotation) end |