carbon-core 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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