carbon-core 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -2
  3. data/.rspec +0 -0
  4. data/.rubocop.yml +0 -0
  5. data/.travis.yml +0 -0
  6. data/.yardopts +0 -0
  7. data/CODE_OF_CONDUCT.md +0 -0
  8. data/Gemfile +0 -0
  9. data/LICENSE.txt +0 -0
  10. data/README.md +0 -0
  11. data/Rakefile +0 -0
  12. data/Vagrantfile +83 -0
  13. data/carbon.gemspec +1 -1
  14. data/lib/carbon.rb +3 -2
  15. data/lib/carbon/concrete.rb +0 -0
  16. data/lib/carbon/concrete/build.rb +1 -1
  17. data/lib/carbon/concrete/index.rb +37 -13
  18. data/lib/carbon/concrete/item.rb +0 -0
  19. data/lib/carbon/concrete/item/base.rb +11 -0
  20. data/lib/carbon/concrete/item/data.rb +0 -0
  21. data/lib/carbon/concrete/item/function.rb +13 -1
  22. data/lib/carbon/concrete/item/internal.rb +0 -0
  23. data/lib/carbon/concrete/item/struct.rb +0 -0
  24. data/lib/carbon/concrete/item/struct/element.rb +0 -0
  25. data/lib/carbon/concrete/item/trait.rb +0 -0
  26. data/lib/carbon/concrete/item/trait/expectation.rb +0 -0
  27. data/lib/carbon/concrete/request.rb +0 -0
  28. data/lib/carbon/concrete/type.rb +0 -0
  29. data/lib/carbon/concrete/type/function.rb +0 -0
  30. data/lib/carbon/concrete/type/generic.rb +0 -0
  31. data/lib/carbon/concrete/type/name.rb +0 -0
  32. data/lib/carbon/concrete/type/parse.rb +0 -0
  33. data/lib/carbon/concrete/type/part.rb +0 -0
  34. data/lib/carbon/core.rb +1 -1
  35. data/lib/carbon/core/int.rb +0 -0
  36. data/lib/carbon/core/integer.rb +0 -0
  37. data/lib/carbon/core/integer/cast.rb +4 -4
  38. data/lib/carbon/core/integer/math.rb +11 -10
  39. data/lib/carbon/core/integer/misc.rb +6 -5
  40. data/lib/carbon/core/integer/pole.rb +9 -7
  41. data/lib/carbon/core/integer/ship.rb +4 -2
  42. data/lib/carbon/core/integer/sign.rb +0 -0
  43. data/lib/carbon/core/integer/type.rb +0 -0
  44. data/lib/carbon/core/integer/zero.rb +2 -2
  45. data/lib/carbon/core/pointer.rb +0 -0
  46. data/lib/carbon/core/pointer/access.rb +7 -4
  47. data/lib/carbon/core/pointer/cast.rb +1 -1
  48. data/lib/carbon/core/pointer/math.rb +12 -10
  49. data/lib/carbon/core/pointer/memory.rb +4 -4
  50. data/lib/carbon/core/pointer/type.rb +0 -0
  51. data/lib/carbon/tacky.rb +1 -0
  52. data/lib/carbon/tacky/block.rb +0 -0
  53. data/lib/carbon/tacky/builder.rb +14 -2
  54. data/lib/carbon/tacky/context.rb +12 -1
  55. data/lib/carbon/tacky/function.rb +1 -1
  56. data/lib/carbon/tacky/instruction.rb +9 -54
  57. data/lib/carbon/tacky/instruction/dependencies.rb +33 -0
  58. data/lib/carbon/tacky/instruction/generation.rb +90 -0
  59. data/lib/carbon/tacky/instruction/typeof.rb +25 -0
  60. data/lib/carbon/tacky/parameter.rb +0 -0
  61. data/lib/carbon/tacky/reference.rb +4 -0
  62. data/lib/carbon/tacky/typed.rb +25 -0
  63. data/lib/carbon/tacky/value.rb +0 -0
  64. data/lib/carbon/version.rb +1 -1
  65. data/scripts/core.rb +9 -0
  66. data/scripts/test.rb +19 -0
  67. metadata +12 -5
@@ -35,7 +35,7 @@ module Carbon
35
35
  function[:definition].add("entry").build do |b|
36
36
  this = function[:definition].params[0]
37
37
  this.name = "self"
38
- b.ret(b.icmp(:ne, this, 0))
38
+ b.ret(b.icmp(:ne, this, 0).as(Carbon::Boolean))
39
39
  end
40
40
  end
41
41
  end
@@ -110,7 +110,7 @@ module Carbon
110
110
  this = definition.params[0]
