carbon-core 0.1.1 → 0.2.0

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +17 -0
  3. data/.gitignore +0 -0
  4. data/.rspec +0 -0
  5. data/.rubocop.yml +0 -0
  6. data/.travis.yml +0 -0
  7. data/.yardopts +0 -0
  8. data/CODE_OF_CONDUCT.md +0 -0
  9. data/Gemfile +0 -0
  10. data/LICENSE.txt +0 -0
  11. data/README.md +0 -0
  12. data/Rakefile +0 -0
  13. data/Vagrantfile +0 -0
  14. data/carbon.gemspec +0 -0
  15. data/lib/carbon.rb +25 -1
  16. data/lib/carbon/concrete.rb +4 -2
  17. data/lib/carbon/concrete/build.rb +21 -13
  18. data/lib/carbon/concrete/index.rb +53 -159
  19. data/lib/carbon/concrete/item.rb +0 -0
  20. data/lib/carbon/concrete/item/base.rb +14 -27
  21. data/lib/carbon/concrete/item/class.rb +71 -0
  22. data/lib/carbon/concrete/item/class/element.rb +42 -0
  23. data/lib/carbon/concrete/item/data.rb +0 -0
  24. data/lib/carbon/concrete/item/function.rb +35 -39
  25. data/lib/carbon/concrete/item/internal.rb +17 -19
  26. data/lib/carbon/concrete/item/struct.rb +12 -7
  27. data/lib/carbon/concrete/item/struct/element.rb +0 -0
  28. data/lib/carbon/concrete/item/trait.rb +9 -10
  29. data/lib/carbon/concrete/item/trait/expectation.rb +0 -0
  30. data/lib/carbon/concrete/request.rb +137 -136
  31. data/lib/carbon/concrete/type.rb +126 -21
  32. data/lib/carbon/concrete/type/function.rb +26 -10
  33. data/lib/carbon/concrete/type/generic.rb +19 -3
  34. data/lib/carbon/concrete/type/name.rb +0 -0
  35. data/lib/carbon/concrete/type/parse.rb +1 -0
  36. data/lib/carbon/concrete/type/part.rb +9 -1
  37. data/lib/carbon/core.rb +6 -1
  38. data/lib/carbon/core/int.rb +0 -0
  39. data/lib/carbon/core/integer.rb +0 -0
  40. data/lib/carbon/core/integer/cast.rb +0 -0
  41. data/lib/carbon/core/integer/math.rb +0 -0
  42. data/lib/carbon/core/integer/misc.rb +17 -1
  43. data/lib/carbon/core/integer/pole.rb +0 -0
  44. data/lib/carbon/core/integer/ship.rb +8 -4
  45. data/lib/carbon/core/integer/sign.rb +0 -0
  46. data/lib/carbon/core/integer/type.rb +0 -0
  47. data/lib/carbon/core/integer/zero.rb +0 -0
  48. data/lib/carbon/core/main.rb +50 -0
  49. data/lib/carbon/core/pointer.rb +0 -0
  50. data/lib/carbon/core/pointer/access.rb +1 -1
  51. data/lib/carbon/core/pointer/cast.rb +0 -0
  52. data/lib/carbon/core/pointer/math.rb +14 -0
  53. data/lib/carbon/core/pointer/memory.rb +2 -4
  54. data/lib/carbon/core/pointer/type.rb +0 -0
  55. data/lib/carbon/core/void.rb +20 -0
  56. data/lib/carbon/counter.rb +27 -0
  57. data/lib/carbon/errors.rb +13 -0
  58. data/lib/carbon/tacky.rb +0 -0
  59. data/lib/carbon/tacky/block.rb +0 -0
  60. data/lib/carbon/tacky/builder.rb +3 -6
  61. data/lib/carbon/tacky/context.rb +4 -10
  62. data/lib/carbon/tacky/function.rb +0 -24
  63. data/lib/carbon/tacky/instruction.rb +2 -5
  64. data/lib/carbon/tacky/instruction/generation.rb +19 -41
  65. data/lib/carbon/tacky/parameter.rb +0 -0
  66. data/lib/carbon/tacky/reference.rb +0 -0
  67. data/lib/carbon/tacky/typed.rb +0 -0
  68. data/lib/carbon/tacky/value.rb +0 -2
  69. data/lib/carbon/version.rb +1 -1
  70. data/scripts/core.rb +0 -0
  71. data/scripts/test.rb +5 -7
  72. metadata +9 -4
  73. data/lib/carbon/tacky/instruction/dependencies.rb +0 -33
  74. data/lib/carbon/tacky/instruction/typeof.rb +0 -25
