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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/.rubocop.yml +38 -0
- data/.travis.yml +4 -0
- data/.yardopts +1 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +14 -0
- data/carbon.gemspec +30 -0
- data/lib/carbon.rb +54 -0
- data/lib/carbon/concrete.rb +43 -0
- data/lib/carbon/concrete/build.rb +63 -0
- data/lib/carbon/concrete/index.rb +324 -0
- data/lib/carbon/concrete/item.rb +37 -0
- data/lib/carbon/concrete/item/base.rb +153 -0
- data/lib/carbon/concrete/item/data.rb +22 -0
- data/lib/carbon/concrete/item/function.rb +97 -0
- data/lib/carbon/concrete/item/internal.rb +83 -0
- data/lib/carbon/concrete/item/struct.rb +65 -0
- data/lib/carbon/concrete/item/struct/element.rb +42 -0
- data/lib/carbon/concrete/item/trait.rb +72 -0
- data/lib/carbon/concrete/item/trait/expectation.rb +55 -0
- data/lib/carbon/concrete/request.rb +137 -0
- data/lib/carbon/concrete/type.rb +260 -0
- data/lib/carbon/concrete/type/function.rb +91 -0
- data/lib/carbon/concrete/type/generic.rb +118 -0
- data/lib/carbon/concrete/type/name.rb +147 -0
- data/lib/carbon/concrete/type/parse.rb +172 -0
- data/lib/carbon/concrete/type/part.rb +100 -0
- data/lib/carbon/core.rb +61 -0
- data/lib/carbon/core/int.rb +87 -0
- data/lib/carbon/core/integer.rb +109 -0
- data/lib/carbon/core/integer/cast.rb +83 -0
- data/lib/carbon/core/integer/math.rb +198 -0
- data/lib/carbon/core/integer/misc.rb +145 -0
- data/lib/carbon/core/integer/pole.rb +133 -0
- data/lib/carbon/core/integer/ship.rb +71 -0
- data/lib/carbon/core/integer/sign.rb +52 -0
- data/lib/carbon/core/integer/type.rb +42 -0
- data/lib/carbon/core/integer/zero.rb +52 -0
- data/lib/carbon/core/pointer.rb +54 -0
- data/lib/carbon/core/pointer/access.rb +123 -0
- data/lib/carbon/core/pointer/cast.rb +55 -0
- data/lib/carbon/core/pointer/math.rb +187 -0
- data/lib/carbon/core/pointer/memory.rb +85 -0
- data/lib/carbon/core/pointer/type.rb +23 -0
- data/lib/carbon/tacky.rb +21 -0
- data/lib/carbon/tacky/block.rb +96 -0
- data/lib/carbon/tacky/builder.rb +310 -0
- data/lib/carbon/tacky/context.rb +66 -0
- data/lib/carbon/tacky/function.rb +137 -0
- data/lib/carbon/tacky/instruction.rb +170 -0
- data/lib/carbon/tacky/parameter.rb +23 -0
- data/lib/carbon/tacky/reference.rb +23 -0
- data/lib/carbon/tacky/value.rb +40 -0
- data/lib/carbon/version.rb +9 -0
- 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
|