@ascent-lang/dev 0.1.0 → 0.2.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.
Files changed (69) hide show
  1. package/dist/errors/elaborate.d.ts +24 -0
  2. package/dist/errors/elaborate.d.ts.map +1 -0
  3. package/dist/errors/elaborate.js +53 -0
  4. package/dist/errors/elaborate.js.map +1 -0
  5. package/dist/errors/index.d.ts.map +1 -1
  6. package/dist/errors/index.js +356 -30
  7. package/dist/errors/index.js.map +1 -1
  8. package/dist/errors/render.d.ts +3 -0
  9. package/dist/errors/render.d.ts.map +1 -0
  10. package/dist/errors/render.js +43 -0
  11. package/dist/errors/render.js.map +1 -0
  12. package/dist/errors/types.d.ts +29 -0
  13. package/dist/errors/types.d.ts.map +1 -1
  14. package/dist/index.js +18 -11
  15. package/dist/index.js.map +1 -1
  16. package/dist/interpreter.d.ts.map +1 -1
  17. package/dist/interpreter.js +28 -5
  18. package/dist/interpreter.js.map +1 -1
  19. package/dist/lexer/index.d.ts.map +1 -1
  20. package/dist/lexer/index.js +4 -3
  21. package/dist/lexer/index.js.map +1 -1
  22. package/dist/lexer/keywords.d.ts.map +1 -1
  23. package/dist/lexer/keywords.js +3 -0
  24. package/dist/lexer/keywords.js.map +1 -1
  25. package/dist/lexer/token.d.ts +7 -1
  26. package/dist/lexer/token.d.ts.map +1 -1
  27. package/dist/parser/ast.d.ts +8 -4
  28. package/dist/parser/ast.d.ts.map +1 -1
  29. package/dist/parser/expr.d.ts.map +1 -1
  30. package/dist/parser/expr.js +34 -19
  31. package/dist/parser/expr.js.map +1 -1
  32. package/dist/parser/stmt.d.ts.map +1 -1
  33. package/dist/parser/stmt.js +5 -3
  34. package/dist/parser/stmt.js.map +1 -1
  35. package/dist/parser/token-stream.d.ts +4 -4
  36. package/dist/parser/token-stream.d.ts.map +1 -1
  37. package/dist/parser/token-stream.js +21 -9
  38. package/dist/parser/token-stream.js.map +1 -1
  39. package/dist/parser/type-expr.d.ts.map +1 -1
  40. package/dist/parser/type-expr.js +3 -2
  41. package/dist/parser/type-expr.js.map +1 -1
  42. package/dist/parser/typechecker.d.ts.map +1 -1
  43. package/dist/parser/typechecker.js +109 -67
  44. package/dist/parser/typechecker.js.map +1 -1
  45. package/dist/types/types.d.ts +4 -0
  46. package/dist/types/types.d.ts.map +1 -1
  47. package/dist/types/types.js +27 -15
  48. package/dist/types/types.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/errors/elaborate.ts +88 -0
  51. package/src/errors/index.ts +356 -30
  52. package/src/errors/lexical.yml +48 -13
  53. package/src/errors/name.yml +45 -9
  54. package/src/errors/render.ts +59 -0
  55. package/src/errors/syntactic.yml +128 -49
  56. package/src/errors/typechecker.yml +147 -61
  57. package/src/errors/types.ts +55 -0
  58. package/src/index.ts +17 -11
  59. package/src/interpreter.ts +24 -6
  60. package/src/lexer/index.ts +4 -3
  61. package/src/lexer/keywords.ts +3 -0
  62. package/src/lexer/token.ts +18 -0
  63. package/src/parser/ast.ts +7 -6
  64. package/src/parser/expr.ts +34 -19
  65. package/src/parser/stmt.ts +5 -3
  66. package/src/parser/token-stream.ts +20 -8
  67. package/src/parser/type-expr.ts +3 -2
  68. package/src/parser/typechecker.ts +140 -52
  69. package/src/types/types.ts +36 -16
