@ascent-lang/dev 0.1.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 (111) hide show
  1. package/README.md +68 -0
  2. package/dist/errors/index.d.ts +4 -0
  3. package/dist/errors/index.d.ts.map +1 -0
  4. package/dist/errors/index.js +35 -0
  5. package/dist/errors/index.js.map +1 -0
  6. package/dist/errors/types.d.ts +9 -0
  7. package/dist/errors/types.d.ts.map +1 -0
  8. package/dist/errors/types.js +5 -0
  9. package/dist/errors/types.js.map +1 -0
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +200 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/interpreter.d.ts +35 -0
  15. package/dist/interpreter.d.ts.map +1 -0
  16. package/dist/interpreter.js +305 -0
  17. package/dist/interpreter.js.map +1 -0
  18. package/dist/lexer/chars.d.ts +6 -0
  19. package/dist/lexer/chars.d.ts.map +1 -0
  20. package/dist/lexer/chars.js +6 -0
  21. package/dist/lexer/chars.js.map +1 -0
  22. package/dist/lexer/cursor.d.ts +16 -0
  23. package/dist/lexer/cursor.d.ts.map +1 -0
  24. package/dist/lexer/cursor.js +43 -0
  25. package/dist/lexer/cursor.js.map +1 -0
  26. package/dist/lexer/index.d.ts +21 -0
  27. package/dist/lexer/index.d.ts.map +1 -0
  28. package/dist/lexer/index.js +163 -0
  29. package/dist/lexer/index.js.map +1 -0
  30. package/dist/lexer/keywords.d.ts +5 -0
  31. package/dist/lexer/keywords.d.ts.map +1 -0
  32. package/dist/lexer/keywords.js +39 -0
  33. package/dist/lexer/keywords.js.map +1 -0
  34. package/dist/lexer/token.d.ts +20 -0
  35. package/dist/lexer/token.d.ts.map +1 -0
  36. package/dist/lexer/token.js +2 -0
  37. package/dist/lexer/token.js.map +1 -0
  38. package/dist/lib.d.ts +14 -0
  39. package/dist/lib.d.ts.map +1 -0
  40. package/dist/lib.js +17 -0
  41. package/dist/lib.js.map +1 -0
  42. package/dist/parser/ast.d.ts +128 -0
  43. package/dist/parser/ast.d.ts.map +1 -0
  44. package/dist/parser/ast.js +2 -0
  45. package/dist/parser/ast.js.map +1 -0
  46. package/dist/parser/expr.d.ts +4 -0
  47. package/dist/parser/expr.d.ts.map +1 -0
  48. package/dist/parser/expr.js +277 -0
  49. package/dist/parser/expr.js.map +1 -0
  50. package/dist/parser/index.d.ts +12 -0
  51. package/dist/parser/index.d.ts.map +1 -0
  52. package/dist/parser/index.js +40 -0
  53. package/dist/parser/index.js.map +1 -0
  54. package/dist/parser/printer.d.ts +7 -0
  55. package/dist/parser/printer.d.ts.map +1 -0
  56. package/dist/parser/printer.js +130 -0
  57. package/dist/parser/printer.js.map +1 -0
  58. package/dist/parser/stmt.d.ts +7 -0
  59. package/dist/parser/stmt.d.ts.map +1 -0
  60. package/dist/parser/stmt.js +153 -0
  61. package/dist/parser/stmt.js.map +1 -0
  62. package/dist/parser/token-stream.d.ts +19 -0
  63. package/dist/parser/token-stream.d.ts.map +1 -0
  64. package/dist/parser/token-stream.js +111 -0
  65. package/dist/parser/token-stream.js.map +1 -0
  66. package/dist/parser/type-expr.d.ts +5 -0
  67. package/dist/parser/type-expr.d.ts.map +1 -0
  68. package/dist/parser/type-expr.js +54 -0
  69. package/dist/parser/type-expr.js.map +1 -0
  70. package/dist/parser/typechecker.d.ts +9 -0
  71. package/dist/parser/typechecker.d.ts.map +1 -0
  72. package/dist/parser/typechecker.js +446 -0
  73. package/dist/parser/typechecker.js.map +1 -0
  74. package/dist/parser/typed-ast.d.ts +130 -0
  75. package/dist/parser/typed-ast.d.ts.map +1 -0
  76. package/dist/parser/typed-ast.js +2 -0
  77. package/dist/parser/typed-ast.js.map +1 -0
  78. package/dist/parser/typed-printer.d.ts +3 -0
  79. package/dist/parser/typed-printer.d.ts.map +1 -0
  80. package/dist/parser/typed-printer.js +91 -0
  81. package/dist/parser/typed-printer.js.map +1 -0
  82. package/dist/types/types.d.ts +28 -0
  83. package/dist/types/types.d.ts.map +1 -0
  84. package/dist/types/types.js +48 -0
  85. package/dist/types/types.js.map +1 -0
  86. package/package.json +70 -0
  87. package/src/errors/index.ts +38 -0
  88. package/src/errors/lexical.yml +16 -0
  89. package/src/errors/name.yml +11 -0
  90. package/src/errors/syntactic.yml +66 -0
  91. package/src/errors/typechecker.yml +61 -0
  92. package/src/errors/types.ts +13 -0
  93. package/src/index.ts +213 -0
  94. package/src/interpreter.ts +332 -0
  95. package/src/lexer/chars.ts +12 -0
  96. package/src/lexer/cursor.ts +51 -0
  97. package/src/lexer/index.ts +174 -0
  98. package/src/lexer/keywords.ts +43 -0
  99. package/src/lexer/token.ts +62 -0
  100. package/src/lib.ts +33 -0
  101. package/src/parser/ast.ts +64 -0
  102. package/src/parser/expr.ts +313 -0
  103. package/src/parser/index.ts +50 -0
  104. package/src/parser/printer.ts +146 -0
  105. package/src/parser/stmt.ts +176 -0
  106. package/src/parser/token-stream.ts +121 -0
  107. package/src/parser/type-expr.ts +63 -0
  108. package/src/parser/typechecker.ts +406 -0
  109. package/src/parser/typed-ast.ts +63 -0
  110. package/src/parser/typed-printer.ts +105 -0
  111. package/src/types/types.ts +65 -0
