Module: Carbon::Compiler::Visitor::Generation::Statements

Included in:
Carbon::Compiler::Visitor::Generation
Defined in:
lib/carbon/compiler/visitor/generation/statements.rb

Overview

Statement generation.

Instance Method Summary collapse

Instance Method Details

#visit_statement_else(node, context, merge) ⇒ Object



112
113
114
115
116
# File 'lib/carbon/compiler/visitor/generation/statements.rb', line 112

def visit_statement_else(node, context, merge)
  accept(node.body, context)
  context.build.br(merge)
  context.swap(merge)
end

#visit_statement_elsif(node, context, merge) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/carbon/compiler/visitor/generation/statements.rb', line 94

def visit_statement_elsif(node, context, merge)
  cond = accept(node.condition)
  assert_type_boolean(cond.type, location: node.condition.location)
  check = context.build.icmp(:ne, cond, 0)

  ifetrue = context.new("if-else-true")
  ifefalse = context.new("if-else-false")

  context.build.cond(check, ifetrue, ifefalse)
  context.swap(ifetrue)
  accept(node.body, context)
  context.build.br(merge)
  context.swap(ifefalse)
  statement_if_false_merge(node, context, merge)
  context.swap(merge)
end

#visit_statement_for(node, context) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/carbon/compiler/visitor/generation/statements.rb', line 57

def visit_statement_for(node, context)
  loop, merge = context.new("for-loop"), context.new("for-merge")

  accept(node.initial, context)
  cond = accept(node.condition, context)
  assert_type_boolean(cond.type, location: node.condition.location)
  check = context.build.icmp(:ne, cond, 0)

  context.build.cond(check, loop, merge)
  context.swap(loop)
  accept(node.body, context)
  accept(node.increment, context)
  cond = accept(node.condition, context)
  check = context.build.icmp(:ne, cond, 0)
  context.build.cond(check, loop, merge)
  context.swap(merge)
end

#visit_statement_if(node, context) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/carbon/compiler/visitor/generation/statements.rb', line 76

def visit_statement_if(node, context)
  cond = accept(node.condition, context)
  assert_type_boolean(cond.type, location: node.condition.location)
  check = context.build.icmp(:ne, cond, 0)

  iftrue, iffalse, ifmerge = context.new("if-true"),
    context.new("if-false"), context.new("if-merge")

  context.build.cond(check, iftrue, iffalse)
  context.swap(iftrue)
  accept(node.body, context)
  context.build.br(ifmerge)
  context.swap(iffalse)
  statement_if_false_merge(node, context, merge)
  context.swap(ifmerge)
end

#visit_statement_let(node, context) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/carbon/compiler/visitor/generation/statements.rb', line 25

def visit_statement_let(node, context)
  name = node.name.value
  value = accept(node.value, context) if node.value
  assert_type_equal(value.type, node.type,
    location: node.value.location) if node.value
  assert_nolocal(name, context)

  context.build do |b|
    context[name] = b.alloca(node.type).as(node.type)
    value = value || b.null(node.type).as(node.type)
    b.store(value, context[name])
  end
end

#visit_statement_return(node, context) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/carbon/compiler/visitor/generation/statements.rb', line 11

def visit_statement_return(node, context)
  if node.value
    value = accept(node.value, context)
    assert_type_equal(value.type, context.function.type,
      location: node.location)
    context.build { |b| b.ret(value) }
  else
    assert_type_equal(Carbon::Void, context.function.type,
      location: node.location)
    context.build(&:ret_void)
  end
end

#visit_statement_while(node, context) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/carbon/compiler/visitor/generation/statements.rb', line 40

def visit_statement_while(node, context)
  loop, merge = context.new("while-loop"), context.new("while-merge")

  cond = accept(node.condition, context)
  assert_type_boolean(cond.type, location: node.condition.location)
  check = context.build.icmp(:ne, cond, 0)

  context.build.cond(check, loop, merge)
  context.swap(loop)
  accept(node.body, context)
  cond = accept(node.condition, context)
  check = context.build.icmp(:ne, cond, 0)
  context.build.cond(check, loop, merge)
  context.swap(merge)
end