111
111
  this.name = "self"
112
112
 
113
- entry.ret(entry.add(this, 1))
113
+ entry.ret(entry.add(this, 1).as(this.type))
114
114
  end
115
115
 
116
116
  def define_prev_definition(definition)
@@ -118,7 +118,7 @@ module Carbon
118
118
  this = definition.params[0]
119
119
  this.name = "self"
120
120
 
121
- entry.ret(entry.sub(this, 1))
121
+ entry.ret(entry.sub(this, 1).as(this.type))
122
122
  end
123
123
 
124
124
  def define_iabs_definition(int, definition)
@@ -129,8 +129,9 @@ module Carbon
129
129
  if int.sign == :unsigned
130
130
  entry.ret(this)
131
131
  else
132
- y = entry.ashr(this, int.size - 1)
133
- entry.ret(entry.sub(entry.xor(this, y), y))
132
+ y = entry.ashr(this, int.size - 1).as(this.type)
133
+ sub = entry.sub(entry.xor(this, y).as(this.type), y).as(this.type)
134
+ entry.ret(sub)
134
135
  end
135
136
  end
136
137
 
@@ -95,8 +95,8 @@ module Carbon
95
95
  this.name = "self"
96
96
 
97
97
  return entry.ret(1) if int.sign == :unsigned
98
- sign = entry.lshr(this, int.size - 1)
99
- trunc = entry.trunc(sign, Carbon::Boolean)
98
+ sign = entry.lshr(this, int.size - 1).as(this.type)
99
+ trunc = entry.trunc(sign, Carbon::Boolean).as(Carbon::Boolean)
100
100
  entry.ret(trunc)
101
101
  end
102
102
 
@@ -106,9 +106,9 @@ module Carbon
106
106
  this.name = "self"
107
107
 
108
108
  return entry.ret(0) if int.sign == :unsigned
109
- sign = entry.lshr(this, int.size - 1)
110
- trunc = entry.trunc(sign, Carbon::Boolean)
111
- negate = entry.xor(trunc, 1)
109
+ sign = entry.lshr(this, int.size - 1).as(this.type)
110
+ trunc = entry.trunc(sign, Carbon::Boolean).as(Carbon::Boolean)
111
+ negate = entry.xor(trunc, 1).as(Carbon::Boolean)
112
112
  entry.ret(negate)
113
113
  end
114
114
 
@@ -117,7 +117,9 @@ module Carbon
117
117
  this = definition.params[0]
118
118
  this.name = "self"
119
119
 
120
- entry.ret(entry.xor(entry.trunc(this, Carbon::Boolean), 1))
120
+ trunc = entry.trunc(this, Carbon::Boolean).as(Carbon::Boolean)
121
+ xor = entry.xor(trunc, 1).as(Carbon::Boolean)
122
+ entry.ret(xor)
121
123
  end
122
124
 
123
125
  def define_odd_definition(_int, definition)
@@ -125,7 +127,7 @@ module Carbon
125
127
  this = definition.params[0]
126
128
  this.name = "self"
127
129
 
128
- entry.ret(entry.trunc(this, Carbon::Boolean))
130
+ entry.ret(entry.trunc(this, Carbon::Boolean).as(Carbon::Boolean))
129
131
  end
130
132
  end
131
133
  end
@@ -61,9 +61,11 @@ module Carbon
61
61
 
62
62
  def define_ship_definition_compare(params, blocks)
63
63
  blocks[0]
64
- .build { |b| b.br(b.icmp(:lt, *params), blocks[1], blocks[2]) }
64
+ .build { |b| b.br(b.icmp(:lt, *params).as(Carbon::Boolean),
65
+ blocks[1], blocks[2]) }
65
66
  blocks[2]
66
- .build { |b| b.br(b.icmp(:eq, *params), blocks[4], blocks[5]) }
67
+ .build { |b| b.br(b.icmp(:eq, *params).as(Carbon::Boolean),
68
+ blocks[3], blocks[4]) }
67
69
  end
68
70
  end
69
71
  end
File without changes
File without changes
@@ -25,7 +25,7 @@ module Carbon
25
25
  function[:definition].add("entry").build do |b|
26
26
  this = function[:definition].params[0]
27
27
  this.name = "self"
28
- b.ret(b.icmp(:eq, this, 0))
28
+ b.ret(b.icmp(:eq, this, 0).as(Carbon::Boolean))
29
29
  end
30
30
  end
31
31
  end
@@ -42,7 +42,7 @@ module Carbon
42
42
  function[:definition].add("entry").build do |b|
43
43
  this = function[:definition].params[0]