File without changes
@@ -8,30 +8,19 @@ module Carbon
8
8
  # items need to share to be compatible with the index. This module is
9
9
  # the bases of the build system in the {Concrete} module.
10
10
  module Base
11
- # Returns the interned name of the item. This contains no generic
12
- # information. Interned names are mostly used to match generic
13
- # information laden types with the items that define them; for example,
14
- # it is meant to be used to match the type
15
- # `Carbon::Pointer<Carbon::String>` to the module `Carbon::Pointer<T>`.
16
- # The common parts of both is the module name that the type uses - or,
17
- # rather, everything but the generic information. Interned names
18
- # discard the information that is unneeded for matching the two.
19
- #
20
- # This methodology has the downside that a module with the same name
21
- # as the base of a generic module cannot exist; however, allowing such
22
- # would ultimately be confusing.
11
+ # Returns the type of the item. This is the full {Concrete::Type}.
23
12
  #
24
13
  # @api public
25
14
  # @example For a module.
26
15
  # item.name # => "Carbon::Pointer<T>"
27
- # item.intern # => "Carbon::Pointer"
16
+ # item.type # => #<Carbon::Type Carbon::Pointer<T>>
28
17
  # @example For a function.
29
18
  # item.name
30
19
  # # => "Carbon::Pointer<T>.+(Carbon::Pointer<T>, Carbon::Int32)"
31
20
  # item.intern
32
- # # => "Carbon::Pointer.+(Carbon::Pointer, Carbon::Int32)"
33
- # @return [::String] The interned name.
34
- attr_reader :intern
21
+ # # => #<Carbon::Type Carbon::Pointer.+(Carbon::Pointer, Carbon::Int32)>
22
+ # @return [Concrete::Type] The type.
23
+ attr_reader :type
35
24
 
36
25
  # Returns the full name of the item. This can include generic
37
26
  # information.
@@ -69,26 +58,24 @@ module Carbon
69
58
  # @param type [Concrete::Type] The type.
70
59
  # @return [{::Symbol => ::Object}]
71
60
  def self.from(type)
72
- { module: type }
61
+ { type: type }
73
62
  end
74
63
 
75
64
  # Compares this item to another object. If the other object _is_ this
76
- # item, then it returns true; otherwise, if the other object is an
77
- # item, and the other object's {#intern} is equal to this object's
78
- # {#intern}, then it returns true; otherwise, it returns false.
65
+ # item, then it returns true; otherwise, it returns false.
79
66
  #
80
67
  # @api public
81
68
  # @example
82
- # first.intern # => "Carbon::Pointer"
83
- # second.intern # => "Carbon::Pointer"
69
+ # first.type # => "Carbon::Pointer<T>"
70
+ # second.type # => "Carbon::Pointer<T>"
84
71
  # first == first # => true
85
72
  # first == second # => true
86
73
  # second == second # => true
87
74
  # second == first # => true
88
- # @param other [Base, ::String, ::Object] The object to compare.
75
+ # @param other [Base, ::Object] The object to compare.
89
76
  # @return [::Boolean] The result of comparison.
90
77
  def ==(other)
91
- equal?(other) || (other.is_a?(Base) && intern == other.intern)
78
+ equal?(other)
92
79
  end
93
80
  alias_method :eql?, :==
94
81
 
@@ -98,7 +85,7 @@ module Carbon
98
85
  # @api private
99
86
  # @return [Numeric]
100
87
  def hash
101
- intern.hash
88
+ type.hash
102
89
  end
103
90
 
104
91
  # rubocop:disable Lint/UnusedMethodArgument
@@ -150,10 +137,10 @@ module Carbon
150
137
 
151
138
  def forced_corrected_dependencies(request, &block)
152
139
  # Array<Type::Generic> -> Array<(Type::Generic, Numeric)> ->
153
- # Array<(String, Type::Generic)> -> {String => Type::Generic}
140
+ # Array<(Type, Type)> -> {Type => Type}
154
141
  mapping = generics
155
142
  .each_with_index
