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,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
|