Skip to content
← Back

src/semantic/function_caller.ghul

1
namespace Semantic is
2
use IO.Std;
3
4
use Logging;
5
6
use Types.Type;
7
8
use IR.Values;
9
10
class FUNCTION_CALLER(
11
_symbol_table: SYMBOL_TABLE,
12
_value_boxer: IR.VALUE_BOXER
13
) is
14
// public so container can initialize it to break a
15
// circular dependency:
16
loader: SYMBOL_LOADER public;
17
18
super();
19
20
call_innate_function(
21
function: Symbols.INNATE_FUNCTION,
22
arguments: Collections.List[Value],
23
argument_types: Collections.List[Type],
24
type: Type?
25
) -> Value =>
26
Call.INNATE(
27
function,
28
null,
29
arguments,
30
type
31
);
32
33
call_innate_function(
34
function: Symbols.INNATE_METHOD,
35
from: Value?,
36
arguments: Collections.List[Value],
37
argument_types: Collections.List[Type],
38
type: Type?
39
) -> Value =>
40
Call.INNATE(
41
function,
42
from,
43
arguments,
44
type
45
);
46
47
call_global_function(
48
function: Symbols.Function,
49
arguments: Collections.List[Value],
50
argument_types: Collections.List[Type],
51
type: Type?
52
) -> Value =>
53
Call.GLOBAL(
54
function,
55
_value_boxer.box_arguments(arguments, function.arguments),
56
type
57
);
58
59
call_instance_method(
60
location: Source.LOCATION,
61
from: Value? mut,
62
function: Symbols.Function,
63
arguments: Collections.List[Value],
64
argument_types: Collections.List[Type],
65
type: Type?
66
) -> Value is
67
if !from? then
68
from = loader.load_self(location);
69
fi
70
71
if from.type!.is_type_variable then
72
from = CONSTRAINED(from);
73
fi
74
75
return
76
Call.INSTANCE(
77
_value_boxer.box_if_value(from),
78
function,
79
_value_boxer.box_arguments(arguments, function.arguments),
80
type
81
);
82
si
83
84
call_struct_method(
85
location: Source.LOCATION,
86
from: Value? mut,
87
function: Symbols.Function,
88
arguments: Collections.List[Value],
89
argument_types: Collections.List[Type],
90
type: Type?
91
) -> Value is
92
if !from? then
93
from = loader.load_self(location);
94
else
95
from = ADDRESS(from);
96
fi
97
98
return
99
Call.STRUCT(
100
from,
101
function,
102
_value_boxer.box_arguments(arguments, function.arguments),
103
type
104
);
105
si
106
107
call_abstract_method(
108
location: Source.LOCATION,
109
from: Value? mut,
110
function: Symbols.Function,
111
arguments: Collections.List[Value],
112
argument_types: Collections.List[Type],
113
type: Type?
114
) -> Value is
115
if !from? then
116
from = loader.load_self(location);
117
elif from.is_value_type then
118
// Don't believe this is possible in practice except
119
// for calls to IDisposable.Dispose() generated by the
120
// compiler for `let use` statements.
121
from = CONSTRAINED(from);
122
fi
123
124
return
125
Call.INSTANCE(
126
from,
127
function,
128
_value_boxer.box_arguments(arguments, function.arguments),
129
type
130
);
131
si
132
133
call_static_method(
134
function: Symbols.Function,
135
arguments: Collections.List[Value],
136
argument_types: Collections.List[Type],
137
type: Type?
138
) -> Value =>
139
Call.STATIC(
140
function,
141
_value_boxer.box_arguments(arguments, function.arguments),
142
type,
143
null
144
);
145
146
// A static virtual/abstract interface member reached through
147
// a bound type parameter - .NET's generic-math mechanism.
148
// `receiver` is the type parameter's type, needed to emit the
149
// `constrained.` prefix the CLR requires to dispatch such a
150
// call.
151
call_static_interface_method(
152
function: Symbols.Function,
153
receiver: Type,
154
arguments: Collections.List[Value],
155
argument_types: Collections.List[Type],
156
type: Type?
157
) -> Value =>
158
Call.STATIC(
159
function,
160
_value_boxer.box_arguments(arguments, function.arguments),
161
type,
162
receiver
163
);
164
165
call_constructor(
166
function: Symbols.Function,
167
arguments: Collections.List[Value],
168
type: Type
169
) -> Value =>
170
NEW(
171
type,
172
function,
173
_value_boxer.box_arguments(arguments, function.arguments)
174
);
175
si
176
si