44
44
  this.name = "self"
45
- b.ret(b.icmp(:ne, this, 0))
45
+ b.ret(b.icmp(:ne, this, 0).as(Carbon::Boolean))
46
46
  end
47
47
  end
48
48
  end
File without changes
@@ -84,12 +84,13 @@ module Carbon
84
84
 
85
85
  private
86
86
 
87
- def define_array_set_definition(_int, definition)
87
+ def define_array_set_definition(int, definition)
88
88
  entry = definition.add("entry").build
89
89
  this, index, value = definition.params
90
90
  this.name, index.name, value.name = %w(self index value)
91
91
 
92
- entry.store(entry.gep(this, index), value)
92
+ gep = entry.gep(this, index).as(Carbon::Type("Carbon::UInt64"))
93
+ entry.store(gep, value)
93
94
  entry.ret(value)
94
95
  end
95
96
 
@@ -98,7 +99,9 @@ module Carbon
98
99
  this, index = definition.params
99
100
  this.name, index.name = %w(self index)
100
101
 
101
- entry.ret(entry.load(entry.gep(this, index)))
102
+ gep = entry.gep(this, index).as(Carbon::Type("Carbon::UInt64"))
103
+ load = entry.load(gep).as(PTYPEGEN)
104
+ entry.ret(load)
102
105
  end
103
106
 
104
107
  def define_value_set_definition(definition)
@@ -115,7 +118,7 @@ module Carbon
115
118
  this = definition.params[0]
116
119
  this.name = "self"
117
120
 
118
- entry.ret(entry.load(this))
121
+ entry.ret(entry.load(this).as(PTYPEGEN))
119
122
  end
120
123
  end
121
124
  end
@@ -47,7 +47,7 @@ module Carbon
47
47
  this = definition.params[0]
48
48
  this.name = "self"
49
49
 
50
- entry.ret(entry.ptr2int(this, int.name))
50
+ entry.ret(entry.ptr2int(this, int.name).as(int.name))
51
51
  end
52
52
  end
53
53
  end
@@ -126,8 +126,8 @@ module Carbon
126
126
  this, other = params
127
127
  this.name, other.name = %w(self other)
128
128
  fname = PTYPE.call(int.cast, [PTYPE])
129
- thisint = entry.call(fname, this)
130
- otherint = entry.call(fname, other)
129
+ thisint = entry.call(fname, this).as(int.name)
130
+ otherint = entry.call(fname, other).as(int.name)
131
131
  [thisint, otherint]
132
132
  end
133
133
 
@@ -138,7 +138,8 @@ module Carbon
138
138
  this, other = perform_pointer_cast(entry, params, int)
139
139
 
140
140
  fname = PTYPE.call(:<=>, [int.name, int.name])
141
- entry.ret(entry.call(fname, this, other))
141
+ call = entry.call(fname, this, other)
142
+ entry.ret(call.as(Carbon::Type("Carbon::Int8")))
142
143
  end
143
144
 
144
145
  def define_comp_pointer_definition(op, definition)
@@ -148,7 +149,7 @@ module Carbon
148
149
  this, other = perform_pointer_cast(entry, params, int)
149
150
  icmp = Integer::Math::COMP_OPERATIONS_MAP.fetch([:signed, op])
150
151
 
151
- entry.ret(entry.icmp(icmp, this, other))
152
+ entry.ret(entry.icmp(icmp, this, other).as(Carbon::Boolean))
152
153
  end
153
154
 
154
155
  def define_space_definition(int, definition)
@@ -157,9 +158,10 @@ module Carbon
157
158
  this.name, other.name = %w(self other)
158
159
 
159
160
  fname = PTYPE.call(int.cast, [PTYPE])
160
- intptr = entry.call(fname, this)
161
+ intptr = entry.call(fname, this).as(int.name)
161
162
  fname = PTYPE.call(:<=>, [int.name, int.name])
162
- entry.ret(entry.call(fname, intptr, other))
163
+ compare = entry.call(fname, intptr, other)
164
+ entry.ret(compare.as(Carbon::Type("Carbon::Int8")))
163
165
  end
164
166
 
165
167
  def define_comp_definition(int, op, definition)
@@ -168,18 +170,18 @@ module Carbon
168
170
  this.name, other.name = %w(self other)
169
171
 
170
172
  fname = PTYPE.call(int.cast, [PTYPE])
171
- intptr = entry.call(fname, this)
173
+ intptr = entry.call(fname, this).as(int.name)
172
174
  icmp = Integer::Math::COMP_OPERATIONS_MAP.fetch([int.sign, op])
