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,145 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Core
6
+ module Integer
7
+ # Defines a set of miscellaneous functions. These functions are various
8
+ # functions that don't fit in any of the other category. These functions
9
+ # include:
10
+ #
11
+ # - `.next(self): self`
12
+ # - `.succ(self): self`
13
+ # - `.abs(self): self`
14
+ # - `.prev(self): self`
15
+ # - `.pred(self): self`
16
+ # - `.to-bool(self): self`
17
+ # - `.size(): Carbon::UInt32`
18
+ # - `.size(self): Carbon::UInt32`
19
+ #
20
+ # These functions are defined on all of the integer types except boolean.
21
+ # However, `.size` is also defined on boolean.
22
+ #
23
+ # @api private
24
+ module Misc
25
+ # Defines the "to boolean" function for the given integer type. This
26
+ # just returns the result of comparison of the number to zero (returns
27
+ # 0 if the number is zero, 1 otherwise).
28
+ #
29
+ # @param int [Core::Int] The (receiver) value.
30
+ # @return [void]
31
+ def define_bool_function(int)
32
+ function_name = int.name.call("to-bool", [int.name])
33
+ Core.define(function: function_name) do |function|
34
+ function[:return] = int.name
35
+ function[:definition].add("entry").build do |b|
36
+ this = function[:definition].params[0]
37
+ this.name = "self"
38
+ b.ret(b.icmp(:ne, this, 0))
39
+ end
40
+ end
41
+ end
42
+
43
+ # Define the next functions for the given integer type. These
44
+ # functions just return the given number incremented by one. This is
45
+ # implemented without any calls. This function defines both the
46
+ # `.next` and `.succ` functions.
47
+ #
48
+ # @param int [Core::Int] The (receiver) value.
49
+ # @return [void]
50
+ def define_next_function(int)
51
+ %w(next succ).each do |name|
52
+ function_name = int.name.call(name, [int.name])
53
+ Core.define(function: function_name) do |function|
54
+ function[:return] = int.name
55
+ define_next_definition(function[:definition])
56
+ end
57
+ end
58
+ end
59
+
60
+ # Define the previous functions for the given integer type. These
61
+ # functions just return the given number decremented by one. This is
62
+ # implemented without any calls. This function defines both the
63
+ # `.prev` and `.pred` functions.
64
+ #
65
+ # @param int [Core::Int] The (receiver) value.
66
+ # @return [void]
67
+ def define_prev_function(int)
68
+ %w(prev pred).each do |name|
69
+ function_name = int.name.call(name, [int.name])
70
+ Core.define(function: function_name) do |function|
71
+ function[:return] = int.name
72
+ define_prev_definition(function[:definition])
73
+ end
74
+ end
75
+ end
76
+
77
+ # Define the absolute value function. For signed integers, it returns
78
+ # the absolute (positive) value of an integer; for unsigned integers,
79
+ # it returns itself.
80
+ #
81
+ # @param int [Core::Int] The (receiver) value.
82
+ # @return [void]
83
+ def define_iabs_function(int)
84
+ function_name = int.name.call("abs", [int.name])
85
+ Core.define(function: function_name) do |function|
86
+ function[:return] = int.name
87
+ define_iabs_definition(int, function[:definition])
88
+ end
89
+ end
90
+
91
+ # Defines the size function. This returns the size of the integer, in
92
+ # bits.
93
+ #
94
+ # @param int [Core::Int] The (receiver) integer type.
95
+ # @return [void]
96
+ def define_size_function(int)
97
+ [[], [int.name]].each do |args|
98
+ function_name = int.name.call("size", args)
99
+ Core.define(function: function_name) do |function|
100
+ function[:return] = Carbon::Type("Carbon::UInt32")
101
+ define_size_definition(int, function[:definition])
102
+ end
103
+ end
104
+ end
105
+
106
+ private
107
+
108
+ def define_next_definition(definition)
109
+ entry = definition.add("entry").build
110
+ this = definition.params[0]
111
+ this.name = "self"
112
+
113
+ entry.ret(entry.add(this, 1))
114
+ end
115
+
116
+ def define_prev_definition(definition)
117
+ entry = definition.add("entry").build
118
+ this = definition.params[0]
119
+ this.name = "self"
120
+
121
+ entry.ret(entry.sub(this, 1))
122
+ end
123
+
124
+ def define_iabs_definition(int, definition)
125
+ entry = definition.add("entry").build
126
+ this = definition.params[0]
127
+ this.name = "self"
128
+
129
+ if int.sign == :unsigned
130
+ entry.ret(this)
131
+ else
132
+ y = entry.ashr(this, int.size - 1)
133
+ entry.ret(entry.sub(entry.xor(this, y), y))
134
+ end
135
+ end
136
+
137
+ def define_size_definition(int, definition)
138
+ entry = definition.add("entry").build
139
+
140
+ entry.ret(int.size)
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,133 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Core
6
+ module Integer
7
+ # Defines "polarity" functions. This means positive/negative or
8
+ # odd/even. This defines the following functions:
9
+ #
10
+ # - `.positive?(self): Carbon::Boolean`
11
+ # - `.negative?(self): Carbon::Boolean`
12
+ # - `.even?(self): Carbon::Boolean`
13
+ # - `.odd?(self): Carbon::Boolean`
14
+ #
15
+ # These functions are defined on all integer types except boolean.
16
+ # That includes `.positive?` and `.negative?`, which has no meaning on
17
+ # an unisgned integer (see {#define_positive_function} and
18
+ # {#define_negative_function} for how unsigned integers are handled).
19
+ #
20
+ # @api private
21
+ module Pole
22
+ # Defines the positive function. The function (named `positive?`)
23
+ # returns a boolean value; if the receiver is greater than or equal to
24
+ # zero, the function returns `true`; otherwise, the function returns
25
+ # `false`. This provides a special case for unsigned integers: all
26
+ # unsigned integers are always positive, so this function returns
27
+ # `true` for unsigned integers. For signed integers, it checks the
28
+ # sign bit (`lshr %i, (sub %i.size, 1)`).
29
+ #
30
+ # @param int [Core::Int] The (receiver) value.
31
+ # @return [void]
32
+ def define_positive_function(int)
33
+ function_name = int.name.call("positive?", [int.name])
34
+ Core.define(function: function_name) do |function|
35
+ function[:return] = Carbon::Boolean
36
+ define_positive_definition(int, function[:definition])
37
+ end
38
+ end
39
+
40
+ # Defines the negative function. The function (named `negative?`)
41
+ # returns a boolean value; if the receiver is less than zero, the
42
+ # function returns `true`; otherwise, the function returns `false`.
43
+ # This provides a special case for unsigned integers: all unsigned
44
+ # integers are always positive, so this function returns `false` for
45
+ # unsigned integers. For signed integers, it checks the sign bit
46
+ # (`xor (lshr %i, (sub %i.size, 1)), 1`).
47
+ #
48
+ # @param int [Core::Int] The (receiver) value.
49
+ # @return [void]
50
+ def define_negative_function(int)
51
+ function_name = int.name.call("negative?", [int.name])
52
+ Core.define(function: function_name) do |function|
53
+ function[:return] = Carbon::Boolean
54
+ define_negative_definition(int, function[:definition])
55
+ end
56
+ end
57
+
58
+ # Defines the even function. The function (named `even?`) returns a
59
+ # boolean value; if the receiver is even (i.e. evenly divisible by
60
+ # two), the function returns `true`; otherwise, the function returns
61
+ # `false`. It performs the check by checking the least significant
62
+ # bit (`trunc %i to i1`).
63
+ #
64
+ # @param int [Core::Int] The (receiver) value.
65
+ # @return [void]
66
+ def define_even_function(int)
67
+ function_name = int.name.call("even?", [int.name])
68
+ Core.define(function: function_name) do |function|
69
+ function[:return] = Carbon::Boolean
70
+ define_even_definition(int, function[:definition])
71
+ end
72
+ end
73
+
74
+ # Defines the odd function. The function (named `odd?`) returns a
75
+ # boolean value; if the receiver is odd (i.e. not evenly divisible
76
+ # by two), the function returns `true`; otherwise, the function returns
77
+ # `false`. It performs the check by checking the least significant
78
+ # bit (`xor (trunc %i to i1), 1`).
79
+ #
80
+ # @param int [Core::Int] The (receiver) value.
81
+ # @return [void]
82
+ def define_odd_function(int)
83
+ function_name = int.name.call("odd?", [int.name])
84
+ Core.define(function: function_name) do |function|
85
+ function[:return] = Carbon::Boolean
86
+ define_odd_definition(int, function[:definition])
87
+ end
88
+ end
89
+
90
+ private
91
+
92
+ def define_positive_definition(int, definition)
93
+ entry = definition.add("entry").build
94
+ this = definition.params[0]
95
+ this.name = "self"
96
+
97
+ return entry.ret(1) if int.sign == :unsigned
98
+ sign = entry.lshr(this, int.size - 1)
99
+ trunc = entry.trunc(sign, Carbon::Boolean)
100
+ entry.ret(trunc)
101
+ end
102
+
103
+ def define_negative_definition(int, definition)
104
+ entry = definition.add("entry").build
105
+ this = definition.params[0]
106
+ this.name = "self"
107
+
108
+ return entry.ret(0) if int.sign == :unsigned
109
+ sign = entry.lshr(this, int.size - 1)
110
+ trunc = entry.trunc(sign, Carbon::Boolean)
111
+ negate = entry.xor(trunc, 1)
112
+ entry.ret(negate)
113
+ end
114
+
115
+ def define_even_definition(_int, definition)
116
+ entry = definition.add("entry").build
117
+ this = definition.params[0]
118
+ this.name = "self"
119
+
120
+ entry.ret(entry.xor(entry.trunc(this, Carbon::Boolean), 1))
121
+ end
122
+
123
+ def define_odd_definition(_int, definition)
124
+ entry = definition.add("entry").build
125
+ this = definition.params[0]
126
+ this.name = "self"
127
+
128
+ entry.ret(entry.trunc(this, Carbon::Boolean))
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Core
6
+ module Integer
7
+ # Defines the "spaceship" function on all integers except booleans. The
8
+ # spaceship operator compares two integers, and returns three possible
9
+ # values depending on the order of the integers: `1` if the receiver
10
+ # (`this`) is greater than the right (`other`), `0` if `this` is equal
11
+ # to `other`, and `-1` if `this` is less than `other`. This is useful
12
+ # for determining the order of things. This module defines a single
13
+ # function on all integers except boolean:
14
+ #
15
+ # - `.<=><T: Carbon::Numeric>(self, other: T): Carbon::Int8`
16
+ #
17
+ # The function returns `Carbon::Int8` because it is the smallest possible
18
+ # integer type that retains sign information.
19
+ module Ship
20
+ # Defines the spaceship function (`:<=>`). The left and right integer
21
+ # types are given. The spaceship function works the same as the one
22
+ # in Ruby:
23
+ #
24
+ # - If the left value is less than the right value, return -1;
25
+ # otherwise,
26
+ # - If the left value is equal to the right value, return 0;
27
+ # otherwise,
28
+ # - The left value is greater than the right value, return 1.
29
+ #
30
+ # @param left [Core::Int] The left (receiver) value.
31
+ # @param right [Core::Int] The right value.
32
+ # @return [void]
33
+ def define_ship_function(left, right)
34
+ return if left.size == 1 || right.size == 1
35
+ function_name = left.name.call(:<=>, [left.name, right.name])
36
+ Core.define(function: function_name) do |function|
37
+ function[:return] = Carbon::Type("Carbon::Int8")
38
+ define_ship_definition(left, right, function[:definition])
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def define_ship_definition(left, right, definition)
45
+ blocks =
46
+ %w(entry this<other this!<other this=other this>other)
47
+ .map { |n| definition.add(n) }
48
+ params = definition.params
49
+ params[0].name, params[1].name = %w(self other)
50
+ params = force_same_cast(params, blocks[0].build, left, right)
51
+
52
+ define_ship_definition_returns(blocks)
53
+ define_ship_definition_compare(params, blocks)
54
+ end
55
+
56
+ def define_ship_definition_returns(blocks)
57
+ blocks[1].build.ret(1)
58
+ blocks[3].build.ret(0)
59
+ blocks[4].build.ret(-1)
60
+ end
61
+
62
+ def define_ship_definition_compare(params, blocks)
63
+ blocks[0]
64
+ .build { |b| b.br(b.icmp(:lt, *params), blocks[1], blocks[2]) }
65
+ blocks[2]
66
+ .build { |b| b.br(b.icmp(:eq, *params), blocks[4], blocks[5]) }
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Core
6
+ module Integer
7
+ # Defines signage functions. This can be used to determine if an integer
8
+ # is signed or unsigned. This defines the following functions on all
9
+ # integers except boolean:
10
+ #
11
+ # - `.signed?(): Carbon::Boolean`
12
+ # - `.signed?(self): Carbon::Boolean`
13
+ # - `.unsigned?(): Carbon::Boolean`
14
+ # - `.unsigned?(self): Carbon::Boolean`
15
+ #
16
+ # @api private
17
+ module Sign
18
+ # Defines the sign functions on the given integer. This produces the
19
+ # four variants of the sign functions: signed vs. unsigned, and
20
+ # no vs. one parameter.
21
+ #
22
+ # @param int [Core::Int] The (receiver) value.
23
+ # @return [void]
24
+ def define_sign_functions(int)
25
+ params = [[], [int.name]]
26
+ signs = [:signed, :unsigned]
27
+ params.product(signs).each do |(param, sign)|
28
+ define_sign_function(int, sign, param)
29
+ end
30
+ end
31
+
32
+ # Defines a sign function. If the integer is the same sign as the
33
+ # given sign, the defined function returns `true`; otherwise, it
34
+ # returns `false`.
35
+ #
36
+ # @param int [Core::Int] The (receiver) value.
37
+ # @param sign [::Symbol] The sign function to define.
38
+ # @param args [<Concrete::Type>] The arguments that the function
39
+ # takes. These are ignored.
40
+ def define_sign_function(int, sign, args)
41
+ function_name = int.name.call("#{sign}?", args)
42
+ Core.define(function: function_name) do |function|
43
+ function[:return] = Carbon::Boolean
44
+ function[:definition].add("entry").build do |b|
45
+ int.sign == sign ? b.ret(1) : b.ret(0)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Core
6
+ module Integer
7
+ # Defines the integer types. This uses the {Core::Ints} list to
8
+ # determine the integer types that will be defined, and defines them with
9
+ # the `:internal` type. This defines the following integer types:
10
+ #
11
+ # - `Carbon::Int8`, `Carbon::UInt8`
12
+ # - `Carbon::Int16`, `Carbon::UInt16`
13
+ # - `Carbon::Int32`, `Carbon::UInt32`
14
+ # - `Carbon::Int64`, `Carbon::UInt64`
15
+ #
16
+ # @api private
17
+ module Type
18
+ # Defines all of the integer types.
19
+ #
20
+ # @return [void]
21
+ def define_integer_types
22
+ Ints.each { |int| define_integer_type(int) }
23
+ end
24
+
25
+ # Defines the integer type for the given integer information. All
26
+ # integers implement both the `Carbon::Sized` and `Carbon::Numeric`
27
+ # traits.
28
+ #
29
+ # @param int [Core::Int] The integer type.
30
+ # @return [void]
31
+ def define_integer_type(int)
32
+ Core.define(internal: int.name) do |internal|
33
+ internal[:kind] = :integer
34
+ internal[:size] = int.size
35
+ internal[:implements] << Carbon::Type("Carbon::Sized")
36
+ internal[:implements] << Carbon::Type("Carbon::Numeric")
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Core
6
+ module Integer
7
+ # Defines zero functions. These can be used to determine if an integer
8
+ # is (or isn't) zero. This defines all of these functions on all
9
+ # integers except booleans:
10
+ #
11
+ # - `.zero?(self): Carbon::Boolean`
12
+ # - `.nonzero?(self): Carbon::Boolean`
13
+ #
14
+ # @api private
15
+ module Zero
16
+ # Defines the zero function. The function returns `true` if the value
17
+ # is equal to zero.
18
+ #
19
+ # @param int [Core::Int] The (receiver) value.
20
+ # @return [void]
21
+ def define_zero_function(int)
22
+ function_name = int.name.call("zero?", [int.name])
23
+ Core.define(function: function_name) do |function|
24
+ function[:return] = Carbon::Boolean
25
+ function[:definition].add("entry").build do |b|
26
+ this = function[:definition].params[0]
27
+ this.name = "self"
28
+ b.ret(b.icmp(:eq, this, 0))
29
+ end
30
+ end
31
+ end
32
+
33
+ # Defines the nonzero function. The function returns `true` if the
34
+ # value isn't equal to zero.
35
+ #
36
+ # @param int [Core::Int] The (receiver) value.
37
+ # @return [void]
38
+ def define_nonzero_function(int)
39
+ function_name = int.name.call("nonzero?", [int.name])
40
+ Core.define(function: function_name) do |function|
41
+ function[:return] = Carbon::Boolean
42
+ function[:definition].add("entry").build do |b|
43
+ this = function[:definition].params[0]
44
+ this.name = "self"
45
+ b.ret(b.icmp(:ne, this, 0))
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end