156
- .map { |gen, i| [gen.name.intern, request.generics[i]] }
143
+ .map { |gen, i| [gen.name, request.generics[i].name] }
157
144
  .to_h
158
145
 
159
146
  dependencies.map { |dep| dep.sub(mapping) }.each(&block)
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require "carbon/concrete/item/class/element"
5
+
6
+ module Carbon
7
+ module Concrete
8
+ module Item
9
+ # A struct data type. This is normally a sequence of elements that are
10
+ # stored sequentially in memory. Each element has a name, to reference
11
+ # which position, and a type. All references to this data type in memory
12
+ # are through pointers.
13
+ #
14
+ # @api private
15
+ # @note
16
+ # **This class is frozen upon initialization.** This means that any
17
+ # attempt to modify it will result in an error. In most cases, the
18
+ # attributes on this class will also be frozen, as well.
19
+ class Class
20
+ include Data
21
+
22
+ # (see Item::Base.from)
23
+ def self.from(type)
24
+ { type: type, implements: [], elements: [] }
25
+ end
26
+
27
+ # Initialize the struct with the given data.
28
+ #
29
+ # @param data [::Hash] The data to initialize with.
30
+ # @option data [Type] :module The name of the struct.
31
+ # @option data [<::String, Type>] :elements The elements of
32
+ # the struct.
33
+ # @option data [<Type>] :implements The traits that this
34
+ # data type implements.
35
+ def initialize(data)
36
+ @type = data.fetch(:type)
37
+ @generics = @type.generics
38
+ @name = @type.to_s
39
+ @extern = data[:extern]
40
+
41
+ @implements = Set.new(data.fetch(:implements))
42
+ @dependencies = Set.new
43
+
44
+ derive_elements(data.fetch(:elements))
45
+ derive_dependencies
46
+ deep_freeze!
47
+ end
48
+
49
+ # (see Base#call)
50
+ def call(build, generics)
51
+ full = @type.sub(generics)
52
+ elements = @elements.map(&:type).map { |t| t.sub(generics) }
53
+ .map { |t| build.fetch(t).last }
54
+ name = @extern || full.to_s
55
+ build.items[full] =
56
+ [self, ::LLVM::Type.struct(elements, false, name).pointer]
57
+ end
58
+
59
+ private
60
+
61
+ def derive_elements(elements)
62
+ @elements = elements.map { |e| Element.new(*e) }
63
+ end
64
+
65
+ def derive_dependencies
66
+ @dependencies.merge(@elements.map(&:type))
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Concrete
6
+ module Item
7
+ class Class
8
+ # An element of a class. Contains name and type information, and
9
+ # that's it.
10
+ #
11
+ # @api private
12
+ # @note
13
+ # **This class is frozen upon initialization.** This means that any
14
+ # attempt to modify it will result in an error. In most cases, the
15
+ # attributes on this class will also be frozen, as well.
16
+ class Element
17
+ # The name of the element.
18
+ #
19
+ # @return [::String]
20
+ attr_reader :name
21
+
22
+ # The type of the element.
23
+ #
24
+ # @return [Type]
25
+ attr_reader :type
26
+
27
+ # Initialize the element with the given name and type.
28
+ #
29
+ # @see #name
30
+ # @see #type
31
+ # @param name [::String] The name of the element.
32
+ # @param type [Type] The type of the element.
33
+ def initialize(name, type)
34
+ @name = name
35
+ @type = type
36
+ deep_freeze!
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
File without changes
@@ -24,35 +24,35 @@ module Carbon
24
24
  attr_reader :return
25
25
  attr_reader :definition
26
26
 
27
-
28
27
  # (see Item::Base.from)
29
28
  def self.from(type)
30
29
  {
31
- module: type.to_module,
32
- internal: type.name.function.name,
33
- arguments: type.name.function.parameters,
30
+ type: type,
34
31
  generics: type.generics,
35
- definition: Tacky::Function.new(type.name.function.parameters)
32
+ internal: type.function.name,
33
+ parameters: type.function.parameters,
34
+ definition: Tacky::Function.new(type.function.parameters)
36
35
  }
37
36
  end
38
37
 
39
38
  def initialize(data)