173
- entry.ret(entry.icmp(icmp, intptr, other))
175
+ entry.ret(entry.icmp(icmp, intptr, other).as(Carbon::Boolean))
174
176
  end
175
177
 
176
178
  def define_math_definition(_int, op, definition)
177
179
  entry = definition.add("entry").build
178
180
  this, other = definition.params
179
181
  this.name, other.name = %w(self other)
180
- other = entry.mul(other, -1) if op == :-
182
+ other = entry.mul(other, -1).as(other.type) if op == :-
181
183
 
182
- entry.ret(entry.gep(this, other))
184
+ entry.ret(entry.gep(this, other).as(PTYPE))
183
185
  end
184
186
  end
185
187
  end
@@ -60,10 +60,10 @@ module Carbon
60
60
  size = definition.params[0]
61
61
  size.name = "size"
62
62
 
63
- element = entry.sizeof(PTYPEGEN)
63
+ element = entry.sizeof(PTYPEGEN).as(Carbon::Type("Carbon::UInt64"))
64
64
  size = convert_int_size(int, size, entry)
65
- total = entry.mul(element, size)
66
- entry.ret(entry.malloc(total))
65
+ total = entry.mul(element, size).as(size.type)
66
+ entry.ret(entry.malloc(total).as(PTYPE))
67
67
  end
68
68
 
69
69
  def define_free_definition(definition)
@@ -77,7 +77,7 @@ module Carbon
77
77
  def convert_int_size(int, value, entry)
78
78
  size = Int.find(sign: :unsigned, size: 64)
79
79
  name = int.name.call(size.cast, [int.name])
80
- entry.call(name, value)
80
+ entry.call(name, value).as(size.name)
81
81
  end
82
82
  end
83
83
  end
File without changes
@@ -9,6 +9,7 @@ require "carbon/tacky/value"
9
9
  require "carbon/tacky/instruction"
10
10
  require "carbon/tacky/parameter"
11
11
  require "carbon/tacky/reference"
12
+ require "carbon/tacky/typed"
12
13
 
13
14
  module Carbon
14
15
  # Tacky is a IR implementation. It is a medium-level IR, just above LLVM IR
File without changes
@@ -288,6 +288,14 @@ module Carbon
288
288
  _call(:_null, type)
289
289
  end
290
290
 
291
+ def typeof(value)
292
+ _call(:_typeof, value)
293
+ end
294
+
295
+ def mcall(mod, name, *params)
296
+ _call(:_mcall, mod, name, *params)
297
+ end
298
+
291
299
  # Creates an instruction, and returns a reference to that instruction.
292
300
  # The reference points to the instruction using the "instruction id,"
293
301
  # which is essentially the instruction's place in the block.
@@ -299,11 +307,15 @@ module Carbon
299
307
  # @param name [::String] The return value name of the instruction.
300
308
  # @return [Tacky::Reference] The reference to the new instruction.
301
309
  def _call(inst, *parameters, name: "")
310
+ # cut it off at the pass and force all parameters to instructions to
311
+ # have a type.
302
312
  id = @block.next
303
- instruction = Tacky::Instruction.new(id, inst, parameters)
313
+ typed = parameters.map { |p| Tacky::Typed.from(p) }
314
+ reference = Tacky::Reference.new(id)
315
+ instruction = Tacky::Instruction.new(id, inst, parameters, reference)
304
316
  instruction.name = name
305
317
  @block.instructions << instruction
306
- Tacky::Reference.new(id)
318
+ reference
307
319
  end
308
320
  end
309
321
  end
@@ -49,11 +49,18 @@ module Carbon
49
49
  attr_reader :functions
50
50
  def_delegator :@build, :functions
51
51
 
52
+ # Returns the function that this is being built for.
53
+ #
54
+ # @return [Tacky::Function]
55
+ attr_reader :function
56
+
52
57
  # Initialize the context.
53
58
  #
59
+ # @param function [Tacky::Function]
54
60
  # @param build [Concrete::Build]
55
61
  # @param generics [{::String => Concrete::Type}]
56
- def initialize(build, generics)
62
+ def initialize(function, build, generics)
63
+ @function = function
57
64
  @build = build
58
65
  @generics = generics
59
66
  @instructions = []
@@ -61,6 +68,10 @@ module Carbon
61
68
  @params = []
62
69
  freeze
63
70
  end
71
+
72
+ def find(name)
73
+ name.function? ? functions.fetch(name).last : types.fetch(name).last
74
+ end
64
75
  end
65
76
  end
66
77
  end
@@ -105,7 +105,7 @@ module Carbon
105
105
  # being applied to the function.