@@ -0,0 +1,24 @@
1
+ import type { Category, Example } from './types.js';
2
+ import type { Marker, Span } from '../lexer/token.js';
3
+ export interface ResolvedFix {
4
+ title: string;
5
+ span: Span;
6
+ replacement: string;
7
+ }
8
+ export interface LabeledSpan {
9
+ span: Span;
10
+ label: string;
11
+ }
12
+ export interface Diagnostic {
13
+ code: string;
14
+ category: Category;
15
+ severity: 'error';
16
+ message: string;
17
+ explanation: string | null;
18
+ span: Span;
19
+ fix: ResolvedFix | null;
20
+ example: Example | null;
21
+ related: LabeledSpan[];
22
+ }
23
+ export declare function elaborate(marker: Marker, source: string): Diagnostic;
24
+ //# sourceMappingURL=elaborate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elaborate.d.ts","sourceRoot":"","sources":["../../src/errors/elaborate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAQ,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;CACrB;AAID,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAgBD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CA4CpE"}
@@ -0,0 +1,53 @@
1
+ import { byCode } from './index.js';
2
+ // Substitute {found} (the offending source text) and any {key} the checker
3
+ // supplied in `data` (type names, counts) into a template.
4
+ const fill = (template, found, data) => {
5
+ let out = template.replaceAll('{found}', found);
6
+ for (const [key, value] of Object.entries(data)) {
7
+ out = out.replaceAll(`{${key}}`, value);
8
+ }
9
+ return out;
10
+ };
11
+ const matches = (when, found) => (when.equals === undefined || found === when.equals) &&
12
+ (when.startsWith === undefined || found.startsWith(when.startsWith));
13
+ export function elaborate(marker, source) {
14
+ const entry = byCode.get(marker.code);
15
+ if (entry === undefined) {
16
+ throw new Error(`Unregistered error code: ${marker.code}`); // dev-time typo guard
17
+ }
18
+ const span = marker.span;
19
+ const found = source.slice(span.start.offset, span.end.offset);
20
+ const data = marker.data ?? {};
21
+ // First matching variant wins; it overrides only the fields it sets, so
22
+ // everything else falls through to the base entry.
23
+ const variant = entry.variants?.find(v => matches(v.when, found)) ?? null;
24
+ const message = fill(variant?.message ?? entry.message ?? entry.summary, found, data);
25
+ const rawExplanation = variant?.explanation ?? entry.explanation ?? null;
26
+ const fixSpec = variant?.fix ?? entry.fix ?? null;
27
+ // Pair each YAML related-label with the span the checker emitted under the
28
+ // same key. A label with no matching span (the declaration had no source
29
+ // location) is dropped; a span with no label is ignored.
30
+ const related = [];
31
+ for (const label of entry.related ?? []) {
32
+ const match = marker.related?.find(r => r.key === label.key) ?? null;
33
+ if (match !== null) {
34
+ related.push({ span: match.span, label: fill(label.label, found, data) });
35
+ }
36
+ }
37
+ return {
38
+ code: entry.code,
39
+ category: entry.category,
40
+ severity: 'error',
41
+ message,
42
+ explanation: rawExplanation === null ? null : fill(rawExplanation, found, data),
43
+ span,
44
+ fix: fixSpec === null ? null : {
45
+ title: fill(fixSpec.title, found, data),
46
+ span,
47
+ replacement: fill(fixSpec.replacement, found, data),
48
+ },
49
+ example: variant?.example ?? entry.example ?? null,
50
+ related,
51
+ };
52
+ }
53
+ //# sourceMappingURL=elaborate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elaborate.js","sourceRoot":"","sources":["../../src/errors/elaborate.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,MAAM,EAAE,UAAU,EA+B9B,CAAC;AAEF,eAAO,MAAM,MAAM,yBAAwC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,MAAM,EAAE,UAAU,EAqW9B,CAAC;AAEF,eAAO,MAAM,MAAM,yBAAwC,CAAC"}
@@ -1,35 +1,361 @@
1
1
  // AUTO-GENERATED — do not edit. Run `npm run generate` to update.
