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.
- 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
|