106
106
  # @return [void]
107
107
  def call(function, build, generics)
108
- context = Context.new(build, generics)
108
+ context = Context.new(self, build, generics)
109
109
  mark_function_params(context, function)
110
110
 
111
111
  @blocks.each do |block|
@@ -1,11 +1,16 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
+ #
4
+ require "carbon/tacky/instruction/generation"
5
+ require "carbon/tacky/instruction/typeof"
3
6
 
4
7
  module Carbon
5
8
  module Tacky
6
9
  # An instruction. This is the building block of the rest of the Tacky
7
10
  # structures. Each instruction performs some sort of action.
8
11
  class Instruction < Value
12
+ include Instruction::Generation
13
+ include Instruction::Typeof
9
14
  # Instructions that can be represented by this class that can have a
10
15
  # name parameter.
11
16
  #
@@ -40,10 +45,11 @@ module Carbon
40
45
  # @param name [::Symbol, ::String] The name of the instruction.
41
46
  # @param parameters [<Reference, Parameter, Value, ::Object>] The
42
47
  # parameters to be used with the instruction.
43
- def initialize(id, name, parameters)
48
+ def initialize(id, name, parameters, reference)
44
49
  @value = id
45
50
  @instruction = name.to_s
46
51
  @parameters = parameters
52
+ @reference = reference
47
53
  end
48
54
 
49
55
  # Builds the instruction. If the instruction is special, i.e. it starts
@@ -60,7 +66,9 @@ module Carbon
60
66
  def call(context, block)
61
67
  case @instruction
62
68
  when "_null" then generate_null(context, block)
69
+ when "_mcall" then generate_mcall(context, block)
63
70
  when "_sizeof" then generate_sizeof(context, block)
71
+ when "_typeof" then generate_typeof(context, block)
64
72
  else generate_normal(context, block)
65
73
  end
66
74
  end
@@ -112,59 +120,6 @@ module Carbon
112
120
 
113
121
  name
114
122
  end
115
-
116
- private
117
-
118
- # Generates a "normal" instruction. It maps the parameters, then sends
119
- # the instruction over to a builder for LLVM, before returning the
120
- # result of the instruction.
121
- #
122
- # @param context [Tacky::Context] The context.
123
- # @param block [::LLVM::BasicBlock] The block.
124
- # @return [::LLVM::Value] The result of the llvm instruction.
125
- def generate_normal(context, block)
126
- params = mapped_parameters(context, block)
127
- value = nil
128
-
129
- block.build { |b| value = b.public_send(@instruction, *params) }
130
- value
131
- end
132
-
133
- def generate_null(context, block)
134
- params = mapped_parameters(context, block)
135
- context.types.fetch(params.first).last.null
136
- end
137
-
138
- def generate_sizeof(context, block)
139
- params = mapped_parameters(context, block)
140
- context.types.fetch(params.first).last.size
141
- end
142
-
143
- def mapped_parameters(context, block)
144
- @parameters.map { |p| mapped_parameter(p, context, block) }
145
- end
146
-
147
- # rubocop:disable Metrics/CyclomaticComplexity
148
- def mapped_parameter(param, context, _block)
149
- case param
150
- when Concrete::Type then map_parameter_type(param, context)
151
- when Tacky::Reference then context.instructions.fetch(param.id)
152
- when Tacky::Parameter then context.params.fetch(param.value)
153
- when ::Integer then LLVM.Int(param)
154
- when ::Float then LLVM.Float(param)
155
- when ::String then param
156
- else fail ArgumentError, "Unexpected parameter #{param.class}"
157
- end
158
- end
159
- # rubocop:enable Metrics/CyclomaticComplexity
160
-
161
- def map_parameter_type(param, context)
162
- if param.function?
163
- context.functions.fetch(param)
164
- else
165
- context.types.fetch(param).last
166
- end
167
- end
168
123
  end
169
124
  end
170
125
  end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Tacky
6
+ class Instruction < Value
7
+ module Dependencies
8
+ def dependencies
9
+ case @instruction
10
+ when "_mcall" then dependencies_mcall
11
+ when "_ucall" then dependencies_ucall
12
+ when "_typeof" then dependencies_typeof
13
+ else dependencies_normal
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def dependencies_mcall
20
+ deps = Set.new
21
+ mod = @parameters[0]
22
+ types = @parameters[2..-1].map { }
23
+ @function = mod.call(@parameters[1])
24
+ deps << @parameters[0]
25
+ end
26
+
27
+ def dependencies_normal
28
+ @parameters.select { |p| p.is_a?(Concrete::Type) }.inject(Set.new, :<<)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end