STUDIO HAZE · topaz
Topaz source
Open by house policy. Topaz is our own language.
Topaz 5.20 · 56 files
compiler/crates/topaz_self_frontend/topaz/checker/model.tpz
Topaz · 13513 B · Original file
1
// Shared data contracts for the acyclic checker module graph.2
// Records carry state, signatures, and call plans across leaves; semantic work3
// remains with type, expression, call, statement, and body modules.5
import types {6
PreviewCheckDiagnostic,7
PreviewResolvedDeclaration,8
PreviewTypeAtom,9
PreviewTypedCall,10
PreviewTypedCapture,11
PreviewTypedNode,12
ResolveResult,13
SyntaxNode,14
}15
import checker_types { TypeValue }17
// Callback boundary that keeps expression, call, statement, and body recursion acyclic.18
export record CheckerRequest {19
kind: string,20
moduleIndex: int,21
source: Bytes,22
node: SyntaxNode,23
typeValue: TypeValue,24
}26
export record CheckerResponse {27
typeValue: TypeValue,28
boolValue: bool,29
}31
export type CheckerService = (CheckerState, CheckerRequest) -> CheckerResponse33
export function serviceInferExpression(34
service: CheckerService,35
state: CheckerState,36
moduleIndex: int,37
source: Bytes,38
expression: SyntaxNode,39
) -> TypeValue {40
service(state, CheckerRequest {41
kind: "infer-expression",42
moduleIndex: moduleIndex,43
source: source,44
node: expression,45
typeValue: emptyType("unknown"),46
}).typeValue47
}49
export function serviceBuiltinNamespaceObject(50
service: CheckerService,51
state: CheckerState,52
moduleIndex: int,53
source: Bytes,54
expression: SyntaxNode,55
) -> bool {56
service(state, CheckerRequest {57
kind: "builtin-namespace-object",58
moduleIndex: moduleIndex,59
source: source,60
node: expression,61
typeValue: emptyType("unknown"),62
}).boolValue63
}65
export function serviceCheckBlock(66
service: CheckerService,67
state: CheckerState,68
moduleIndex: int,69
source: Bytes,70
block: SyntaxNode,71
) -> TypeValue {72
service(state, CheckerRequest {73
kind: "check-block",74
moduleIndex: moduleIndex,75
source: source,76
node: block,77
typeValue: emptyType("unknown"),78
}).typeValue79
}81
export function serviceCheckBlockExpected(82
service: CheckerService,83
state: CheckerState,84
moduleIndex: int,85
source: Bytes,86
block: SyntaxNode,87
expected: TypeValue,88
) -> TypeValue {89
service(state, CheckerRequest {90
kind: "check-block-expected",91
moduleIndex: moduleIndex,92
source: source,93
node: block,94
typeValue: expected,95
}).typeValue96
}98
export function serviceGateCollectionKey(99
service: CheckerService,100
state: CheckerState,101
moduleIndex: int,102
node: SyntaxNode,103
key: TypeValue,104
) -> () {105
let _ = service(state, CheckerRequest {106
kind: "gate-collection-key",107
moduleIndex: moduleIndex,108
source: Bytes.encodeUtf8(""),109
node: node,110
typeValue: key,111
})112
()113
}115
// This decodes the parser's high type-parameter component and low bound ordinal.116
export const TYPE_BOUND_INDEX_STRIDE = 4294967296118
// These decimal limits are u64::MAX divided by each unit's millisecond multiplier.119
export const MAX_DURATION_MILLISECONDS = "18446744073709551615"121
export const MAX_DURATION_SECONDS = "18446744073709551"123
export const MAX_DURATION_MINUTES = "307445734561825"125
// Text parsing represents i64::MIN without first constructing an overflowing positive literal.126
export const MINIMUM_INT_DECIMAL = "-9223372036854775808"128
// Constant integer power accepts the same unsigned 32-bit exponent range as runtime power.129
export const MAX_CONSTANT_EXPONENT = 4294967295131
export record SymbolType {132
moduleIndex: int,133
lo: int,134
hi: int,135
name: string,136
typeValue: TypeValue,137
mutable: bool,138
}140
export record RecordField {141
name: string,142
typeValue: TypeValue,143
hasDefault: bool,144
}146
export record RecordDefinition {147
moduleIndex: int,148
name: string,149
typeParameters: Array<string>,150
fields: Array<RecordField>,151
}153
export record EnumVariant {154
name: string,155
payloads: Array<TypeValue>,156
}158
export record EnumDefinition {159
moduleIndex: int,160
name: string,161
typeParameters: Array<string>,162
variants: Array<EnumVariant>,163
}165
export record NewtypeDefinition {166
moduleIndex: int,167
name: string,168
typeParameters: Array<string>,169
base: TypeValue,170
}172
export record AliasDefinition {173
moduleIndex: int,174
name: string,175
typeParameters: Array<string>,176
body: TypeValue,177
}179
export record FunctionDefinition {180
moduleIndex: int,181
name: string,182
lo: int,183
hi: int,184
typeParameters: Array<string>,185
typeParameterOrigins: Array<string>,186
parameterNames: Array<string>,187
parameterTypes: Array<TypeValue>,188
parameterDefaults: Array<bool>,189
variadic: Array<TypeValue>,190
result: TypeValue,191
bounds: Array<FunctionBound>,192
}194
export record FunctionBound {195
parameterName: string,196
protocol: string,197
}199
export record ProtocolMethodDefinition {200
name: string,201
parameterNames: Array<string>,202
typeValue: TypeValue,203
}205
export record ProtocolDefinition {206
name: string,207
methods: Array<ProtocolMethodDefinition>,208
}210
export record ProtocolConformance {211
moduleIndex: int,212
typeName: string,213
protocol: string,214
derived: bool,215
}217
export record ReceiverMethodDefinition {218
moduleIndex: int,219
typeName: string,220
name: string,221
functionIndex: int,222
exported: bool,223
}225
export record TypeParameterFact {226
moduleIndex: int,227
owner: string,228
name: string,229
origin: string,230
}232
export record ModuleSyntax {233
moduleIndex: int,234
sourceOrdinal: int,235
identity: string,236
source: Bytes,237
root: SyntaxNode,238
generatedStd: bool,239
}241
export record LoopFrame {242
label: string,243
valueLoop: bool,244
bareTarget: bool,245
bareError: string,246
expected: Option<TypeValue>,247
breaks: Array<TypeValue>,248
}250
// Single owner of phase catalogs; service callbacks update it instead of copying caches.251
export record CheckerState {252
resolved: ResolveResult,253
modules: Array<ModuleSyntax>,254
declarationIndexes: Map<string, int>,255
valueDeclarationIndexesByModule: Map<string, Array<int>>,256
namespaceImportIndexes: Map<string, int>,257
referenceIndexes: Map<string, int>,258
scopeIndexes: Map<string, int>,259
symbolIndexes: Map<string, int>,260
nodeIndexes: Map<string, int>,261
callIndexes: Map<string, int>,262
functionIndexes: Map<string, int>,263
functionNameIndexes: Map<string, int>,264
receiverMethodIndexes: Map<string, int>,265
protocolIndexes: Map<string, int>,266
conformanceIndexes: Map<string, int>,267
conformanceTypeIndexes: Map<string, int>,268
recordIndexes: Map<string, int>,269
enumIndexes: Map<string, int>,270
newtypeIndexes: Map<string, int>,271
aliasIndexes: Map<string, int>,272
symbols: Array<SymbolType>,273
records: Array<RecordDefinition>,274
enums: Array<EnumDefinition>,275
newtypes: Array<NewtypeDefinition>,276
aliases: Array<AliasDefinition>,277
functions: Array<FunctionDefinition>,278
receiverMethods: Array<ReceiverMethodDefinition>,279
protocols: Array<ProtocolDefinition>,280
pendingFunctions: Array<bool>,281
functionAliases: Map<string, int>,282
conformances: Array<ProtocolConformance>,283
typeParameters: Array<TypeParameterFact>,284
activeFunctions: Array<int>,285
expectedReturns: Array<TypeValue>,286
returnJoins: Array<Array<TypeValue>>,287
expectedExpressions: Array<ExpectedExpressionContext>,288
bareBindingExpressions: Array<SyntaxNode>,289
literalJoinContexts: Array<int>,290
branchJoinContexts: Array<int>,291
statementExpressionContexts: Array<int>,292
typeCapabilitySuppressions: Array<bool>,293
loopFrames: Array<LoopFrame>,294
loopFloors: Array<int>,295
pipeValues: Array<TypeValue>,296
nodes: Array<PreviewTypedNode>,297
calls: Array<PreviewTypedCall>,298
captures: Array<PreviewTypedCapture>,299
diagnostics: Array<PreviewCheckDiagnostic>,300
inferenceSolutions: Map<string, TypeValue>,301
nextInference: int,302
}304
export record ExpectedExpressionContext {305
kind: string,306
lo: int,307
hi: int,308
typeValue: TypeValue,309
}311
export record TypeBinding {312
name: string,313
typeValue: TypeValue,314
}316
export record TypeTarget {317
moduleIndex: int,318
name: string,319
}321
export record NamedNominalTarget {322
semanticKind: string,323
diagnosticKind: string,324
typeArgumentCount: int,325
}327
export record PatternCoverage {328
irrefutable: bool,329
keys: Array<string>,330
}332
export record CoverageGap {333
decidable: bool,334
missing: Array<string>,335
}337
export record InferredCallArguments {338
types: Array<TypeValue>,339
nodes: Array<SyntaxNode>,340
}342
export record CallResultCandidates {343
nominal: Option<TypeValue>,344
protocol: Option<TypeValue>,345
}347
export record LeadingCallArgument {348
node: SyntaxNode,349
typeValue: TypeValue,350
}352
export record CaptureTarget {353
declaration: PreviewResolvedDeclaration,354
name: string,355
typeValue: Array<PreviewTypeAtom>,356
ambient: bool,357
}359
export record CallArgumentPlan {360
slots: Array<int>,361
leadingSlot: int,362
resultUnknown: bool,363
}365
export record CallSignature {366
parameterNames: Array<string>,367
parameterDefaults: Array<bool>,368
parameterCount: int,369
variadic: bool,370
positionalOnlyIdentity: string,371
}373
export record BuiltinFunction {374
typeValue: TypeValue,375
callSignature: CallSignature,376
}378
export record UserProtocolCallTarget {379
protocolName: string,380
method: ProtocolMethodDefinition,381
}383
// Selected call signature and argument plan before contextual inference completes.384
export record CallPreparation {385
callee: SyntaxNode,386
diagnosticNode: SyntaxNode,387
declaredType: TypeValue,388
contextualType: TypeValue,389
receiverType: TypeValue,390
optionalContainer: string,391
referencedDefinition: Option<FunctionDefinition>,392
userProtocolTarget: Option<UserProtocolCallTarget>,393
argumentPlan: CallArgumentPlan,394
bindings: Array<TypeBinding>,395
leading: Option<LeadingCallArgument>,396
projectedMember: string,397
}399
export record CompletedCall {400
calleeType: TypeValue,401
resultType: TypeValue,402
}404
export function emptyType(kind: string) -> TypeValue {405
TypeValue {406
kind: kind,407
name: "",408
value: "",409
identity: "",410
origin: "",411
arguments: [],412
members: [],413
fieldNames: [],414
fields: [],415
parameters: [],416
variadic: [],417
result: [],418
}419
}421
export function primitive(name: string) -> TypeValue {422
TypeValue {423
kind: "primitive",424
name: name,425
value: "",426
identity: "",427
origin: "",428
arguments: [],429
members: [],430
fieldNames: [],431
fields: [],432
parameters: [],433
variadic: [],434
result: [],435
}436
}438
export function literal(name: string, spelling: string) -> TypeValue {439
TypeValue {440
kind: "literal",441
name: name,442
value: spelling,443
identity: "",444
origin: "",445
arguments: [],446
members: [],447
fieldNames: [],448
fields: [],449
parameters: [],450
variadic: [],451
result: [],452
}453
}455
export function nominal(kind: string, identity: string, arguments: Array<TypeValue>) -> TypeValue {456
TypeValue {457
kind: kind,458
name: "",459
value: "",460
identity: identity,461
origin: "",462
arguments: arguments,463
members: [],464
fieldNames: [],465
fields: [],466
parameters: [],467
variadic: [],468
result: [],469
}470
}472
export function nominalInModule(473
kind: string,474
identity: string,475
arguments: Array<TypeValue>,476
moduleIdentity: string,477
) -> TypeValue {478
TypeValue {479
kind: kind,480
name: "",481
value: "",482
identity: identity,483
origin: moduleIdentity,484
arguments: arguments,485
members: [],486
fieldNames: [],487
fields: [],488
parameters: [],489
variadic: [],490
result: [],491
}492
}494
export function constructor(name: string, arguments: Array<TypeValue>) -> TypeValue {495
TypeValue {496
kind: "constructor",497
name: name,498
value: "",499
identity: "",500
origin: "",501
arguments: arguments,502
members: [],503
fieldNames: [],504
fields: [],505
parameters: [],506
variadic: [],507
result: [],508
}509
}511
export function functionType(512
parameters: Array<TypeValue>,513
variadic: Array<TypeValue>,514
result: TypeValue,515
) -> TypeValue {516
TypeValue {517
kind: "function",518
name: "",519
value: "",520
identity: "",521
origin: "",522
arguments: [],523
members: [],524
fieldNames: [],525
fields: [],526
parameters: parameters,527
variadic: variadic,528
result: [result],529
}530
}532
export function inference(index: int) -> TypeValue {533
TypeValue {534
kind: "inference-variable",535
name: "",536
value: "{index}",537
identity: "",538
origin: "",539
arguments: [],540
members: [],541
fieldNames: [],542
fields: [],543
parameters: [],544
variadic: [],545
result: [],546
}547
}549
export function rigid(name: string, origin: string) -> TypeValue {550
TypeValue {551
kind: "rigid",552
name: name,553
value: "",554
identity: "",555
origin: origin,556
arguments: [],557
members: [],558
fieldNames: [],559
fields: [],560
parameters: [],561
variadic: [],562
result: [],563
}564
}566
export function structural(fieldNames: Array<string>, fields: Array<TypeValue>) -> TypeValue {567
let mut orderedNames: Array<string> = []568
let mut orderedFields: Array<TypeValue> = []569
let mut sourceIndex = 0570
for name in fieldNames {571
let field = match fields.get(sourceIndex) {572
case Some(found) => found573
case None => emptyType("unknown")574
}575
let mut inserted = false576
let mut index = 0577
while index < orderedNames.length {578
let existing = match orderedNames.get(index) {579
case Some(found) => found580
case None => name581
}582
if name < existing {583
orderedNames.insert(index, name)584
orderedFields.insert(index, field)585
inserted = true586
break587
}588
index += 1589
}590
if !inserted {591
orderedNames.push(name)592
orderedFields.push(field)593
}594
sourceIndex += 1595
}596
TypeValue {597
kind: "record",598
name: "",599
value: "",600
identity: "",601
origin: "",602
arguments: [],603
members: [],604
fieldNames: orderedNames,605
fields: orderedFields,606
parameters: [],607
variadic: [],608
result: [],609
}610
}SHA256 24c5c4c024167334ed682a031b054b79991aae1bf3f59b43a150428e593ad55e