carbon-core 0.1.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 (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +38 -0
  5. data/.travis.yml +4 -0
  6. data/.yardopts +1 -0
  7. data/CODE_OF_CONDUCT.md +49 -0
  8. data/Gemfile +11 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +41 -0
  11. data/Rakefile +14 -0
  12. data/carbon.gemspec +30 -0
  13. data/lib/carbon.rb +54 -0
  14. data/lib/carbon/concrete.rb +43 -0
  15. data/lib/carbon/concrete/build.rb +63 -0
  16. data/lib/carbon/concrete/index.rb +324 -0
  17. data/lib/carbon/concrete/item.rb +37 -0
  18. data/lib/carbon/concrete/item/base.rb +153 -0
  19. data/lib/carbon/concrete/item/data.rb +22 -0
  20. data/lib/carbon/concrete/item/function.rb +97 -0
  21. data/lib/carbon/concrete/item/internal.rb +83 -0
  22. data/lib/carbon/concrete/item/struct.rb +65 -0
  23. data/lib/carbon/concrete/item/struct/element.rb +42 -0
  24. data/lib/carbon/concrete/item/trait.rb +72 -0
  25. data/lib/carbon/concrete/item/trait/expectation.rb +55 -0
  26. data/lib/carbon/concrete/request.rb +137 -0
  27. data/lib/carbon/concrete/type.rb +260 -0
  28. data/lib/carbon/concrete/type/function.rb +91 -0
  29. data/lib/carbon/concrete/type/generic.rb +118 -0
  30. data/lib/carbon/concrete/type/name.rb +147 -0
  31. data/lib/carbon/concrete/type/parse.rb +172 -0
  32. data/lib/carbon/concrete/type/part.rb +100 -0
  33. data/lib/carbon/core.rb +61 -0
  34. data/lib/carbon/core/int.rb +87 -0
  35. data/lib/carbon/core/integer.rb +109 -0
  36. data/lib/carbon/core/integer/cast.rb +83 -0
  37. data/lib/carbon/core/integer/math.rb +198 -0
  38. data/lib/carbon/core/integer/misc.rb +145 -0
  39. data/lib/carbon/core/integer/pole.rb +133 -0
  40. data/lib/carbon/core/integer/ship.rb +71 -0
  41. data/lib/carbon/core/integer/sign.rb +52 -0
  42. data/lib/carbon/core/integer/type.rb +42 -0
  43. data/lib/carbon/core/integer/zero.rb +52 -0
  44. data/lib/carbon/core/pointer.rb +54 -0
  45. data/lib/carbon/core/pointer/access.rb +123 -0
  46. data/lib/carbon/core/pointer/cast.rb +55 -0
  47. data/lib/carbon/core/pointer/math.rb +187 -0
  48. data/lib/carbon/core/pointer/memory.rb +85 -0
  49. data/lib/carbon/core/pointer/type.rb +23 -0
  50. data/lib/carbon/tacky.rb +21 -0
  51. data/lib/carbon/tacky/block.rb +96 -0
  52. data/lib/carbon/tacky/builder.rb +310 -0
  53. data/lib/carbon/tacky/context.rb +66 -0
  54. data/lib/carbon/tacky/function.rb +137 -0
  55. data/lib/carbon/tacky/instruction.rb +170 -0
  56. data/lib/carbon/tacky/parameter.rb +23 -0
  57. data/lib/carbon/tacky/reference.rb +23 -0
  58. data/lib/carbon/tacky/value.rb +40 -0
  59. data/lib/carbon/version.rb +9 -0
  60. metadata +186 -0
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Core
6
+ # Defines the pointer type and functions for the Carbon Core library.
7
+ #
8
+ # @api private
9
+ module Pointer
10
+ # The pointer type name. This is kept here to provide a shortcut to
11
+ # the pointer type.
12
+ #
13
+ # @return [Concrete::Type]
14
+ PTYPE = Carbon::Type("Carbon::Pointer<T>")
15
+
16
+ # The pointer generic type name. This is kept here to provide a
17
+ # shortcut.
18
+ #
19
+ # @return [Concrete::Type]
20
+ PTYPEGEN = PTYPE.generics[0].name
21
+
22
+ require "carbon/core/pointer/access"
23
+ require "carbon/core/pointer/cast"
24
+ require "carbon/core/pointer/math"
25
+ require "carbon/core/pointer/memory"
26
+ require "carbon/core/pointer/type"
27
+
28
+ extend Pointer::Access
29
+ extend Pointer::Cast
30
+ extend Pointer::Math
31
+ extend Pointer::Memory
32
+ extend Pointer::Type
33
+
34
+ # Defines the pointer type and all of the pointer functions.
35
+ #
36
+ # @see #define_pointer_type
37
+ # @see .define_pointer_functions
38
+ # @return [self]
39
+ def self.define_pointer
40
+ define_pointer_type
41
+ define_pointer_functions
42
+ self
43
+ end
44
+
45
+ # Defines all of the pointer
46
+ def self.define_pointer_functions
47
+ define_math_functions
48
+ define_cast_functions
49
+ define_memory_functions
50
+ define_access_functions
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,123 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ # rubocop:disable Metrics/LineLength
4
+
5
+ module Carbon
6
+ module Core
7
+ module Pointer
8
+ # Methods that perform accesses on pointers. This is essentially
9
+ # dereferencing and indexing. This defines the following functions:
10
+ #
11
+ # - `Carbon::Pointer<T>.value(self): T`
12
+ # - `Carbon::Pointer<T>.value=(self, value: T): T`
13
+ # - `Carbon::Pointer<T>.[]<I: Carbon::Numeric>(self, index: I): T`
14
+ # - `Carbon::Pointer<T>.[]=<I: Carbon::Numeric>(self, index: I, value: T): T`
15
+ #
16
+ # @api private
17
+ module Access
18
+ # Define all of the access functions. This iterates over all of the
19
+ # integers, defining the array get/set functions in terms of each
20
+ # integer type. It then defines the value get/set functions.
21
+ #
22
+ # @return [void]
23
+ def define_access_functions
24
+ Ints.each do |int|
25
+ next if int.size == 1
26
+ define_array_get_function(int)
27
+ define_array_set_function(int)
28
+ end
29
+ define_value_get_function
30
+ define_value_set_function
31
+ end
32
+
33
+ # Defines the value set function. This function (named `value=`) sets
34
+ # the value at the pointer. This is the same as calling the array
35
+ # set function with an index of zero (0).
36
+ #
37
+ # @return [void]
38
+ def define_value_set_function
39
+ function_name = PTYPE.call(:value=, [PTYPE, PTYPEGEN])
40
+ Core.define(function: function_name) do |function|
41
+ function[:return] = PTYPEGEN
42
+ define_value_set_definition(function[:definition])
43
+ end
44
+ end
45
+
46
+ # Defines the value get function. This function (named `value`) gets
47
+ # the value at the pointer. This is the same as calling the array
48
+ # get function with an index of zero (0).
49
+ #
50
+ # @return [void]
51
+ def define_value_get_function
52
+ function_name = PTYPE.call(:value, [PTYPE])
53
+ Core.define(function: function_name) do |function|
54
+ function[:return] = PTYPEGEN
55
+ define_value_get_definition(function[:definition])
56
+ end
57
+ end
58
+
59
+ # Defines the array set function. This function (named `[]=`) sets
60
+ # the value a given distance away from the pointer.
61
+ #
62
+ # @param int [Core::Int] The integer type for the index.
63
+ # @return [void]
64
+ def define_array_set_function(int)
65
+ function_name = PTYPE.call(:[]=, [PTYPE, int.name, PTYPEGEN])
66
+ Core.define(function: function_name) do |function|
67
+ function[:return] = PTYPEGEN
68
+ define_array_set_definition(int, function[:definition])
69
+ end
70
+ end
71
+
72
+ # Defines the array get function. This function (named `[]`) gets the
73
+ # value at a given distance away from the pointer.
74
+ #
75
+ # @param int [Core::Int] The integer type for the index.
76
+ # @return [void]
77
+ def define_array_get_function(int)
78
+ function_name = PTYPE.call(:[], [PTYPE, int.name])
79
+ Core.define(function: function_name) do |function|
80
+ function[:return] = PTYPEGEN
81
+ define_array_get_definition(int, function[:definition])
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def define_array_set_definition(_int, definition)
88
+ entry = definition.add("entry").build
89
+ this, index, value = definition.params
90
+ this.name, index.name, value.name = %w(self index value)
91
+
92
+ entry.store(entry.gep(this, index), value)
93
+ entry.ret(value)
94
+ end
95
+
96
+ def define_array_get_definition(_int, definition)
97
+ entry = definition.add("entry").build
98
+ this, index = definition.params
99
+ this.name, index.name = %w(self index)
100
+
101
+ entry.ret(entry.load(entry.gep(this, index)))
102
+ end
103
+
104
+ def define_value_set_definition(definition)
105
+ entry = definition.add("entry").build
106
+ this, value = definition.params
107
+ this.name, value.name = %w(self value)
108
+
109
+ entry.store(this, value)
110
+ entry.ret(value)
111
+ end
112
+
113
+ def define_value_get_definition(definition)
114
+ entry = definition.add("entry").build
115
+ this = definition.params[0]
116
+ this.name = "self"
117
+
118
+ entry.ret(entry.load(this))
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Core
6
+ module Pointer
7
+ # Performs casting for pointers. This converts them into an integer
8
+ # for use in the program. This defines the following functions on the
9
+ # pointer type:
10
+ #
11
+ # - `.to-int64(self): Carbon::Int64`
12
+ # - `.to-uint64(self): Carbon::UInt64`
13
+ # - `.to-int32(self): Carbon::Int32`
14
+ # - `.to-uint32(self): Carbon::UInt32`
15
+ # - `.to-int16(self): Carbon::Int16`
16
+ # - `.to-uint16(self): Carbon::UInt16`
17
+ # - `.to-int8(self): Carbon::Int8`
18
+ # - `.to-uint8(self): Carbon::UInt8`
19
+ module Cast
20
+ # Defines all of the cast functions for all of the integer types.
21
+ #
22
+ # @see #define_cast_function
23
+ # @return [void]
24
+ def define_cast_functions
25
+ Ints.each do |int|
26
+ next if int.size == 1
27
+ define_cast_function(int)
28
+ end
29
+ end
30
+
31
+ # Defines a cast function for a given integer type.
32
+ #
33
+ # @param int [Core::Int] The integer to cast the pointer to.
34
+ # @return [void]
35
+ def define_cast_function(int)
36
+ function_name = PTYPE.call(int.cast, [PTYPE])
37
+ Core.define(function: function_name) do |function|
38
+ function[:return] = int.name
39
+ define_cast_definition(int, function[:definition])
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def define_cast_definition(int, definition)
46
+ entry = definition.add("entry").build
47
+ this = definition.params[0]
48
+ this.name = "self"
49
+
50
+ entry.ret(entry.ptr2int(this, int.name))
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,187 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Core
6
+ module Pointer
7
+ # Defines pointer arithmatic. This allows for addition and subtraction,
8
+ # as well as comparison. This module defines the following functions:
9
+ #
10
+ # - `.+<N: Carbon::Numeric>(self, other: N): self`
11
+ # - `.-<N: Carbon::Numeric>(self, other: N): self`
12
+ # - `.<<N: Carbon::Numeric>(self, other: N): Carbon::Boolean`
13
+ # - `.><N: Carbon::Numeric>(self, other: N): Carbon::Boolean`
14
+ # - `.<=<N: Carbon::Numeric>(self, other: N): Carbon::Boolean`
15
+ # - `.>=<N: Carbon::Numeric>(self, other: N): Carbon::Boolean`
16
+ # - `.<=><N: Carbon::Numeric>(self, other: N): Carbon::Int8`
17
+ # - `.<(self, other: self): Carbon::Boolean`
18
+ # - `.>(self, other: self): Carbon::Boolean`
19
+ # - `.<=(self, other: self): Carbon::Boolean`
20
+ # - `.>=(self, other: self): Carbon::Boolean`
21
+ # - `.<=>(self, other: self): Carbon::Int8`
22
+ #
23
+ # These are defined for all integers except boolean.
24
+ module Math
25
+ # The math operations that can be applied to pointers.
26
+ #
27
+ # @return [<::Symbol>]
28
+ MATH_OPERATIONS = %i(+ -).freeze
29
+
30
+ # The comparison operations that can be applied to pointers.
31
+ #
32
+ # @return [<::Symbol>]
33
+ COMP_OPERATIONS = %i(< > <= >=).freeze
34
+
35
+ # Comprehensively defines all of the math, comparison, and spaceship
36
+ # operations for pointers.
37
+ #
38
+ # @see #define_math_function
39
+ # @see #define_comp_function
40
+ # @see #define_space_function
41
+ # @see #define_comp_pointer_function
42
+ # @see #define_space_pointer_function
43
+ # @return [void]
44
+ def define_math_functions
45
+ Ints.each do |int|
46
+ next if int.size == 1
47
+ MATH_OPERATIONS.each { |op| define_math_function(int, op) }
48
+ COMP_OPERATIONS.each { |op| define_comp_function(int, op) }
49
+ define_space_function(int)
50
+ end
51
+
52
+ COMP_OPERATIONS.each { |op| define_comp_pointer_function(op) }
53
+ define_space_pointer_function
54
+ end
55
+
56
+ # Defines the `<=>` function for two pointers. This returns `-1`,
57
+ # `0`, or `1`, if the receiver is less than, equal to, or greater than
58
+ # the parameter, respectively.
59
+ #
60
+ # @return [void]
61
+ def define_space_pointer_function
62
+ function_name = PTYPE.call(:<=>, [PTYPE, PTYPE])
63
+ Core.define(function: function_name) do |function|
64
+ function[:return] = Carbon::Type("Carbon::Int8")
65
+ define_space_pointer_definition(function[:definition])
66
+ end
67
+ end
68
+
69
+ # Defines a comparison function for two pointers.
70
+ #
71
+ # @param op [::Symbol] The operation that the function performs.
72
+ # This should be one of {COMP_OPERATIONS}.
73
+ # @return [void]
74
+ def define_comp_pointer_function(op)
75
+ function_name = PTYPE.call(op, [PTYPE, PTYPE])
76
+ Core.define(function: function_name) do |function|
77
+ function[:return] = Carbon::Boolean
78
+ define_comp_pointer_definition(op, function[:definition])
79
+ end
80
+ end
81
+
82
+ # Defines the space function (`<=>`) for a pointer and an integer.
83
+ # It returns `-1`, `0`, or `1`, if the receiver is less than, equal to,
84
+ # or greater than the parameter, respectively.
85
+ #
86
+ # @param int [Core::Int] The integer type to compare to.
87
+ # @return [void]
88
+ def define_space_function(int)
89
+ function_name = PTYPE.call(:<=>, [PTYPE, int.name])
90
+ Core.define(function: function_name) do |function|
91
+ function[:return] = Carbon::Type("Carbon::Int8")
92
+ define_space_definition(int, function[:definition])
93
+ end
94
+ end
95
+
96
+ # Defines a given math function on a pointer.
97
+ #
98
+ # @param int [Core::Int] The integer type that the operation uses.
99
+ # @param op [::Symbol] The math operation to perform. This should be
100
+ # one of {MATH_OPERATIONS}.
101
+ # @return [void]
102
+ def define_math_function(int, op)
103
+ function_name = PTYPE.call(op, [PTYPE, int.name])
104
+ Core.define(function: function_name) do |function|
105
+ function[:return] = PTYPE
106
+ define_math_definition(int, op, function[:definition])
107
+ end
108
+ end
109
+
110
+ # Defines a given comparison operation on a pointer.
111
+ #
112
+ # @param int [Core::Int] The integer type that the operation uses.
113
+ # @param op [::Symbol] The comparison operation to perform. This should
114
+ # be one of {COMP_OPERATIONS}.
115
+ def define_comp_function(int, op)
116
+ function_name = PTYPE.call(op, [PTYPE, int.name])
117
+ Core.define(function: function_name) do |function|
118
+ function[:return] = Carbon::Boolean
119
+ define_comp_definition(int, op, function[:definition])
120
+ end
121
+ end
122
+
123
+ private
124
+
125
+ def perform_pointer_cast(entry, params, int)
126
+ this, other = params
127
+ this.name, other.name = %w(self other)
128
+ fname = PTYPE.call(int.cast, [PTYPE])
129
+ thisint = entry.call(fname, this)
130
+ otherint = entry.call(fname, other)
131
+ [thisint, otherint]
132
+ end
133
+
134
+ def define_space_pointer_definition(definition)
135
+ entry = definition.add("entry").build
136
+ params = definition.params
137
+ int = Int.find(sign: :signed, size: 64)
138
+ this, other = perform_pointer_cast(entry, params, int)
139
+
140
+ fname = PTYPE.call(:<=>, [int.name, int.name])
141
+ entry.ret(entry.call(fname, this, other))
142
+ end
143
+
144
+ def define_comp_pointer_definition(op, definition)
145
+ entry = definition.add("entry").build
146
+ params = definition.params
147
+ int = Ints.find { |i| i.sign == :signed && i.size == 64 }
148
+ this, other = perform_pointer_cast(entry, params, int)
149
+ icmp = Integer::Math::COMP_OPERATIONS_MAP.fetch([:signed, op])
150
+
151
+ entry.ret(entry.icmp(icmp, this, other))
152
+ end
153
+
154
+ def define_space_definition(int, definition)
155
+ entry = definition.add("entry").build
156
+ this, other = definition.params
157
+ this.name, other.name = %w(self other)
158
+
159
+ fname = PTYPE.call(int.cast, [PTYPE])
160
+ intptr = entry.call(fname, this)
161
+ fname = PTYPE.call(:<=>, [int.name, int.name])
162
+ entry.ret(entry.call(fname, intptr, other))
163
+ end
164
+
165
+ def define_comp_definition(int, op, definition)
166
+ entry = definition.add("entry").build
167
+ this, other = definition.params
168
+ this.name, other.name = %w(self other)
169
+
170
+ fname = PTYPE.call(int.cast, [PTYPE])
171
+ intptr = entry.call(fname, this)
172
+ icmp = Integer::Math::COMP_OPERATIONS_MAP.fetch([int.sign, op])
173
+ entry.ret(entry.icmp(icmp, intptr, other))
174
+ end
175
+
176
+ def define_math_definition(_int, op, definition)
177
+ entry = definition.add("entry").build
178
+ this, other = definition.params
179
+ this.name, other.name = %w(self other)
180
+ other = entry.mul(other, -1) if op == :-
181
+
182
+ entry.ret(entry.gep(this, other))
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Core
6
+ module Pointer
7
+ # Performs memory operations on a pointer. This is mainly alloc/free.
8
+ # C library functions are included in another module. This defines
9
+ # the following functions on the pointer type:
10
+ #
11
+ # - `.alloc<T: Carbon::Numeric>(size: T): self`
12
+ # - `.free(self): Carbon::Void`
13
+ #
14
+ # These are defined for every integer except boolean.
15
+ module Memory
16
+ # Defines all of the memory functions relative to each integer type.
17
+ #
18
+ # @see #define_alloc_function
19
+ # @see #define_free_function
20
+ # @return [void]
21
+ def define_memory_functions
22
+ Ints.each do |int|
23
+ next if int.size == 1
24
+ define_alloc_function(int)
25
+ end
26
+
27
+ define_free_function
28
+ end
29
+
30
+ # Defines the `alloc` function with the given integer type as the
31
+ # parameter. The `alloc` function allocates a block of memory and
32
+ # returns it as a pointer.
33
+ #
34
+ # @param int [Core::Int] The integer type to be used as a parameter.
35
+ # @return [void]
36
+ def define_alloc_function(int)
37
+ function_name = PTYPE.call(:alloc, [int.name])
38
+ Core.define(function: function_name) do |function|
39
+ function[:return] = PTYPE
40
+ define_alloc_definition(int, function[:definition])
41
+ end
42
+ end
43
+
44
+ # Defines the `free` function. The `free` function frees the current
45
+ # pointer.
46
+ #
47
+ # @return [void]
48
+ def define_free_function
49
+ function_name = PTYPE.call(:free, [PTYPE])
50
+ Core.define(function: function_name) do |function|
51
+ function[:return] = Carbon::Type("Carbon::Void")
52
+ define_free_definition(function[:definition])
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def define_alloc_definition(int, definition)
59
+ entry = definition.add("entry").build
60
+ size = definition.params[0]
61
+ size.name = "size"
62
+
63
+ element = entry.sizeof(PTYPEGEN)
64
+ size = convert_int_size(int, size, entry)
65
+ total = entry.mul(element, size)
66
+ entry.ret(entry.malloc(total))
67
+ end
68
+
69
+ def define_free_definition(definition)
70
+ entry = definition.add("entry").build
71
+ this = definition.params[0]
72
+ this.name = "self"
73
+ entry.free(this)
74
+ entry.ret_void
75
+ end
76
+
77
+ def convert_int_size(int, value, entry)
78
+ size = Int.find(sign: :unsigned, size: 64)
79
+ name = int.name.call(size.cast, [int.name])
80
+ entry.call(name, value)
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end