slow.monster

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 work
3// remains with type, expression, call, statement, and body modules.
5import types {
6 PreviewCheckDiagnostic,
7 PreviewResolvedDeclaration,
8 PreviewTypeAtom,
9 PreviewTypedCall,
10 PreviewTypedCapture,
11 PreviewTypedNode,
12 ResolveResult,
13 SyntaxNode,
15import checker_types { TypeValue }
17// Callback boundary that keeps expression, call, statement, and body recursion acyclic.
18export record CheckerRequest {
19 kind: string,
20 moduleIndex: int,
21 source: Bytes,
22 node: SyntaxNode,
23 typeValue: TypeValue,
26export record CheckerResponse {
27 typeValue: TypeValue,
28 boolValue: bool,
31export type CheckerService = (CheckerState, CheckerRequest) -> CheckerResponse
33export 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 }).typeValue
49export 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 }).boolValue
65export 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 }).typeValue
81export 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 }).typeValue
98export 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 ()
115// This decodes the parser's high type-parameter component and low bound ordinal.
116export const TYPE_BOUND_INDEX_STRIDE = 4294967296
118// These decimal limits are u64::MAX divided by each unit's millisecond multiplier.
119export const MAX_DURATION_MILLISECONDS = "18446744073709551615"
121export const MAX_DURATION_SECONDS = "18446744073709551"
123export const MAX_DURATION_MINUTES = "307445734561825"
125// Text parsing represents i64::MIN without first constructing an overflowing positive literal.
126export const MINIMUM_INT_DECIMAL = "-9223372036854775808"
128// Constant integer power accepts the same unsigned 32-bit exponent range as runtime power.
129export const MAX_CONSTANT_EXPONENT = 4294967295
131export record SymbolType {
132 moduleIndex: int,
133 lo: int,
134 hi: int,
135 name: string,
136 typeValue: TypeValue,
137 mutable: bool,
140export record RecordField {
141 name: string,
142 typeValue: TypeValue,
143 hasDefault: bool,
146export record RecordDefinition {
147 moduleIndex: int,
148 name: string,
149 typeParameters: Array<string>,
150 fields: Array<RecordField>,
153export record EnumVariant {
154 name: string,
155 payloads: Array<TypeValue>,
158export record EnumDefinition {
159 moduleIndex: int,
160 name: string,
161 typeParameters: Array<string>,
162 variants: Array<EnumVariant>,
165export record NewtypeDefinition {
166 moduleIndex: int,
167 name: string,
168 typeParameters: Array<string>,
169 base: TypeValue,
172export record AliasDefinition {
173 moduleIndex: int,
174 name: string,
175 typeParameters: Array<string>,
176 body: TypeValue,
179export 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>,
194export record FunctionBound {
195 parameterName: string,
196 protocol: string,
199export record ProtocolMethodDefinition {
200 name: string,
201 parameterNames: Array<string>,
202 typeValue: TypeValue,
205export record ProtocolDefinition {
206 name: string,
207 methods: Array<ProtocolMethodDefinition>,
210export record ProtocolConformance {
211 moduleIndex: int,
212 typeName: string,
213 protocol: string,
214 derived: bool,
217export record ReceiverMethodDefinition {
218 moduleIndex: int,
219 typeName: string,
220 name: string,
221 functionIndex: int,
222 exported: bool,
225export record TypeParameterFact {
226 moduleIndex: int,
227 owner: string,
228 name: string,
229 origin: string,
232export record ModuleSyntax {
233 moduleIndex: int,
234 sourceOrdinal: int,
235 identity: string,
236 source: Bytes,
237 root: SyntaxNode,
238 generatedStd: bool,
241export record LoopFrame {
242 label: string,
243 valueLoop: bool,
244 bareTarget: bool,
245 bareError: string,
246 expected: Option<TypeValue>,
247 breaks: Array<TypeValue>,
250// Single owner of phase catalogs; service callbacks update it instead of copying caches.
251export 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,
304export record ExpectedExpressionContext {
305 kind: string,
306 lo: int,
307 hi: int,
308 typeValue: TypeValue,
311export record TypeBinding {
312 name: string,
313 typeValue: TypeValue,
316export record TypeTarget {
317 moduleIndex: int,
318 name: string,
321export record NamedNominalTarget {
322 semanticKind: string,
323 diagnosticKind: string,
324 typeArgumentCount: int,
327export record PatternCoverage {
328 irrefutable: bool,
329 keys: Array<string>,
332export record CoverageGap {
333 decidable: bool,
334 missing: Array<string>,
337export record InferredCallArguments {
338 types: Array<TypeValue>,
339 nodes: Array<SyntaxNode>,
342export record CallResultCandidates {
343 nominal: Option<TypeValue>,
344 protocol: Option<TypeValue>,
347export record LeadingCallArgument {
348 node: SyntaxNode,
349 typeValue: TypeValue,
352export record CaptureTarget {
353 declaration: PreviewResolvedDeclaration,
354 name: string,
355 typeValue: Array<PreviewTypeAtom>,
356 ambient: bool,
359export record CallArgumentPlan {
360 slots: Array<int>,
361 leadingSlot: int,
362 resultUnknown: bool,
365export record CallSignature {
366 parameterNames: Array<string>,
367 parameterDefaults: Array<bool>,
368 parameterCount: int,
369 variadic: bool,
370 positionalOnlyIdentity: string,
373export record BuiltinFunction {
374 typeValue: TypeValue,
375 callSignature: CallSignature,
378export record UserProtocolCallTarget {
379 protocolName: string,
380 method: ProtocolMethodDefinition,
383// Selected call signature and argument plan before contextual inference completes.
384export 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,
399export record CompletedCall {
400 calleeType: TypeValue,
401 resultType: TypeValue,
404export 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 }
421export 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 }
438export 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 }
455export 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 }
472export 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 }
494export 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 }
511export 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 }
532export 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 }
549export 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 }
566export 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 = 0
570 for name in fieldNames {
571 let field = match fields.get(sourceIndex) {
572 case Some(found) => found
573 case None => emptyType("unknown")
574 }
575 let mut inserted = false
576 let mut index = 0
577 while index < orderedNames.length {
578 let existing = match orderedNames.get(index) {
579 case Some(found) => found
580 case None => name
581 }
582 if name < existing {
583 orderedNames.insert(index, name)
584 orderedFields.insert(index, field)
585 inserted = true
586 break
587 }
588 index += 1
589 }
590 if !inserted {
591 orderedNames.push(name)
592 orderedFields.push(field)
593 }
594 sourceIndex += 1
595 }
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 }

SHA256 24c5c4c024167334ed682a031b054b79991aae1bf3f59b43a150428e593ad55e