40
- @module = data.fetch(:module)
41
- @internal = data.fetch(:internal)
42
- @parameters = data.fetch(:arguments) { data.fetch(:parameters) }
39
+ @type = data.fetch(:type)
40
+ @internal = data.fetch(:internal) { @type.function.name }
41
+ @parameters = data.fetch(:parameters) { @type.function.parameters }
43
42
  @definition = data.fetch(:definition)
44
- @generics = data.fetch(:generics) { @module.generics }
43
+ @generics = data.fetch(:generics) { @type.generics }
45
44
  @return = data.fetch(:return)
45
+ @extern = data[:extern]
46
+ @name = @type.to_s
46
47
 
47
- derive_name
48
48
  derive_dependencies
49
49
  deep_freeze!
50
50
  end
51
51
 
52
52
  def define(index)
53
53
  if @definition.is_a?(::Proc)
54
- Function.from(func)
55
- .merge(definition: @definition.call(index), return: @return)
54
+ Function.new(Function.from(@type)
55
+ .merge(definition: @definition.call(index), return: @return))
56
56
  else
57
57
  self
58
58
  end
@@ -60,47 +60,43 @@ module Carbon
60
60
 
61
61
  # (see Base#call)
62
62
  def call(build, generics)
63
- value = case @definition
64
- when Tacky::Function
65
- build_function_intern(build, generics)
66
- when ::String, ::Symbol
67
- build_function_extern(build, generics)
68
- else fail ArgumentError,
69
- "Unknown definition #{@definition.class}"
70
- end
71
-
72
- build.functions[@module.sub(generics)] = value
63
+ case @definition
64
+ when Tacky::Function
65
+ build_function_intern(build, generics)
66
+ when ::String, ::Symbol
67
+ build_function_extern(build, generics)
68
+ else fail ArgumentError,
69
+ "Unknown definition #{@definition.class}"
70
+ end
73
71
  end
74
72
 
75
73
  private
76
74
 
77
- # rubocop:disable Metrics/AbcSize
78
75
  def build_function_intern(build, generics)
79
- full = @full.sub(generics)
76
+ full = @type.sub(generics)
80
77
  params = @parameters
81
- .map { |p| build.types.fetch(p.sub(generics)).last }
82
- ret = build.types.fetch(@return.sub(generics)).last
83
- func = build.module.functions.add(full, params, ret)
78
+ .map { |p| build.fetch(p.sub(generics)).last }
79
+ ret = build.fetch(@return.sub(generics)).last
80
+ func = build.module.functions.add(@extern || full, params, ret)
84
81
  @definition.call(func, build, generics)
85
- build.functions[full] = [self, func]
82
+ build.items[full] = [self, func]
86
83
  end
87
- # rubocop:enable Metrics/AbcSize
88
84
 
89
- # @todo TODO: finish.
90
85
  def build_function_extern(build, generics)
86
+ full = @type.sub(generics)
87
+ params = @parameters
88
+ .map { |p| build.fetch(p.sub(generics)).last }
89
+ ret = build.fetch(@return.sub(generics)).last
90
+ func = build.module.functions.add(@definition, params, ret)
91
+ build.items[full] = [self, func]
91
92
  end
92
-
93
- def derive_name
94
- @full = @module.call(@internal, @parameters)
95
- @intern = @full.intern
96
- @name = @full.to_s
97
- end
93
+ # rubocop:enable Metrics/AbcSize
98
94
 
99
95
  def derive_dependencies
100
96
  @dependencies = Set.new
101
- @dependencies << @return.to_request
102
- @dependencies.merge(@parameters.map(&:to_request))
103
- @dependencies.merge(@definition.dependencies.map(&:to_request)) if \
97
+ @dependencies << @return
98
+ @dependencies.merge(@parameters)
99
+ @dependencies.merge(@definition.dependencies) if \
104
100
  @definition.is_a?(Tacky::Function)
105
101
  end
106
102
  end
@@ -26,7 +26,7 @@ module Carbon
26
26
 
27
27
  # (see Item::Base.from)
28
28
  def self.from(type)
29
- { module: type, implements: [] }
29
+ { type: type, implements: [] }
30
30
  end
31
31
 
32
32
  # Initialize the internal data type. Internal data types may not have
@@ -34,11 +34,11 @@ module Carbon
34
34
  # implement traits.
35
35
  #
36
36
  # @param data [::Hash] The options for the internal data type.
37
- # @option data [Type] :module The module of the internal data type.
37
+ # @option data [Type] :type The module of the internal data type.
38
38
  # @option data [::String, ::Symbol] :kind The kind of the internal data
