@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.
- package/README.md +68 -0
- package/dist/errors/index.d.ts +4 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +35 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/types.d.ts +9 -0
- package/dist/errors/types.d.ts.map +1 -0
- package/dist/errors/types.js +5 -0
- package/dist/errors/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +200 -0
- package/dist/index.js.map +1 -0
- package/dist/interpreter.d.ts +35 -0
- package/dist/interpreter.d.ts.map +1 -0
- package/dist/interpreter.js +305 -0
- package/dist/interpreter.js.map +1 -0
- package/dist/lexer/chars.d.ts +6 -0
- package/dist/lexer/chars.d.ts.map +1 -0
- package/dist/lexer/chars.js +6 -0
- package/dist/lexer/chars.js.map +1 -0
- package/dist/lexer/cursor.d.ts +16 -0
- package/dist/lexer/cursor.d.ts.map +1 -0
- package/dist/lexer/cursor.js +43 -0
- package/dist/lexer/cursor.js.map +1 -0
- package/dist/lexer/index.d.ts +21 -0
- package/dist/lexer/index.d.ts.map +1 -0
- package/dist/lexer/index.js +163 -0
- package/dist/lexer/index.js.map +1 -0
- package/dist/lexer/keywords.d.ts +5 -0
- package/dist/lexer/keywords.d.ts.map +1 -0
- package/dist/lexer/keywords.js +39 -0
- package/dist/lexer/keywords.js.map +1 -0
- package/dist/lexer/token.d.ts +20 -0
- package/dist/lexer/token.d.ts.map +1 -0
- package/dist/lexer/token.js +2 -0
- package/dist/lexer/token.js.map +1 -0
- package/dist/lib.d.ts +14 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +17 -0
- package/dist/lib.js.map +1 -0
- package/dist/parser/ast.d.ts +128 -0
- package/dist/parser/ast.d.ts.map +1 -0
- package/dist/parser/ast.js +2 -0
- package/dist/parser/ast.js.map +1 -0
- package/dist/parser/expr.d.ts +4 -0
- package/dist/parser/expr.d.ts.map +1 -0
- package/dist/parser/expr.js +277 -0
- package/dist/parser/expr.js.map +1 -0
- package/dist/parser/index.d.ts +12 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +40 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/printer.d.ts +7 -0
- package/dist/parser/printer.d.ts.map +1 -0
- package/dist/parser/printer.js +130 -0
- package/dist/parser/printer.js.map +1 -0
- package/dist/parser/stmt.d.ts +7 -0
- package/dist/parser/stmt.d.ts.map +1 -0
- package/dist/parser/stmt.js +153 -0
- package/dist/parser/stmt.js.map +1 -0
- package/dist/parser/token-stream.d.ts +19 -0
- package/dist/parser/token-stream.d.ts.map +1 -0
- package/dist/parser/token-stream.js +111 -0
- package/dist/parser/token-stream.js.map +1 -0
- package/dist/parser/type-expr.d.ts +5 -0
- package/dist/parser/type-expr.d.ts.map +1 -0
- package/dist/parser/type-expr.js +54 -0
- package/dist/parser/type-expr.js.map +1 -0
- package/dist/parser/typechecker.d.ts +9 -0
- package/dist/parser/typechecker.d.ts.map +1 -0
- package/dist/parser/typechecker.js +446 -0
- package/dist/parser/typechecker.js.map +1 -0
- package/dist/parser/typed-ast.d.ts +130 -0
- package/dist/parser/typed-ast.d.ts.map +1 -0
- package/dist/parser/typed-ast.js +2 -0
- package/dist/parser/typed-ast.js.map +1 -0
- package/dist/parser/typed-printer.d.ts +3 -0
- package/dist/parser/typed-printer.d.ts.map +1 -0
- package/dist/parser/typed-printer.js +91 -0
- package/dist/parser/typed-printer.js.map +1 -0
- package/dist/types/types.d.ts +28 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +48 -0
- package/dist/types/types.js.map +1 -0
- package/package.json +70 -0
- package/src/errors/index.ts +38 -0
- package/src/errors/lexical.yml +16 -0
- package/src/errors/name.yml +11 -0
- package/src/errors/syntactic.yml +66 -0
- package/src/errors/typechecker.yml +61 -0
- package/src/errors/types.ts +13 -0
- package/src/index.ts +213 -0
- package/src/interpreter.ts +332 -0
- package/src/lexer/chars.ts +12 -0
- package/src/lexer/cursor.ts +51 -0
- package/src/lexer/index.ts +174 -0
- package/src/lexer/keywords.ts +43 -0
- package/src/lexer/token.ts +62 -0
- package/src/lib.ts +33 -0
- package/src/parser/ast.ts +64 -0
- package/src/parser/expr.ts +313 -0
- package/src/parser/index.ts +50 -0
- package/src/parser/printer.ts +146 -0
- package/src/parser/stmt.ts +176 -0
- package/src/parser/token-stream.ts +121 -0
- package/src/parser/type-expr.ts +63 -0
- package/src/parser/typechecker.ts +406 -0
- package/src/parser/typed-ast.ts +63 -0
- package/src/parser/typed-printer.ts +105 -0
- package/src/types/types.ts +65 -0
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Ascent: The Teaching Language
|
|
2
|
+
|
|
3
|
+
> *Ascent is a programming language built to teach programming to complete beginners. The goal is to do it clearly, gently, and from the ground up.*
|
|
4
|
+
|
|
5
|
+
## ⚠️ Experimental
|
|
6
|
+
|
|
7
|
+
`@ascent-lang/dev` is an experimental package intended for rapid development and language exploration.
|
|
8
|
+
|
|
9
|
+
During this phase, the language syntax, parser, interpreter, APIs, and project structure may change frequently between releases. Breaking changes may occur at any time, and version numbers should not be interpreted as indicators of API stability.
|
|
10
|
+
|
|
11
|
+
This package is primarily intended for:
|
|
12
|
+
- experimenting with new language features,
|
|
13
|
+
- testing language design ideas,
|
|
14
|
+
- early adopters interested in following development.
|
|
15
|
+
|
|
16
|
+
Once the language and architecture mature, functionality will be split into dedicated packages such as `@ascent-lang/parser`, `@ascent-lang/interpreter`, and `@ascent-lang/core`, which will follow a more stable versioning and compatibility policy.
|
|
17
|
+
|
|
18
|
+
Until then, expect frequent changes and be prepared to update your code when upgrading to newer releases.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install -g @ascent-lang/dev
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or run it once without installing:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx @ascent-lang/dev path/to/program.asc
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Using the CLI
|
|
33
|
+
|
|
34
|
+
Run a `.asc` file:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
ascent program.asc
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If the program declares `args`, pass them as flags:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
ascent program.asc --name Ada --score 95
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Start the interactive REPL by running `ascent` with no file:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
ascent
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Using it as a library
|
|
53
|
+
|
|
54
|
+
The individual pipeline stages are exported from the package entry point,
|
|
55
|
+
so you can lex, parse, type-check, and interpret Ascent source from your own
|
|
56
|
+
tooling:
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
import { Lexer, Parser, typecheck, executeProgram, Environment } from '@ascent-lang/dev';
|
|
60
|
+
|
|
61
|
+
const source = '1 + 2';
|
|
62
|
+
const { tokens } = new Lexer(source).tokenize();
|
|
63
|
+
const { program } = new Parser(tokens).parse();
|
|
64
|
+
const { typedProgram } = typecheck(program);
|
|
65
|
+
const result = executeProgram(typedProgram, new Environment());
|
|
66
|
+
|
|
67
|
+
console.log(result); // { type: 'Int', value: 3n }
|
|
68
|
+
```
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// AUTO-GENERATED — do not edit. Run `npm run generate` to update.
|
|
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." },
|
|
33
|
+
];
|
|
34
|
+
export const byCode = new Map(ERRORS.map(e => [e.code, e]));
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/errors/types.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/errors/types.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,uEAAuE;AACvE,kEAAkE"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createInterface } from 'node:readline/promises';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { Lexer } from './lexer/index.js';
|
|
6
|
+
import { Parser } from './parser/index.js';
|
|
7
|
+
import { typecheck } from './parser/typechecker.js';
|
|
8
|
+
import { formatValue } from './parser/printer.js';
|
|
9
|
+
import { formatTypedStmt } from './parser/typed-printer.js';
|
|
10
|
+
import { executeStmt, executeProgram, Environment } from './interpreter.js';
|
|
11
|
+
// \x01 and \x02 bracket invisible bytes so readline counts the visible
|
|
12
|
+
// width of the prompt correctly — without them cursor positioning breaks.
|
|
13
|
+
const PROMPT = `\x01${chalk.bold.green('>')}\x02 `;
|
|
14
|
+
// Parses '--name value' pairs from argv into a name→raw-string map.
|
|
15
|
+
const parseCliFlags = (argv) => {
|
|
16
|
+
const flags = new Map();
|
|
17
|
+
for (let i = 0; i < argv.length; i++) {
|
|
18
|
+
const arg = argv[i];
|
|
19
|
+
if (arg.startsWith('--')) {
|
|
20
|
+
const name = arg.slice(2);
|
|
21
|
+
const next = argv[i + 1];
|
|
22
|
+
if (next !== undefined && !next.startsWith('--')) {
|
|
23
|
+
flags.set(name, next);
|
|
24
|
+
i++;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
flags.set(name, 'true'); // bare flag → boolean
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return flags;
|
|
32
|
+
};
|
|
33
|
+
// Converts raw CLI strings to RuntimeValues according to each ArgDef,
|
|
34
|
+
// then declares them as fixed slots. Exits on missing or ill-typed args.
|
|
35
|
+
const bindArgs = (argDefs, cliFlags, env) => {
|
|
36
|
+
for (const def of argDefs) {
|
|
37
|
+
const raw = cliFlags.get(def.name);
|
|
38
|
+
if (raw === undefined) {
|
|
39
|
+
process.stderr.write(`Missing argument: --${def.name} (${def.type})\n`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
let value;
|
|
43
|
+
switch (def.type) {
|
|
44
|
+
case 'Int': {
|
|
45
|
+
if (!/^-?\d+$/.test(raw)) {
|
|
46
|
+
process.stderr.write(`--${def.name}: expected Int, got '${raw}'\n`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
value = { type: 'Int', value: BigInt(raw) };
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case 'Float': {
|
|
53
|
+
const n = Number(raw);
|
|
54
|
+
if (isNaN(n)) {
|
|
55
|
+
process.stderr.write(`--${def.name}: expected Float, got '${raw}'\n`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
value = { type: 'Float', value: n };
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case 'Bool': {
|
|
62
|
+
if (raw !== 'true' && raw !== 'false') {
|
|
63
|
+
process.stderr.write(`--${def.name}: expected Bool (true or false), got '${raw}'\n`);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
value = { type: 'Bool', value: raw === 'true' };
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
case 'String': {
|
|
70
|
+
value = { type: 'String', value: raw };
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
env.declare(def.name, value, false);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const runFile = async (filePath) => {
|
|
78
|
+
if (!filePath.endsWith('.asc')) {
|
|
79
|
+
process.stderr.write(`Expected a .asc file, got '${filePath}'\n`);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
let src;
|
|
83
|
+
try {
|
|
84
|
+
src = await readFile(filePath, 'utf8');
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
process.stderr.write(`Cannot read file '${filePath}'\n`);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
const lexResult = new Lexer(src).tokenize();
|
|
91
|
+
const parseResult = new Parser(lexResult.tokens).parse();
|
|
92
|
+
const errors = [...lexResult.errorMarkers, ...parseResult.errorMarkers];
|
|
93
|
+
if (errors.length > 0) {
|
|
94
|
+
for (const marker of errors) {
|
|
95
|
+
process.stderr.write(chalk.red(`[${marker.code}]`) + '\n');
|
|
96
|
+
}
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
if (parseResult.program === null)
|
|
100
|
+
return;
|
|
101
|
+
const typeResult = typecheck(parseResult.program);
|
|
102
|
+
if (typeResult.errorMarkers.length > 0) {
|
|
103
|
+
for (const marker of typeResult.errorMarkers) {
|
|
104
|
+
process.stderr.write(chalk.red(`[${marker.code}]`) + '\n');
|
|
105
|
+
}
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
const env = new Environment();
|
|
109
|
+
if (parseResult.program.args.length > 0) {
|
|
110
|
+
bindArgs(parseResult.program.args, parseCliFlags(process.argv.slice(3)), env);
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const result = executeProgram(typeResult.typedProgram, env);
|
|
114
|
+
if (result.type !== 'Done') {
|
|
115
|
+
process.stdout.write(formatValue(result) + '\n');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
process.stderr.write(chalk.red(String(e)) + '\n');
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
const runRepl = async () => {
|
|
124
|
+
process.stdout.write(chalk.bold.green('Ascent') + ' REPL\n');
|
|
125
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
126
|
+
const env = new Environment();
|
|
127
|
+
try {
|
|
128
|
+
while (true) {
|
|
129
|
+
const line = await rl.question(PROMPT);
|
|
130
|
+
const lexResult = new Lexer(line).tokenize();
|
|
131
|
+
let markerIndex = 0;
|
|
132
|
+
const tokenParts = lexResult.tokens
|
|
133
|
+
.filter(tok => tok.kind !== 'EOF')
|
|
134
|
+
.map(tok => {
|
|
135
|
+
if (tok.kind === 'ERROR') {
|
|
136
|
+
const code = lexResult.errorMarkers[markerIndex++]?.code ?? '?';
|
|
137
|
+
return chalk.red(`[${code}]`);
|
|
138
|
+
}
|
|
139
|
+
return `[${chalk.cyan(tok.kind)} ${chalk.yellow(`"${tok.value}"`)}]`;
|
|
140
|
+
});
|
|
141
|
+
process.stdout.write(tokenParts.join(` ${chalk.dim('·')} `) + '\n');
|
|
142
|
+
const parseResult = new Parser(lexResult.tokens).parse();
|
|
143
|
+
// A non-null program no longer means error-free: panic-mode
|
|
144
|
+
// recovery can skip a malformed statement and still finish the
|
|
145
|
+
// parse, so errorMarkers — not program nullness — is what decides
|
|
146
|
+
// whether it's safe to typecheck/run.
|
|
147
|
+
if (parseResult.errorMarkers.length > 0) {
|
|
148
|
+
// Only show parser errors when the lexer succeeded — if the lexer
|
|
149
|
+
// already flagged something, the parser error is a downstream echo.
|
|
150
|
+
if (lexResult.errorMarkers.length === 0) {
|
|
151
|
+
for (const marker of parseResult.errorMarkers) {
|
|
152
|
+
process.stdout.write(chalk.red(`[${marker.code}]`) + '\n');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else if (parseResult.program !== null) {
|
|
157
|
+
const typeResult = typecheck(parseResult.program);
|
|
158
|
+
const typeErrors = typeResult.errorMarkers;
|
|
159
|
+
if (typeErrors.length > 0) {
|
|
160
|
+
for (const marker of typeErrors) {
|
|
161
|
+
process.stdout.write(chalk.red(`[${marker.code}]`) + '\n');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// Print the untyped parse tree; execute the typed AST.
|
|
166
|
+
// The two arrays are guaranteed to be the same length when
|
|
167
|
+
// typedProgram is non-null (every statement type-checked).
|
|
168
|
+
const typedStmts = typeResult.typedProgram.stmts;
|
|
169
|
+
for (let i = 0; i < typedStmts.length; i++) {
|
|
170
|
+
process.stdout.write(formatTypedStmt(typedStmts[i]) + '\n');
|
|
171
|
+
try {
|
|
172
|
+
const result = executeStmt(typedStmts[i], env);
|
|
173
|
+
process.stdout.write(chalk.dim('=> ') + formatValue(result) + '\n');
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
process.stdout.write(chalk.red(String(e)) + '\n');
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// stdin closed (Ctrl+D)
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
rl.close();
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
const main = async () => {
|
|
191
|
+
const filePath = process.argv[2];
|
|
192
|
+
if (filePath !== undefined) {
|
|
193
|
+
await runFile(filePath);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
await runRepl();
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
main();
|
|
200
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { TypedExpr, TypedStatement, TypedProgram } from './parser/typed-ast.js';
|
|
2
|
+
export type RuntimeValue = ({
|
|
3
|
+
type: 'Int';
|
|
4
|
+
value: bigint;
|
|
5
|
+
} | {
|
|
6
|
+
type: 'Float';
|
|
7
|
+
value: number;
|
|
8
|
+
} | {
|
|
9
|
+
type: 'Bool';
|
|
10
|
+
value: boolean;
|
|
11
|
+
} | {
|
|
12
|
+
type: 'String';
|
|
13
|
+
value: string;
|
|
14
|
+
} | {
|
|
15
|
+
type: 'List';
|
|
16
|
+
elements: RuntimeValue[];
|
|
17
|
+
} | {
|
|
18
|
+
type: 'None';
|
|
19
|
+
} | {
|
|
20
|
+
type: 'Done';
|
|
21
|
+
});
|
|
22
|
+
export type AssignResult = 'ok' | 'immutable' | 'undeclared';
|
|
23
|
+
export declare class Environment {
|
|
24
|
+
private readonly parent;
|
|
25
|
+
private readonly vars;
|
|
26
|
+
constructor(parent?: Environment | null);
|
|
27
|
+
get(name: string): RuntimeValue | undefined;
|
|
28
|
+
declare(name: string, value: RuntimeValue, mutable: boolean): void;
|
|
29
|
+
assign(name: string, value: RuntimeValue): AssignResult;
|
|
30
|
+
child(): Environment;
|
|
31
|
+
}
|
|
32
|
+
export declare const evaluateExpr: (expr: TypedExpr, env: Environment) => RuntimeValue;
|
|
33
|
+
export declare const executeStmt: (stmt: TypedStatement, env: Environment) => RuntimeValue;
|
|
34
|
+
export declare const executeProgram: (program: TypedProgram, env: Environment) => RuntimeValue;
|
|
35
|
+
//# sourceMappingURL=interpreter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interpreter.d.ts","sourceRoot":"","sources":["../src/interpreter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAc,cAAc,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGjG,MAAM,MAAM,YAAY,GAAG,CACvB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CACnB,CAAC;AAIF,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,WAAW,GAAG,YAAY,CAAC;AAO7D,qBAAa,WAAW;IAGH,OAAO,CAAC,QAAQ,CAAC,MAAM;IAF1C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA8B;gBAEf,MAAM,GAAE,WAAW,GAAG,IAAW;IAE9D,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI3C,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IASlE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,YAAY;IAUvD,KAAK,IAAI,WAAW;CAG5B;AAYD,eAAO,MAAM,YAAY,GAAI,MAAM,SAAS,EAAE,KAAK,WAAW,KAAG,YAwEhE,CAAC;AAWF,eAAO,MAAM,WAAW,GAAI,MAAM,cAAc,EAAE,KAAK,WAAW,KAAG,YA8BpE,CAAC;AAkJF,eAAO,MAAM,cAAc,GAAI,SAAS,YAAY,EAAE,KAAK,WAAW,KAAG,YAMxE,CAAC"}
|