Skip to content
← Back

src/syntax/process/register_source_intrinsics.ghul

1
namespace Syntax.Process is
2
use Logging
3
use Trees
4
use Source
5
6
// Registers an innate for each intrinsic the compilation declares in
7
// source, so the assembly that provides the intrinsics can be built by
8
// a compiler that otherwise reflects them.
9
//
10
// The declaration itself stays where it is written and is emitted
11
// normally — that emitted method, carrying its INTRINSIC_ATTRIBUTE, is
12
// what every other compilation reflects. What it cannot do is serve
13
// this compilation: a call has to lower to an opcode, and that is a
14
// property of the symbol's class, not a flag. So a matching innate is
15
// registered in `Ghul`, where the language looks for it.
16
//
17
// Runs once signatures are resolved, because the innate takes its own
18
// from the declaration.
19
class REGISTER_SOURCE_INTRINSICS: ScopedVisitor is
20
_namespaces: Semantic.NAMESPACES
21
22
init(
23
logger: Logger,
24
symbol_table: Semantic.SYMBOL_TABLE,
25
namespaces: Semantic.NAMESPACES
26
)
27
is
28
super.init(logger, symbol_table, namespaces)
29
30
_namespaces = namespaces
31
si
32
33
apply(root: Trees.Node) is
34
root.walk(self)
35
si
36
37
visit(function: Definitions.FUNCTION) is
38
super.visit(function)
39
40
let symbol = symbol_for(function)
41
42
if !symbol? \/ !isa Semantic.Symbols.Function(symbol) then
43
return
44
fi
45
46
let declaration = cast Semantic.Symbols.Function(symbol)
47
48
if !declaration.intrinsic_operation? \/ declaration.is_innate then
49
return
50
fi
51
52
let operation = declaration.intrinsic_operation
53
54
let intrinsic: Semantic.Symbols.Function mut
55
56
// An operator a type declares for itself goes onto the type of
57
// its first operand, as its reflected counterpart does.
58
if let home = _operator_home(declaration) then
59
intrinsic = Semantic.Symbols.INNATE_FUNCTION(
60
declaration.location,
61
home,
62
declaration.name,
63
home,
64
operation
65
)
66
67
home.declare_function_group(declaration.location, intrinsic, null)
68
else
69
let target = _namespaces.try_find_namespace(".Ghul.Intrinsics")
70
71
if !target? then
72
return
73
fi
74
75
intrinsic =
76
cast Semantic.Symbols.Function?(
77
target.declare_innate(
78
declaration.location,
79
declaration.name,
80
operation,
81
target,
82
null
83
)
84
)!
85
fi
86
87
intrinsic.arguments = declaration.arguments
88
intrinsic.argument_names = declaration.argument_names
89
intrinsic.return_type = declaration.return_type
90
91
// An operator's other operand types reach it too.
92
if let home = _operator_home(declaration) then
93
for other in Semantic.Symbols.TYPE_HOMED_OPERATORS.homes(declaration) do
94
if other != home then
95
other.declare_function_group(declaration.location, intrinsic, null)
96
fi
97
od
98
fi
99
100
if declaration.is_generic then
101
intrinsic.is_generic = true
102
intrinsic.generic_arguments = declaration.generic_arguments
103
intrinsic.generic_argument_names = declaration.generic_argument_names
104
intrinsic.generic_argument_constraint_kinds = declaration.generic_argument_constraint_kinds
105
intrinsic.generic_argument_has_constructor_constraint = declaration.generic_argument_has_constructor_constraint
106
fi
107
si
108
109
_operator_home(declaration: Semantic.Symbols.Function) -> Semantic.Symbols.Classy? is
110
if !Semantic.Symbols.TYPE_HOMED_OPERATORS.contains(declaration.name) \/ declaration.arguments.count == 0 then
111
return null
112
fi
113
114
if let first: Semantic.Types.NAMED = declaration.arguments[0] then
115
return cast Semantic.Symbols.Classy?(first.symbol)
116
fi
117
118
return null
119
si
120
si
121
si