2
2
  export const ERRORS = [
3
- { code: 'L0001', name: 'unexpected-character', category: 'lexical', summary: "A character that can't begin any token." },
4
- { code: 'L0002', name: 'invalid-number-literal', category: 'lexical', summary: "A letter immediately followed a number — '123abc' is not a valid token." },
5
- { code: 'L0003', name: 'unterminated-string', category: 'lexical', summary: "A string literal that doesn't end before the end of the line." },
6
- { code: 'N0001', name: 'undefined-slot', category: 'name', summary: "A name was used that has not been declared with 'fix' or 'mut'." },
7
- { code: 'N0002', name: 'reassign-fix', category: 'name', summary: "Assignment to a slot declared with 'fix' 'fix' slots never change; declare it with 'mut' instead if it needs to." },
8
- { code: 'S0001', name: 'unclosed-paren', category: 'syntactic', summary: "An opening '(' has no matching ')'." },
9
- { code: 'S0002', name: 'expected-expression', category: 'syntactic', summary: "An expression was required here but the input contained none." },
10
- { code: 'S0003', name: 'expected-slot-name', category: 'syntactic', summary: "A slot name (lowercase identifier) was expected after 'fix'." },
11
- { code: 'S0004', name: 'expected-equals', category: 'syntactic', summary: "An '=' was expected after the slot name in a 'fix' declaration." },
12
- { code: 'S0005', name: 'unclosed-brace', category: 'syntactic', summary: "An opening '{' has no matching '}'." },
13
- { code: 'S0006', name: 'expected-test-paren', category: 'syntactic', summary: "An '(' was expected here to start the condition." },
14
- { code: 'S0007', name: 'expected-block', category: 'syntactic', summary: "A block ('{ … }') was expected here." },
15
- { code: 'S0008', name: 'chained-comparison', category: 'syntactic', summary: "Comparisons don't chain 'a < b < c' isn't valid. Group with parentheses instead." },
16
- { code: 'S0009', name: 'expected-colon', category: 'syntactic', summary: "A ':' was expected between the argument name and its type." },
17
- { code: 'S0010', name: 'expected-type', category: 'syntactic', summary: "A type name was expected here. Valid types are Int, Float, Bool, String, and List<T>." },
18
- { code: 'S0011', name: 'expected-semicolon', category: 'syntactic', summary: "A ';' was expected here." },
19
- { code: 'S0012', name: 'expected-method-name', category: 'syntactic', summary: "A method name (lowercase identifier) was expected after '.'." },
20
- { code: 'S0013', name: 'unclosed-bracket', category: 'syntactic', summary: "An opening '[' has no matching ']'." },
21
- { code: 'T0001', name: 'annotation-mismatch', category: 'type', summary: "The declared type annotation doesn't match the inferred type of the initialiser." },
22
- { code: 'T0002', name: 'incompatible-list-elements', category: 'type', summary: "List elements have incompatible types — a list must be homogeneous (all the same type, with Int widening to Float)." },
23
- { code: 'T0003', name: 'empty-list-needs-annotation', category: 'type', summary: "An empty list '[]' has no element type. Annotate the variable: 'fix xs: List<Int> = []'." },
24
- { code: 'T0004', name: 'condition-not-bool', category: 'type', summary: "The condition in 'if' or 'while' must be of type Bool." },
25
- { code: 'T0005', name: 'if-branch-mismatch', category: 'type', summary: "The 'then' and 'else' branches of 'if' have incompatible types." },
26
- { code: 'T0006', name: 'no-such-method', category: 'type', summary: "The type has no method with this name." },
27
- { code: 'T0007', name: 'wrong-arg-count', category: 'type', summary: "Wrong number of arguments for this method or function call." },
28
- { code: 'T0008', name: 'wrong-arg-type', category: 'type', summary: "An argument has the wrong type for this method or function call." },
29
- { code: 'T0009', name: 'operator-type-error', category: 'type', summary: "An operator was applied to operands of incompatible types." },
30
- { code: 'T0010', name: 'index-requires-list', category: 'type', summary: "The '[ ]' index operator requires a List, but the receiver has a different type." },
31
- { code: 'T0011', name: 'index-not-int', category: 'type', summary: "List indices must be of type Int." },
32
- { code: 'T0012', name: 'no-methods', category: 'type', summary: "This type has no methods." },
3
+ {
4
+ "code": "L0001",
5
+ "name": "unexpected-character",
6
+ "category": "lexical",
7
+ "summary": "A character that isn't part of Ascent.",
8
+ "message": "I don't recognise '{found}' here.",
9
+ "explanation": "Ascent is built from letters, digits, and a small set of symbols like + - * / ( ) { } = . This character isn't one of them.",
10
+ "variants": [
11
+ {
12
+ "when": {
13
+ "equals": "!"
14
+ },
15
+ "explanation": "Ascent doesn't use '!' on its own. It writes \"is not equal to\" as '!=', and flips a True / False value with the word 'not'."
16
+ },
17
+ {
18
+ "when": {
19
+ "equals": "?"
20
+ },
21
+ "explanation": "Ascent doesn't use '?' on its own. It uses '??' to supply a fallback value when something is None."
22
+ }
23
+ ]
24
+ },
25
+ {
26
+ "code": "L0002",
27
+ "name": "invalid-number-literal",
28
+ "category": "lexical",
29
+ "summary": "A number with letters attached, like '123abc'.",
30
+ "message": "I can't read '{found}' as a number.",
31
+ "explanation": "A number in Ascent is made of digits, with an optional '.' for a decimal like 42 or 3.14. This one has letters joined onto it, so it isn't a number.",
32
+ "example": {
33
+ "valid": "42",
34
+ "invalid": "123abc"
35
+ }
36
+ },
37
+ {
38
+ "code": "L0003",
39
+ "name": "unterminated-string",
40
+ "category": "lexical",
41
+ "summary": "A String with no closing \".",
42
+ "message": "This String is missing its closing \".",
43
+ "explanation": "Every String begins and ends with a \". This one has an opening \" but the line ends before a matching \" appears."
44
+ },
45
+ {
46
+ "code": "L0004",
47
+ "name": "missing-integer-part",
48
+ "category": "lexical",
49
+ "summary": "A decimal with no digit before the '.', like '.5'.",
50
+ "message": "This number needs a digit before the '.'.",
51
+ "explanation": "In Ascent a decimal needs a digit on both sides of the '.'. '{found}' has nothing before the '.', so it isn't complete.",
52
+ "fix": {
53
+ "title": "Write '0{found}'",
54
+ "replacement": "0{found}"
55
+ },
56
+ "example": {
57
+ "valid": "0.5",
58
+ "invalid": ".5"
59
+ }
60
+ },
61
+ {
62
+ "code": "N0001",
63
+ "name": "undefined-slot",
64
+ "category": "name",
65
+ "summary": "A name was used before it was created with 'fix' or 'mut'.",
66
+ "message": "I can't find anything named '{found}'.",
67
+ "explanation": "In Ascent a name has to be created before it's used, with 'fix' (a value that never changes) or 'mut' (one you can update later). Check that '{found}' is spelled the same as where you created it, or create it before this line."
68
+ },
69
+ {
70
+ "code": "N0002",
71
+ "name": "reassign-fix",
72
+ "category": "name",
73
+ "summary": "Assignment to a name created with 'fix', whose value never changes.",
74
+ "message": "'{found}' was created with 'fix', so its value can't change.",
75
+ "explanation": "A name created with 'fix' keeps its first value for good — that's what 'fix' means. If '{found}' needs to hold different values over time, create it with 'mut' instead of 'fix' where it was first made.",
76
+ "related": [
77
+ {
78
+ "key": "declaration",
79
+ "label": "'{found}' was created with 'fix' here"
80
+ }
81
+ ]
82
+ },
83
+ {
84
+ "code": "N0003",
85
+ "name": "assign-to-undeclared",
86
+ "category": "name",
87
+ "summary": "Assignment to a name that was never created with 'fix' or 'mut'.",
88
+ "message": "I can't find a name '{found}' to assign to.",
89
+ "explanation": "'=' changes the value of a name that already exists. To create '{found}' and give it a value at the same time, write 'mut {found} = …' (for a value you'll change later) or 'fix {found} = …' (for one that won't). If '{found}' should already exist, check the spelling."
90
+ },
91
+ {
92
+ "code": "N0004",
93
+ "name": "assign-to-arg",
94
+ "category": "name",
95
+ "summary": "Assignment to a program input, which is fixed for the whole run.",
96
+ "message": "'{found}' is a program input, so its value can't change.",
97
+ "explanation": "'{found}' comes from the program's 'args' — it's set once when the program starts and stays the same for the whole run, so it can't be assigned to. To work with a value you can update, make a new name with 'mut' and start it from '{found}', like 'mut total = {found};'."
98
+ },
99
+ {
100
+ "code": "S0001",
101
+ "name": "unclosed-paren",
102
+ "category": "syntactic",
103
+ "summary": "An opening '(' has no matching ')'.",
104
+ "message": "I expected a ')' here.",
105
+ "explanation": "Every '(' has to be closed with a matching ')'. One was opened earlier — around a group like '(a + b)', a call's inputs, or an 'if' or 'while' condition — and this is where its ')' should be.",
106
+ "related": [
107
+ {
108
+ "key": "opener",
109
+ "label": "this '(' was opened here"
110
+ }
111
+ ]
112
+ },
113
+ {
114
+ "code": "S0002",
115
+ "name": "expected-expression",
116
+ "category": "syntactic",
117
+ "summary": "A value was expected here, but there wasn't one.",
118
+ "message": "I expected a value here.",
119
+ "explanation": "This spot needs a value — a number, a String, a name, or something built from them like 'a + b'. Places that need one include just after '=', just after an operator like '+', and inside '( )'."
120
+ },
121
+ {
122
+ "code": "S0003",
123
+ "name": "expected-slot-name",
124
+ "category": "syntactic",
125
+ "summary": "A name was expected after 'fix' or 'mut', or as a program input.",
126
+ "message": "I expected a name here.",
127
+ "explanation": "A name is needed here — after 'fix' or 'mut' to create one ('fix count = 0'), or as the name of a program input ('args (age: Int)'). A name starts with a lowercase letter."
128
+ },
129
+ {
130
+ "code": "S0004",
131
+ "name": "expected-equals",
132
+ "category": "syntactic",
133
+ "summary": "An '=' was expected after the name in a 'fix' or 'mut' declaration.",
134
+ "message": "I expected an '=' here.",
135
+ "explanation": "'fix' and 'mut' give a name its starting value, so the name is followed by '=' and the value, like 'fix count = 0'. (A type can go in between, as in 'fix count: Int = 0'.)"
136
+ },
137
+ {
138
+ "code": "S0005",
139
+ "name": "unclosed-brace",
140
+ "category": "syntactic",
141
+ "summary": "An opening '{' has no matching '}'.",
142
+ "message": "I expected a '}' here.",
143
+ "explanation": "A block groups statements between '{' and '}'. One was opened earlier and this is where its closing '}' should be.",
144
+ "related": [
145
+ {
146
+ "key": "opener",
147
+ "label": "this '{' was opened here"
148
+ }
149
+ ]
150
+ },
151
+ {
152
+ "code": "S0006",
153
+ "name": "expected-test-paren",
154
+ "category": "syntactic",
155
+ "summary": "A '(' was expected to open a condition or an 'args' list.",
156
+ "message": "I expected a '(' here.",
157
+ "explanation": "An 'if' or 'while' condition — and the inputs listed after 'args' — go inside '( )', like 'if (age >= 18) { … }'. This is where that opening '(' should be."
158
+ },
159
+ {
160
+ "code": "S0007",
161
+ "name": "expected-block",
162
+ "category": "syntactic",
163
+ "summary": "A block ('{ … }') was expected here.",
164
+ "message": "I expected a '{' here.",
165
+ "explanation": "The body of an 'if', 'else', or 'while' is always a block between '{' and '}', even when it holds a single line, as in 'if (ok) { … }'."
166
+ },
167
+ {
168
+ "code": "S0008",
169
+ "name": "chained-comparison",
170
+ "category": "syntactic",
171
+ "summary": "Comparisons can't be chained — 'a < b < c' isn't allowed.",
172
+ "message": "I can't chain two comparisons like this.",
173
+ "explanation": "A comparison such as '<' or '==' looks at two values and gives back True or False. Chaining a third one, as in 'a < b < c', would then compare that True or False against another value, which has no clear meaning — so compare two values at a time."
174
+ },
175
+ {
176
+ "code": "S0009",
177
+ "name": "expected-colon",
178
+ "category": "syntactic",
179
+ "summary": "A ':' was expected between a program input's name and its type.",
180
+ "message": "I expected a ':' here.",
181
+ "explanation": "Each program input is written as a name, then ':', then its type, like 'args (age: Int)'. This is where the ':' should be."
182
+ },
183
+ {
184
+ "code": "S0010",
185
+ "name": "expected-type",
186
+ "category": "syntactic",
187
+ "summary": "A type name was expected here.",
188
+ "message": "I expected a type name here.",
189
+ "explanation": "A type name says what kind of value this is. The built-in types are Int, Float, Bool, and String, plus 'List<…>' for a list, as in 'List<Int>'."
190
+ },
191
+ {
192
+ "code": "S0011",
193
+ "name": "expected-semicolon",
194
+ "category": "syntactic",
195
+ "summary": "A ';' was expected to end the statement.",
196
+ "message": "I expected a ';' here.",
197
+ "explanation": "Every statement in Ascent ends with a ';'. It looks like the statement before this point was never finished with one."
198
+ },
199
+ {
200
+ "code": "S0012",
201
+ "name": "expected-method-name",
202
+ "category": "syntactic",
203
+ "summary": "A method name was expected after '.'.",
204
+ "message": "I expected a method name here.",
205
+ "explanation": "A '.' calls a method on a value, so it's followed by the method's name and '( )', like 'items.length()'. A method name starts with a lowercase letter."
206
+ },
207
+ {
208
+ "code": "S0013",
209
+ "name": "unclosed-bracket",
210
+ "category": "syntactic",
211
+ "summary": "An opening '[' has no matching ']'.",
212
+ "message": "I expected a ']' here.",
213
+ "explanation": "Square brackets '[ ]' wrap a list like '[1, 2, 3]' or pick an item out of one like 'items[0]'. One '[' was opened earlier and this is where its ']' should be.",
214
+ "related": [
215
+ {
216
+ "key": "opener",
217
+ "label": "this '[' was opened here"
218
+ }
219
+ ]
220
+ },
221
+ {
222
+ "code": "S0014",
223
+ "name": "expected-call-paren",
224
+ "category": "syntactic",
225
+ "summary": "A method call needs '( )' after the method name.",
226
+ "message": "I expected a '(' here.",
227
+ "explanation": "A '.' calls a method, and a call always has '( )' after the name — even when the method takes no inputs, as in 'items.length()'. This is where that opening '(' should be."
228
+ },
229
+ {
230
+ "code": "T0001",
231
+ "name": "annotation-mismatch",
232
+ "category": "type",
233
+ "summary": "A value's type doesn't match the type expected here (a written annotation, or the name's existing type).",
234
+ "message": "This value has type {actual}, but {expected} was expected here.",
235
+ "explanation": "A value's type has to fit the type asked for in this spot. Here the value is {actual} and {expected} was expected, and those don't match. (An Int can go where a Float is expected, but not the other way around.)",
236
+ "related": [
237
+ {
238
+ "key": "annotation",
239
+ "label": "the type was set to {expected} here"
240
+ },
241
+ {
242
+ "key": "declaration",
243
+ "label": "this was created holding {expected}"
244
+ }
245
+ ]
246
+ },
247
+ {
248
+ "code": "T0002",
249
+ "name": "incompatible-list-elements",
250
+ "category": "type",
251
+ "summary": "A list mixes items of types that have no common type.",
252
+ "message": "The items in this list don't all have the same type.",
253
+ "explanation": "Every item in a list shares one type. Some items here are {first}, but this one is {other}, and those don't fit together. (A mix of Int and Float is fine — the Ints become Floats — but unrelated types like Int and String can't share a list.)",
254
+ "related": [
255
+ {
256
+ "key": "element",
257
+ "label": "this item is {other}"
258
+ }
259
+ ]
260
+ },
261
+ {
262
+ "code": "T0003",
263
+ "name": "empty-list-needs-annotation",
264
+ "category": "type",
265
+ "summary": "An empty list has no items to show its type, and none was written down.",
266
+ "message": "This empty list needs a type.",
267
+ "explanation": "An empty list '[]' has no items to show what it holds, so its type has to be written down — for example 'fix xs: List<Int> = []'."
268
+ },
269
+ {
270
+ "code": "T0004",
271
+ "name": "condition-not-bool",
272
+ "category": "type",
273
+ "summary": "The condition of an 'if' or 'while' isn't a True/False value.",
274
+ "message": "This condition has type {actual}, but it has to be True or False.",
275
+ "explanation": "An 'if' or 'while' chooses what to do from a True/False value, so its condition has to be one — a comparison like 'x > 0', or another Bool. This one has type {actual}."
276
+ },
277
+ {
278
+ "code": "T0005",
279
+ "name": "if-branch-mismatch",
280
+ "category": "type",
281
+ "summary": "The two branches of an 'if' produce different types.",
282
+ "message": "The two branches of this 'if' have different types.",
283
+ "explanation": "When an 'if' is used as a value, both branches have to produce the same type, because the whole 'if' becomes one value. Here one branch gives {then} and the other gives {else}.",
284
+ "related": [
285
+ {
286
+ "key": "then",
287
+ "label": "this branch gives {then}"
288
+ },
289
+ {
290
+ "key": "else",
291
+ "label": "this branch gives {else}"
292
+ }
293
+ ]
294
+ },
295
+ {
296
+ "code": "T0006",
297
+ "name": "no-such-method",
298
+ "category": "type",
299
+ "summary": "A method with this name doesn't exist on the value's type.",
300
+ "message": "{type} has no method called '{method}'.",
301
+ "explanation": "The methods you can call depend on the value's type. For example, an Int has 'toStr()', 'toFloat()', and 'abs()'; a list has 'length()', 'append(…)', 'reverse()', and more. Check the spelling of '{method}'."
302
+ },
303
+ {
304
+ "code": "T0007",
305
+ "name": "wrong-arg-count",
306
+ "category": "type",
307
+ "summary": "A method or function call was given the wrong number of inputs.",
308
+ "message": "This call has the wrong number of inputs.",
309
+ "explanation": "It needs {expected}, but was given {got}. Each input goes inside the '( )', separated by commas."
310
+ },
311
+ {
312
+ "code": "T0008",
313
+ "name": "wrong-arg-type",
314
+ "category": "type",
315
+ "summary": "An input to a method or function has a type that isn't accepted here.",
316
+ "message": "This input has type {actual}, but {expected} was expected.",
317
+ "explanation": "Each method or function accepts inputs of certain types. Here {expected} was expected, but the input given is {actual}."
318
+ },
319
+ {
320
+ "code": "T0009",
321
+ "name": "operator-type-error",
322
+ "category": "type",
323
+ "summary": "An operator was used on types it doesn't accept.",
324
+ "message": "I can't use '{op}' on {operands}.",
325
+ "explanation": "Operators only work on certain types: '+', '-', '*', and '/' need numbers (Int or Float); 'div' and 'mod' need whole numbers (Int); 'and', 'or', and 'not' need True/False values (Bool); and a comparison needs two values of the same kind. '{op}' doesn't work on {operands}."
326
+ },
327
+ {
328
+ "code": "T0010",
329
+ "name": "index-requires-list",
330
+ "category": "type",
331
+ "summary": "The '[ ]' index was used on something that isn't a list.",
332
+ "message": "I can't use '[ ]' here — this has type {actual}, not a list.",
333
+ "explanation": "Reading an item with '[ ]', like 'items[0]', works only on a list. This value has type {actual}, which isn't a list."
334
+ },
335
+ {
336
+ "code": "T0011",
337
+ "name": "index-not-int",
338
+ "category": "type",
339
+ "summary": "A list index isn't an Int.",
340
+ "message": "A list index has to be an Int, but this has type {actual}.",
341
+ "explanation": "Inside 'items[…]', the value in the brackets picks an item by its position, counting from 0, so it has to be a whole number (Int). This one has type {actual}."
342
+ },
343
+ {
344
+ "code": "T0012",
345
+ "name": "no-methods",
346
+ "category": "type",
347
+ "summary": "The value's type has no methods at all.",
348
+ "message": "Values of type {type} don't have any methods.",
349
+ "explanation": "Only some types have methods you can call with '.': Int, Float, and List. A {type} has none, so 'value.something()' can't be used on it."
350
+ },
351
+ {
352
+ "code": "T0013",
353
+ "name": "unknown-function",
354
+ "category": "type",
355
+ "summary": "A call names a function that doesn't exist.",
356
+ "message": "There's no function called '{name}'.",
357
+ "explanation": "Ascent has just one built-in function right now — 'floor(x)', which rounds a Float down to a whole number. Everything else is a method, called on a value with '.', like 'x.toStr()'."
358
+ }
33
359
  ];
