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