@@ -0,0 +1,91 @@
1
+ import chalk from 'chalk';
2
+ import { typeToString } from '../types/types.js';
3
+ import { branch } from './printer.js';
4
+ // Appends the inferred type as a dim annotation on a node label.
5
+ const ty = (t) => chalk.dim(`: ${t}`);
6
+ const typedExprLines = (expr) => {
7
+ const t = ty(typeToString(expr.type));
8
+ switch (expr.kind) {
9
+ case 'literal':
10
+ switch (expr.valueType) {
11
+ case 'Int': return [`${chalk.cyan('Lit')} ${chalk.yellow(String(expr.value))}${t}`];
12
+ case 'Float': return [`${chalk.cyan('Lit')} ${chalk.yellow(String(expr.value))}${t}`];
13
+ case 'Bool': return [`${chalk.cyan('Lit')} ${chalk.yellow(expr.value ? 'True' : 'False')}${t}`];
14
+ case 'String': return [`${chalk.cyan('Lit')} ${chalk.green(JSON.stringify(expr.value))}${t}`];
15
+ case 'None': return [`${chalk.cyan('Lit')} ${chalk.yellow('None')}${t}`];
16
+ case 'Done': return [`${chalk.cyan('Lit')} ${chalk.yellow('Done')}${t}`];
17
+ }
18
+ case 'slot':
19
+ return [`${chalk.cyan('Slot')} ${chalk.green(expr.name)}${t}`];
20
+ case 'call': {
21
+ const argLines = expr.args.flatMap((arg, i) => branch(typedExprLines(arg), i === expr.args.length - 1));
22
+ return [`${chalk.cyan('Call')} ${chalk.green(expr.callee)}${t}`, ...argLines];
23
+ }
24
+ case 'methodCall': {
25
+ const children = [expr.receiver, ...expr.args];
26
+ const childLines = children.flatMap((child, i) => branch(typedExprLines(child), i === children.length - 1));
27
+ return [`${chalk.cyan('MethodCall')} ${chalk.green('.' + expr.method)}${t}`, ...childLines];
28
+ }
29
+ case 'list': {
30
+ if (expr.elements.length === 0) {
31
+ return [`${chalk.cyan('List')} ${chalk.dim('[]')}${t}`];
32
+ }
33
+ const elementLines = expr.elements.flatMap((el, i) => branch(typedExprLines(el), i === expr.elements.length - 1));
34
+ return [`${chalk.cyan('List')}${t}`, ...elementLines];
35
+ }
36
+ case 'index': {
37
+ const listLines = branch(typedExprLines(expr.list), false);
38
+ const indexLines = branch(typedExprLines(expr.index), true);
39
+ return [`${chalk.cyan('Index')}${t}`, ...listLines, ...indexLines];
40
+ }
41
+ case 'unary': {
42
+ const operandLines = branch(typedExprLines(expr.operand), true);
43
+ return [`${chalk.cyan('Unary')} ${chalk.magenta(expr.op)}${t}`, ...operandLines];
44
+ }
45
+ case 'binary': {
46
+ const leftLines = branch(typedExprLines(expr.left), false);
47
+ const rightLines = branch(typedExprLines(expr.right), true);
48
+ return [`${chalk.cyan('Binary')} ${chalk.magenta(expr.op)}${t}`, ...leftLines, ...rightLines];
49
+ }
50
+ case 'block': {
51
+ if (expr.stmts.length === 0) {
52
+ return [`${chalk.cyan('Block')} ${chalk.dim('(empty)')}${t}`];
53
+ }
54
+ const stmtLines = expr.stmts.flatMap((stmt, i) => branch(typedStmtLines(stmt), i === expr.stmts.length - 1));
55
+ return [`${chalk.cyan('Block')}${t}`, ...stmtLines];
56
+ }
57
+ case 'if': {
58
+ const condLines = branch(typedExprLines(expr.cond), false);
59
+ const thenLines = branch(typedExprLines(expr.then), expr.else === null);
60
+ const elseLines = expr.else !== null
61
+ ? branch(typedExprLines(expr.else), true)
62
+ : [];
63
+ return [`${chalk.cyan('If')}${t}`, ...condLines, ...thenLines, ...elseLines];
64
+ }
65
+ }
66
+ };
67
+ const typedStmtLines = (stmt) => {
68
+ switch (stmt.kind) {
69
+ case 'fix':
70
+ case 'mut': {
71
+ const label = stmt.kind === 'fix' ? 'Fix' : 'Mut';
72
+ const slotTy = ty(typeToString(stmt.slotType));
73
+ const initLines = branch(typedExprLines(stmt.init), true);
74
+ return [`${chalk.cyan(label)} ${chalk.green(stmt.name)}${slotTy}`, ...initLines];
75
+ }
76
+ case 'assign': {
77
+ const slotTy = ty(typeToString(stmt.slotType));
78
+ const valueLines = branch(typedExprLines(stmt.value), true);
79
+ return [`${chalk.cyan('Assign')} ${chalk.green(stmt.name)}${slotTy}`, ...valueLines];
80
+ }
81
+ case 'expr':
82
+ return typedExprLines(stmt.expr);
83
+ case 'while': {
84
+ const condLines = branch(typedExprLines(stmt.cond), false);
85
+ const bodyLines = branch(typedExprLines(stmt.body), true);
86
+ return [`${chalk.cyan('While')}`, ...condLines, ...bodyLines];
87
+ }
88
+ }
89
+ };
90
+ export const formatTypedStmt = (stmt) => typedStmtLines(stmt).join('\n');
91
+ //# sourceMappingURL=typed-printer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typed-printer.js","sourceRoot":"","sources":["../../src/parser/typed-printer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ export type AscentType = {
2
+ kind: 'Int';
3
+ } | {
4
+ kind: 'Float';
5
+ } | {
6
+ kind: 'Bool';
7
+ } | {
8
+ kind: 'String';
9
+ } | {
10
+ kind: 'None';
11
+ } | {
12
+ kind: 'Done';
13
+ } | {
14
+ kind: 'List';
15
+ elem: AscentType;
16
+ };
17
+ export declare const INT_TYPE: AscentType;
18
+ export declare const FLOAT_TYPE: AscentType;
19
+ export declare const BOOL_TYPE: AscentType;
20
+ export declare const STRING_TYPE: AscentType;
21
+ export declare const NONE_TYPE: AscentType;
22
+ export declare const DONE_TYPE: AscentType;
23
+ export declare const listOfType: (elem: AscentType) => AscentType;
24
+ export declare const typeToString: (t: AscentType) => string;
25
+ export declare const typesEqual: (a: AscentType, b: AscentType) => boolean;
26
+ export declare const leastCommonType: (a: AscentType, b: AscentType) => AscentType | null;
27
+ export declare const isAssignableTo: (from: AscentType, to: AscentType) => boolean;
28
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC;AAEvC,eAAO,MAAM,QAAQ,EAAE,UAA4B,CAAC;AACpD,eAAO,MAAM,UAAU,EAAE,UAA8B,CAAC;AACxD,eAAO,MAAM,SAAS,EAAE,UAA6B,CAAC;AACtD,eAAO,MAAM,WAAW,EAAE,UAA+B,CAAC;AAC1D,eAAO,MAAM,SAAS,EAAE,UAA6B,CAAC;AACtD,eAAO,MAAM,SAAS,EAAE,UAA6B,CAAC;AACtD,eAAO,MAAM,UAAU,GAAI,MAAM,UAAU,KAAG,UAAsC,CAAC;AAErF,eAAO,MAAM,YAAY,GAAI,GAAG,UAAU,KAAG,MAK5C,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,GAAG,UAAU,EAAE,GAAG,UAAU,KAAG,OAUzD,CAAC;AAKF,eAAO,MAAM,eAAe,GAAI,GAAG,UAAU,EAAE,GAAG,UAAU,KAAG,UAAU,GAAG,IAkB3E,CAAC;AAIF,eAAO,MAAM,cAAc,GAAI,MAAM,UAAU,EAAE,IAAI,UAAU,KAAG,OAGjE,CAAC"}
@@ -0,0 +1,48 @@
1
+ export const INT_TYPE = { kind: 'Int' };
2
+ export const FLOAT_TYPE = { kind: 'Float' };
3
+ export const BOOL_TYPE = { kind: 'Bool' };
4
+ export const STRING_TYPE = { kind: 'String' };
5
+ export const NONE_TYPE = { kind: 'None' };
6
+ export const DONE_TYPE = { kind: 'Done' };
7
+ export const listOfType = (elem) => ({ kind: 'List', elem });
8
+ export const typeToString = (t) => {
9
+ if (t.kind === 'List') {
10
+ return `List<${typeToString(t.elem)}>`;
11
+ }
12
+ return t.kind;
13
+ };
14
+ export const typesEqual = (a, b) => {
15
+ if (a.kind !== b.kind) {
16
+ return false;
17
+ }
18
+ if (a.kind === 'List' && b.kind === 'List') {
19
+ return typesEqual(a.elem, b.elem);
20
+ }
21
+ return true;
22
+ };
23
+ // Int widens to Float everywhere — the only implicit numeric promotion.
24
+ // List<Int> widens to List<Float> via the same rule applied recursively.
25
+ // Returns null when the two types have no common supertype.
26
+ export const leastCommonType = (a, b) => {
27
+ if (typesEqual(a, b)) {
28
+ return a;
29
+ }
30
+ if (a.kind === 'Int' && b.kind === 'Float') {
31
+ return FLOAT_TYPE;
32
+ }
33
+ if (a.kind === 'Float' && b.kind === 'Int') {
34
+ return FLOAT_TYPE;
35
+ }
36
+ if (a.kind === 'List' && b.kind === 'List') {
37
+ const elem = leastCommonType(a.elem, b.elem);
38
+ return elem !== null ? listOfType(elem) : null;
39
+ }
40
+ return null;
41
+ };
42
+ // `from` is assignable to `to` when their LCT is exactly `to`
43
+ // (i.e., `from` fits inside `to`, possibly by widening).
44
+ export const isAssignableTo = (from, to) => {
45
+ const lct = leastCommonType(from, to);
46
+ return lct !== null && typesEqual(lct, to);
47
+ };
48
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types/types.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,QAAQ,GAAe,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACpD,MAAM,CAAC,MAAM,UAAU,GAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACxD,MAAM,CAAC,MAAM,SAAS,GAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACtD,MAAM,CAAC,MAAM,WAAW,GAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC1D,MAAM,CAAC,MAAM,SAAS,GAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACtD,MAAM,CAAC,MAAM,SAAS,GAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACtD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAgB,EAAc,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAErF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAa,EAAU,EAAE;IACpD,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,QAAQ,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IACzC,CAAC;IACD,OAAO,CAAC,CAAC,IAAI,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAa,EAAE,CAAa,EAAW,EAAE;IAClE,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3C,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,wEAAwE;AACxE,yEAAyE;AACzE,4DAA4D;AAC5D,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAa,EAAE,CAAa,EAAqB,EAAE;IACjF,IAAI,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3C,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC3C,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7C,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,8DAA8D;AAC9D,yDAAyD;AACzD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAgB,EAAE,EAAc,EAAW,EAAE;IAC1E,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACtC,OAAO,GAAG,KAAK,IAAI,IAAI,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAC7C,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@ascent-lang/dev",
3
+ "version": "0.1.0",
4
+ "description": "The Ascent teaching language: CLI and interpreter for running and embedding .asc programs.",
5
+ "type": "module",
6
+ "main": "dist/lib.js",
7
+ "types": "dist/lib.d.ts",
8
+ "bin": {
9
+ "ascent": "dist/index.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/lib.d.ts",
14
+ "default": "./dist/lib.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "src",
20
+ "README.md"
21
+ ],
22
+ "engines": {
23
+ "node": ">=20"
24
+ },
25
+ "directories": {
26
+ "doc": "docs"
27
+ },
28
+ "scripts": {
29
+ "generate": "tsx scripts/gen-errors.ts",
30
+ "clean": "rm -rf dist",
31
+ "prebuild": "npm run generate",
32
+ "build": "tsc",
33
+ "dev": "tsx src/index.ts",
34
+ "prestart": "tsx scripts/gen-errors.ts",
35
+ "start": "tsx src/index.ts",
36
+ "prepublishOnly": "npm run clean && npm run build",
37
+ "test": "echo \"Error: no test specified\" && exit 1"
38
+ },
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/podlomar/ascent-lang.git"
42
+ },
43
+ "keywords": [
44
+ "ascent",
45
+ "language",
46
+ "interpreter",
47
+ "teaching",
48
+ "education",
49
+ "cli"
50
+ ],
51
+ "author": "Martin Podloucký",
52
+ "license": "ISC",
53
+ "bugs": {
54
+ "url": "https://github.com/podlomar/ascent-lang/issues"
55
+ },
56
+ "homepage": "https://github.com/podlomar/ascent-lang#readme",
57
+ "publishConfig": {
58
+ "access": "public"
59
+ },
60
+ "devDependencies": {
61
+ "@types/node": "^26.0.1",
62
+ "tsx": "^4.22.4",
63
+ "typescript": "^6.0.3",
64
+ "typescript-yaml-plugin": "^1.0.11",
65
+ "yaml": "^2.9.0"
66
+ },
67
+ "dependencies": {
68
+ "chalk": "^5.6.2"
69
+ }
70
+ }
@@ -0,0 +1,38 @@
1
+ // AUTO-GENERATED — do not edit. Run `npm run generate` to update.
2
+
3
+ import type { ErrorEntry } from './types.js';
4
+
5
+ export const ERRORS: ErrorEntry[] = [
6
+ { code: 'L0001', name: 'unexpected-character', category: 'lexical', summary: "A character that can't begin any token." },
7
+ { code: 'L0002', name: 'invalid-number-literal', category: 'lexical', summary: "A letter immediately followed a number — '123abc' is not a valid token." },
8
+ { code: 'L0003', name: 'unterminated-string', category: 'lexical', summary: "A string literal that doesn't end before the end of the line." },
9
+ { code: 'N0001', name: 'undefined-slot', category: 'name', summary: "A name was used that has not been declared with 'fix' or 'mut'." },
10
+ { 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." },
11
+ { code: 'S0001', name: 'unclosed-paren', category: 'syntactic', summary: "An opening '(' has no matching ')'." },
12
+ { code: 'S0002', name: 'expected-expression', category: 'syntactic', summary: "An expression was required here but the input contained none." },
13
+ { code: 'S0003', name: 'expected-slot-name', category: 'syntactic', summary: "A slot name (lowercase identifier) was expected after 'fix'." },
14
+ { code: 'S0004', name: 'expected-equals', category: 'syntactic', summary: "An '=' was expected after the slot name in a 'fix' declaration." },
15
+ { code: 'S0005', name: 'unclosed-brace', category: 'syntactic', summary: "An opening '{' has no matching '}'." },
16
+ { code: 'S0006', name: 'expected-test-paren', category: 'syntactic', summary: "An '(' was expected here to start the condition." },
17
+ { code: 'S0007', name: 'expected-block', category: 'syntactic', summary: "A block ('{ … }') was expected here." },
18
+ { code: 'S0008', name: 'chained-comparison', category: 'syntactic', summary: "Comparisons don't chain — 'a < b < c' isn't valid. Group with parentheses instead." },
19
+ { code: 'S0009', name: 'expected-colon', category: 'syntactic', summary: "A ':' was expected between the argument name and its type." },
20
+ { code: 'S0010', name: 'expected-type', category: 'syntactic', summary: "A type name was expected here. Valid types are Int, Float, Bool, String, and List<T>." },
21
+ { code: 'S0011', name: 'expected-semicolon', category: 'syntactic', summary: "A ';' was expected here." },
22
+ { code: 'S0012', name: 'expected-method-name', category: 'syntactic', summary: "A method name (lowercase identifier) was expected after '.'." },
23
+ { code: 'S0013', name: 'unclosed-bracket', category: 'syntactic', summary: "An opening '[' has no matching ']'." },
24
+ { code: 'T0001', name: 'annotation-mismatch', category: 'type', summary: "The declared type annotation doesn't match the inferred type of the initialiser." },
25
+ { 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)." },
26
+ { code: 'T0003', name: 'empty-list-needs-annotation', category: 'type', summary: "An empty list '[]' has no element type. Annotate the variable: 'fix xs: List<Int> = []'." },
27
+ { code: 'T0004', name: 'condition-not-bool', category: 'type', summary: "The condition in 'if' or 'while' must be of type Bool." },
28
+ { code: 'T0005', name: 'if-branch-mismatch', category: 'type', summary: "The 'then' and 'else' branches of 'if' have incompatible types." },
29
+ { code: 'T0006', name: 'no-such-method', category: 'type', summary: "The type has no method with this name." },
30
+ { code: 'T0007', name: 'wrong-arg-count', category: 'type', summary: "Wrong number of arguments for this method or function call." },
31
+ { code: 'T0008', name: 'wrong-arg-type', category: 'type', summary: "An argument has the wrong type for this method or function call." },
32
+ { code: 'T0009', name: 'operator-type-error', category: 'type', summary: "An operator was applied to operands of incompatible types." },
33
+ { code: 'T0010', name: 'index-requires-list', category: 'type', summary: "The '[ ]' index operator requires a List, but the receiver has a different type." },
34
+ { code: 'T0011', name: 'index-not-int', category: 'type', summary: "List indices must be of type Int." },
35
+ { code: 'T0012', name: 'no-methods', category: 'type', summary: "This type has no methods." },
36
+ ];
37
+
38
+ export const byCode = new Map(ERRORS.map(e => [e.code, e]));
@@ -0,0 +1,16 @@
1
+ # L — lexical: the characters don't form a valid token
2
+
3
+ - code: 'L0001'
4
+ name: 'unexpected-character'
5
+ category: 'lexical'
6
+ summary: "A character that can't begin any token."
7
+
8
+ - code: 'L0002'
9
+ name: 'invalid-number-literal'
10
+ category: 'lexical'
11
+ summary: "A letter immediately followed a number — '123abc' is not a valid token."
12
+
13
+ - code: 'L0003'
14
+ name: 'unterminated-string'
15
+ category: 'lexical'
16
+ summary: "A string literal that doesn't end before the end of the line."
@@ -0,0 +1,11 @@
1
+ # N — name & binding: a name/slot rule is broken
2
+
3
+ - code: 'N0001'
4
+ name: 'undefined-slot'
5
+ category: 'name'
6
+ summary: "A name was used that has not been declared with 'fix' or 'mut'."
7
+
8
+ - code: 'N0002'
9
+ name: 'reassign-fix'
10
+ category: 'name'
11
+ summary: "Assignment to a slot declared with 'fix' — 'fix' slots never change; declare it with 'mut' instead if it needs to."
@@ -0,0 +1,66 @@
1
+ # S — syntactic: the tokens don't form a valid expression
2
+
3
+ - code: 'S0001'
4
+ name: 'unclosed-paren'
5
+ category: 'syntactic'
6
+ summary: "An opening '(' has no matching ')'."
7
+
8
+ - code: 'S0002'
9
+ name: 'expected-expression'
10
+ category: 'syntactic'
11
+ summary: 'An expression was required here but the input contained none.'
12
+
13
+ - code: 'S0003'
14
+ name: 'expected-slot-name'
15
+ category: 'syntactic'
16
+ summary: "A slot name (lowercase identifier) was expected after 'fix'."
17
+
18
+ - code: 'S0004'
19
+ name: 'expected-equals'
20
+ category: 'syntactic'
21
+ summary: "An '=' was expected after the slot name in a 'fix' declaration."
22
+
23
+ - code: 'S0005'
24
+ name: 'unclosed-brace'
25
+ category: 'syntactic'
26
+ summary: "An opening '{' has no matching '}'."
27
+
28
+ - code: 'S0006'
29
+ name: 'expected-test-paren'
30
+ category: 'syntactic'
31
+ summary: "An '(' was expected here to start the condition."
32
+
33
+ - code: 'S0007'
34
+ name: 'expected-block'
35
+ category: 'syntactic'
36
+ summary: "A block ('{ … }') was expected here."
37
+
38
+ - code: 'S0008'
39
+ name: 'chained-comparison'
40
+ category: 'syntactic'
41
+ summary: "Comparisons don't chain — 'a < b < c' isn't valid. Group with parentheses instead."
42
+
43
+ - code: 'S0009'
44
+ name: 'expected-colon'
45
+ category: 'syntactic'
46
+ summary: "A ':' was expected between the argument name and its type."
47
+
48
+ - code: 'S0010'
49
+ name: 'expected-type'
50
+ category: 'syntactic'
51
+ summary: "A type name was expected here. Valid types are Int, Float, Bool, String, and List<T>."
52
+
53
+ - code: 'S0011'
54
+ name: 'expected-semicolon'
55
+ category: 'syntactic'
56
+ summary: "A ';' was expected here."
57
+
58
+ - code: 'S0012'
59
+ name: 'expected-method-name'
60
+ category: 'syntactic'
61
+ summary: "A method name (lowercase identifier) was expected after '.'."
62
+
63
+ - code: 'S0013'
64
+ name: 'unclosed-bracket'
65
+ category: 'syntactic'
66
+ summary: "An opening '[' has no matching ']'."
@@ -0,0 +1,61 @@
1
+ # T — type: a type rule is broken
2
+
3
+ - code: 'T0001'
4
+ name: 'annotation-mismatch'
5
+ category: 'type'
6
+ summary: "The declared type annotation doesn't match the inferred type of the initialiser."
7
+
8
+ - code: 'T0002'
9
+ name: 'incompatible-list-elements'
10
+ category: 'type'
11
+ summary: "List elements have incompatible types — a list must be homogeneous (all the same type, with Int widening to Float)."
12
+
13
+ - code: 'T0003'
14
+ name: 'empty-list-needs-annotation'
15
+ category: 'type'
16
+ summary: "An empty list '[]' has no element type. Annotate the variable: 'fix xs: List<Int> = []'."
17
+
18
+ - code: 'T0004'
19
+ name: 'condition-not-bool'
20
+ category: 'type'
21
+ summary: "The condition in 'if' or 'while' must be of type Bool."
22
+
23
+ - code: 'T0005'
24
+ name: 'if-branch-mismatch'
25
+ category: 'type'
26
+ summary: "The 'then' and 'else' branches of 'if' have incompatible types."
27
+
28
+ - code: 'T0006'
29
+ name: 'no-such-method'
30
+ category: 'type'
31
+ summary: "The type has no method with this name."
32
+
33
+ - code: 'T0007'
34
+ name: 'wrong-arg-count'
35
+ category: 'type'
36
+ summary: "Wrong number of arguments for this method or function call."
37
+
38
+ - code: 'T0008'
39
+ name: 'wrong-arg-type'
40
+ category: 'type'
41
+ summary: "An argument has the wrong type for this method or function call."
42
+
43
+ - code: 'T0009'
44
+ name: 'operator-type-error'
45
+ category: 'type'
46
+ summary: "An operator was applied to operands of incompatible types."
47
+
48
+ - code: 'T0010'
49
+ name: 'index-requires-list'
50
+ category: 'type'
51
+ summary: "The '[ ]' index operator requires a List, but the receiver has a different type."
52
+
53
+ - code: 'T0011'
54
+ name: 'index-not-int'
55
+ category: 'type'
56
+ summary: "List indices must be of type Int."
57
+
58
+ - code: 'T0012'
59
+ name: 'no-methods'
60
+ category: 'type'
61
+ summary: "This type has no methods."
@@ -0,0 +1,13 @@
1
+ // Append-only registry of every diagnostic code emitted by this stage.
2
+ // A code is permanent — never reused, never renumbered, never deleted.
3
+ // To retire one, set retired: true and leave the row in the YAML.
4
+
5
+ export type Category = 'lexical' | 'syntactic' | 'name' | 'type' | 'runtime';
6
+
7
+ export interface ErrorEntry {
8
+ code: string;
9
+ name: string;
10
+ category: Category;
11
+ summary: string;
12
+ retired?: boolean;
13
+ }