carbon-core 0.1.0

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