34
360
  export const byCode = new Map(ERRORS.map(e => [e.code, e]));
35
361
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Diagnostic } from './elaborate.js';
2
+ export declare function renderTerminal(d: Diagnostic, source: string, filePath: string | null): string;
3
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/errors/render.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AA0BjD,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CA8B7F"}
@@ -0,0 +1,43 @@
1
+ import chalk from 'chalk';
2
+ // One span rendered as its source line plus an underline, with an optional
3
+ // trailing label. `mark` is the underline character and `colour` tints it, so
4
+ // the primary span (red '^') and a supporting span (cyan '-') look distinct.
5
+ function snippet(sourceLines, span, mark, colour, label) {
6
+ const line = sourceLines[span.start.line - 1] ?? '';
7
+ // A span may run to the line end (an unterminated string), so clamp the
8
+ // underline to the visible text of its starting line.
9
+ const endColumn = span.end.line === span.start.line ? span.end.column : line.length + 1;
10
+ const underline = mark.repeat(Math.max(1, endColumn - span.start.column));
11
+ const gutter = String(span.start.line);
12
+ const blank = ' '.repeat(gutter.length);
13
+ const caret = `${' '.repeat(span.start.column - 1)}${colour(underline)}`;
14
+ return [
15
+ `${chalk.dim(`${gutter} |`)} ${line}`,
16
+ `${chalk.dim(`${blank} |`)} ${label !== null ? `${caret} ${colour(label)}` : caret}`,
17
+ ];
18
+ }
19
+ export function renderTerminal(d, source, filePath) {
20
+ const sourceLines = source.split('\n');
21
+ const lines = [];
22
+ lines.push(chalk.red.bold(`Error ${d.code}`) + chalk.bold(`: ${d.message}`));
23
+ const where = filePath !== null
24
+ ? `${filePath}:${d.span.start.line}:${d.span.start.column}`
25
+ : `line ${d.span.start.line}, column ${d.span.start.column}`;
26
+ lines.push(chalk.dim(` → ${where}`));
27
+ lines.push(...snippet(sourceLines, d.span, '^', chalk.red, null));
28
+ // Supporting spans (e.g. "'count' was created with 'fix' here") point back at
29
+ // context elsewhere in the source, each with its own snippet.
30
+ for (const rel of d.related) {
31
+ lines.push(...snippet(sourceLines, rel.span, '-', chalk.cyan, rel.label));
32
+ }
33
+ if (d.explanation !== null) {
34
+ lines.push('');
35
+ lines.push(d.explanation);
36
+ }
37
+ if (d.fix !== null) {
38
+ lines.push('');
39
+ lines.push(chalk.green(`fix: ${d.fix.title}`));
40
+ }
41
+ return lines.join('\n');
42
+ }
43
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/errors/render.ts"],"names":[],"mappings":"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"}