39
- # type. Valid values are `:integer`, `:pointer`, `:int_pointer`,
40
- # `:ary_pointer`, or the string version of any of those. This
41
- # controls the underlying LLVM type of the internal data type.
39
+ # type. Valid values are `:integer`, `:pointer`, `:void`, or the
40
+ # string version of any of those. This controls the underlying LLVM
41
+ # type of the internal data type.
42
42
  # @option data [::String, ::Numeric, #to_i] :size The size of the
43
43
  # internal data type. For integers, it is the number of bits in the
44
44
  # integer; for pointers, it is the number of bits of the element it
@@ -46,36 +46,34 @@ module Carbon
46
46
  # @option data [<Type>] :implements ([]) The types that the
47
47
  # internal data type implements.
48
48
  def initialize(data)
49
- @module = data.fetch(:module)
50
- @kind = data.fetch(:kind) { data.fetch(:type) }.to_s
49
+ @type = data.fetch(:type)
50
+ @kind = data.fetch(:kind).to_s
51
51
  @size = data.fetch(:size, 8)
52
+ @extern = data[:extern]
52
53
 
53
- @generics = @module.generics
54
+ @generics = @type.generics
54
55
  @implements = Set.new(data.fetch(:implements, []))
55
- @dependencies = Set.new
56
+ @dependencies = Set.new(@generics.map(&:name))
57
+ @name = @module.to_s
56
58
 
57
- derive_name
58
59
  deep_freeze!
59
60
  end
60
61
 
61
62
  # (see Base#call)
62
63
  def call(build, generics)
64
+ full = @type.sub(generics)
63
65
  value = case @kind.to_s
64
66
  when "integer" then TYPE.call(@size)
67
+ when "void" then ::LLVM::Type.void
68
+ when "opaque"
69
+ ::LLVM::Type.struct([], false, @extern || full.to_s)
65
70
  when "pointer"
66
- type = build.types.fetch(generics.fetch("T"))
71
+ type = build.fetch(generics.fetch(Carbon::Type("T")))
67
72
  type.last.pointer
68
73
  else fail ArgumentError, "Unknown kind #{@kind}"
69
74
  end
70
75
 
71
- build.types[@module.sub(generics)] = [self, value]
72
- end
73
-
74
- private
75
-
76
- def derive_name
77
- @intern = @module.intern
78
- @name = @module.to_s
76
+ build.items[@type.sub(generics)] = [self, value]
79
77
  end
80
78
  end
81
79
  end
@@ -20,7 +20,7 @@ module Carbon
20
20
 
21
21
  # (see Item::Base.from)
22
22
  def self.from(type)
23
- { module: type, implements: [], elements: [] }
23
+ { type: type, implements: [], elements: [] }
24
24
  end
25
25
 
26
26
  # Initialize the struct with the given data.
@@ -32,10 +32,10 @@ module Carbon
32
32
  # @option data [<Type>] :implements The traits that this
33
33
  # data type implements.
34
34
  def initialize(data)
35
- @module = data.fetch(:module)
36
- @generics = @module.generics
37
- @intern = @module.intern
38
- @name = @module.to_s
35
+ @type = data.fetch(:type)
36
+ @generics = @type.generics
37
+ @name = @type.to_s
38
+ @extern = data[:extern]
39
39
 
40
40
  @implements = Set.new(data.fetch(:implements))
41
41
  @dependencies = Set.new
@@ -47,7 +47,12 @@ module Carbon
47
47
 
48
48
  # (see Base#call)
49
49
  def call(build, generics)
50
- super # TODO: fixme.
50
+ full = @type.sub(generics)
51
+ elements = @elements.map(&:type).map { |t| t.sub(generics) }
52
+ .map { |t| build.fetch(t).last }
53
+ name = @extern || full.to_s
54
+ build.items[full] =
55
+ [self, ::LLVM::Type.struct(elements, false, name)]
51
56
  end
52
57
 
53
58
  private
@@ -57,7 +62,7 @@ module Carbon
57
62
  end
58
63
 
59
64
  def derive_dependencies
60
- @dependencies.merge(@elements.map { |e| e.type.to_request })
65
+ @dependencies.merge(@elements.map(&:type))
61
66
  end
62
67
  end
63
68
  end