Class: MilkTea::ConstEval::Evaluator

Inherits:
Object
  • Object
show all
Includes:
Layout
Defined in:
lib/milk_tea/core/compile_time/const_eval.rb

Direct Known Subclasses

MilkTea::CompileTime::Evaluator

Constant Summary

Constants included from Layout

Layout::POINTER_SIZE

Instance Method Summary collapse

Methods included from Layout

align_up, alignment_of, array_type?, explicit_alignment, generic_layout, layout_pointer_like_nullable_base?, nullable_opt_layout_fields, offset_of, ordered_fields, packed_layout?, primitive_layout, size_and_alignment, size_of, str_buffer_fields, str_buffer_type?, struct_layout, struct_layout_from_infos, union_layout, union_layout_from_layouts, variant_layout, with_stack

Constructor Details

#initialize(resolve_identifier:, resolve_member_access:, resolve_type_ref: nil, resolve_call: nil) ⇒ Evaluator

Returns a new instance of Evaluator.



34
35
36
37
38
39
# File 'lib/milk_tea/core/compile_time/const_eval.rb', line 34

def initialize(resolve_identifier:, resolve_member_access:, resolve_type_ref: nil, resolve_call: nil)
  @resolve_identifier = resolve_identifier
  @resolve_member_access = resolve_member_access
  @resolve_type_ref = resolve_type_ref
  @resolve_call = resolve_call
end

Instance Method Details

#evaluate(expression) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/milk_tea/core/compile_time/const_eval.rb', line 41

def evaluate(expression)
  case expression
  when AST::ErrorExpr
    nil
  when AST::ExpressionList
    expression.elements.filter_map { |element| evaluate(element) }
  when AST::IntegerLiteral, AST::FloatLiteral, AST::BooleanLiteral
    expression.value
  when AST::StringLiteral
    expression.value
  when AST::Identifier
    @resolve_identifier&.call(expression)
  when AST::MemberAccess
    @resolve_member_access&.call(expression)
  when AST::Call
    @resolve_call&.call(expression)
  when AST::Specialization
    @resolve_call&.call(expression)
  when AST::SizeofExpr
    type = resolve_layout_type(expression.type)
    type && size_of(type)
  when AST::AlignofExpr
    type = resolve_layout_type(expression.type)
    type && alignment_of(type)
  when AST::OffsetofExpr
    type = resolve_layout_type(expression.type)
    if type
      result = offset_of(type, expression.field)
      return result if result

      id_expr = AST::Identifier.new(name: expression.field)
      value = @resolve_identifier&.call(id_expr)
      if value.is_a?(Types::FieldHandle)
        return offset_of(type, value.field_name)
      end
    end
    nil
  when AST::UnaryOp
    evaluate_unary(expression)
  when AST::BinaryOp
    evaluate_binary(expression)
  when AST::IfExpr
    condition = evaluate(expression.condition)
    return unless ConstEval.boolean_value?(condition)

    evaluate(condition ? expression.then_expression : expression.else_expression)
  else
    nil
  end
end