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.
- checksums.yaml +4 -4
- data/.gitattributes +17 -0
- data/.gitignore +0 -0
- data/.rspec +0 -0
- data/.rubocop.yml +0 -0
- data/.travis.yml +0 -0
- data/.yardopts +0 -0
- data/CODE_OF_CONDUCT.md +0 -0
- data/Gemfile +0 -0
- data/LICENSE.txt +0 -0
- data/README.md +0 -0
- data/Rakefile +0 -0
- data/Vagrantfile +0 -0
- data/carbon.gemspec +0 -0
- data/lib/carbon.rb +25 -1
- data/lib/carbon/concrete.rb +4 -2
- data/lib/carbon/concrete/build.rb +21 -13
- data/lib/carbon/concrete/index.rb +53 -159
- data/lib/carbon/concrete/item.rb +0 -0
- data/lib/carbon/concrete/item/base.rb +14 -27
- data/lib/carbon/concrete/item/class.rb +71 -0
- data/lib/carbon/concrete/item/class/element.rb +42 -0
- data/lib/carbon/concrete/item/data.rb +0 -0
- data/lib/carbon/concrete/item/function.rb +35 -39
- data/lib/carbon/concrete/item/internal.rb +17 -19
- data/lib/carbon/concrete/item/struct.rb +12 -7
- data/lib/carbon/concrete/item/struct/element.rb +0 -0
- data/lib/carbon/concrete/item/trait.rb +9 -10
- data/lib/carbon/concrete/item/trait/expectation.rb +0 -0
- data/lib/carbon/concrete/request.rb +137 -136
- data/lib/carbon/concrete/type.rb +126 -21
- data/lib/carbon/concrete/type/function.rb +26 -10
- data/lib/carbon/concrete/type/generic.rb +19 -3
- data/lib/carbon/concrete/type/name.rb +0 -0
- data/lib/carbon/concrete/type/parse.rb +1 -0
- data/lib/carbon/concrete/type/part.rb +9 -1
- data/lib/carbon/core.rb +6 -1
- data/lib/carbon/core/int.rb +0 -0
- data/lib/carbon/core/integer.rb +0 -0
- data/lib/carbon/core/integer/cast.rb +0 -0
- data/lib/carbon/core/integer/math.rb +0 -0
- data/lib/carbon/core/integer/misc.rb +17 -1
- data/lib/carbon/core/integer/pole.rb +0 -0
- data/lib/carbon/core/integer/ship.rb +8 -4
- data/lib/carbon/core/integer/sign.rb +0 -0
- data/lib/carbon/core/integer/type.rb +0 -0
- data/lib/carbon/core/integer/zero.rb +0 -0
- data/lib/carbon/core/main.rb +50 -0
- data/lib/carbon/core/pointer.rb +0 -0
- data/lib/carbon/core/pointer/access.rb +1 -1
- data/lib/carbon/core/pointer/cast.rb +0 -0
- data/lib/carbon/core/pointer/math.rb +14 -0
- data/lib/carbon/core/pointer/memory.rb +2 -4
- data/lib/carbon/core/pointer/type.rb +0 -0
- data/lib/carbon/core/void.rb +20 -0
- data/lib/carbon/counter.rb +27 -0
- data/lib/carbon/errors.rb +13 -0
- data/lib/carbon/tacky.rb +0 -0
- data/lib/carbon/tacky/block.rb +0 -0
- data/lib/carbon/tacky/builder.rb +3 -6
- data/lib/carbon/tacky/context.rb +4 -10
- data/lib/carbon/tacky/function.rb +0 -24
- data/lib/carbon/tacky/instruction.rb +2 -5
- data/lib/carbon/tacky/instruction/generation.rb +19 -41
- data/lib/carbon/tacky/parameter.rb +0 -0
- data/lib/carbon/tacky/reference.rb +0 -0
- data/lib/carbon/tacky/typed.rb +0 -0
- data/lib/carbon/tacky/value.rb +0 -2
- data/lib/carbon/version.rb +1 -1
- data/scripts/core.rb +0 -0
- data/scripts/test.rb +5 -7
- metadata +9 -4
- data/lib/carbon/tacky/instruction/dependencies.rb +0 -33
- data/lib/carbon/tacky/instruction/typeof.rb +0 -25
data/lib/carbon/concrete/item.rb
CHANGED
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
|
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.
|
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
|
-
# # =>
|
33
|
-
# @return [::
|
34
|
-
attr_reader :
|
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
|
-
{
|
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,
|
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.
|
83
|
-
# second.
|
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, ::
|
75
|
+
# @param other [Base, ::Object] The object to compare.
|
89
76
|
# @return [::Boolean] The result of comparison.
|
90
77
|
def ==(other)
|
91
|
-
equal?(other)
|
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
|
-
|
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<(
|
140
|
+
# Array<(Type, Type)> -> {Type => Type}
|
154
141
|
mapping = generics
|
155
142
|
.each_with_index
|
156
|
-
.map { |gen, i| [gen.name
|
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
|
-
|
32
|
-
internal: type.name.function.name,
|
33
|
-
arguments: type.name.function.parameters,
|
30
|
+
type: type,
|
34
31
|
generics: type.generics,
|
35
|
-
|
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
|
-
@
|
41
|
-
@internal = data.fetch(:internal)
|
42
|
-
@parameters = data.fetch(:
|
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) { @
|
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(
|
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
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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 = @
|
76
|
+
full = @type.sub(generics)
|
80
77
|
params = @parameters
|
81
|
-
.map { |p| build.
|
82
|
-
ret = build.
|
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.
|
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
|
102
|
-
@dependencies.merge(@parameters
|
103
|
-
@dependencies.merge(@definition.dependencies
|
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
|
-
{
|
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] :
|
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`, `:
|
40
|
-
#
|
41
|
-
#
|
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
|
-
@
|
50
|
-
@kind = data.fetch(:kind)
|
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 = @
|
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.
|
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.
|
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
|
-
{
|
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
|
-
@
|
36
|
-
@generics = @
|
37
|
-
@
|
38
|
-
@
|
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
|
-
|
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
|
65
|
+
@dependencies.merge(@elements.map(&:type))
|
61
66
|
end
|
62
67
|
end
|
63
68
|
end
|