@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
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export const KEYWORDS = {
|
|
2
|
+
div: 'KW_DIV',
|
|
3
|
+
mod: 'KW_MOD',
|
|
4
|
+
fix: 'KW_FIX',
|
|
5
|
+
mut: 'KW_MUT',
|
|
6
|
+
if: 'KW_IF',
|
|
7
|
+
else: 'KW_ELSE',
|
|
8
|
+
while: 'KW_WHILE',
|
|
9
|
+
args: 'KW_ARGS',
|
|
10
|
+
};
|
|
11
|
+
// Built-in constructors: uppercase names that are part of the language
|
|
12
|
+
// core but are not keywords — they are non-shadowable constructor names
|
|
13
|
+
// (True, False, None) that happen to be built in rather than user-defined.
|
|
14
|
+
export const CONSTRUCTORS = {
|
|
15
|
+
True: 'BOOL_LIT',
|
|
16
|
+
False: 'BOOL_LIT',
|
|
17
|
+
None: 'NONE_LIT',
|
|
18
|
+
Done: 'DONE_LIT',
|
|
19
|
+
};
|
|
20
|
+
// Built-in type names: recognised as TYPE_NAME tokens so the parser can
|
|
21
|
+
// use them in type annotations (e.g. args declarations). Other uppercase
|
|
22
|
+
// names that are neither constructors nor type names are still L0001.
|
|
23
|
+
const BUILTIN_TYPES = {
|
|
24
|
+
Int: 'TYPE_NAME',
|
|
25
|
+
Float: 'TYPE_NAME',
|
|
26
|
+
Bool: 'TYPE_NAME',
|
|
27
|
+
String: 'TYPE_NAME',
|
|
28
|
+
List: 'TYPE_NAME',
|
|
29
|
+
};
|
|
30
|
+
// Returns the token kind for a scanned word, or null for an unrecognised
|
|
31
|
+
// uppercase name (the caller must emit L0001). Lowercase words that are not
|
|
32
|
+
// keywords resolve to SLOT rather than null.
|
|
33
|
+
export function resolveWord(value, firstCh) {
|
|
34
|
+
if (firstCh >= 'A' && firstCh <= 'Z') {
|
|
35
|
+
return CONSTRUCTORS[value] ?? BUILTIN_TYPES[value] ?? null;
|
|
36
|
+
}
|
|
37
|
+
return KEYWORDS[value] ?? 'SLOT';
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=keywords.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keywords.js","sourceRoot":"","sources":["../../src/lexer/keywords.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,QAAQ,GAA8B;IACjD,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,EAAE,EAAE,OAAO;IACX,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,UAAU;IACjB,IAAI,EAAE,SAAS;CAChB,CAAC;AAEF,uEAAuE;AACvE,wEAAwE;AACxE,2EAA2E;AAC3E,MAAM,CAAC,MAAM,YAAY,GAA8B;IACrD,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,UAAU;IACjB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,UAAU;CACjB,CAAC;AAEF,wEAAwE;AACxE,yEAAyE;AACzE,sEAAsE;AACtE,MAAM,aAAa,GAA8B;IAC/C,GAAG,EAAE,WAAW;IAChB,KAAK,EAAE,WAAW;IAClB,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,WAAW;IACnB,IAAI,EAAE,WAAW;CAClB,CAAC;AAEF,yEAAyE;AACzE,4EAA4E;AAC5E,6CAA6C;AAC7C,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,OAAe;IACxD,IAAI,OAAO,IAAI,GAAG,IAAI,OAAO,IAAI,GAAG,EAAE,CAAC;QACrC,OAAO,YAAY,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;IAC7D,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type TokenKind = 'INT_LIT' | 'FLOAT_LIT' | 'STR_LIT' | 'BOOL_LIT' | 'NONE_LIT' | 'DONE_LIT' | 'SLOT' | 'PLUS' | 'MINUS' | 'STAR' | 'SLASH' | 'KW_DIV' | 'KW_MOD' | 'KW_FIX' | 'KW_MUT' | 'KW_IF' | 'KW_ELSE' | 'KW_WHILE' | 'KW_ARGS' | 'TYPE_NAME' | 'COLON' | 'EQUALS' | 'EQ_EQ' | 'BANG_EQ' | 'LT' | 'LT_EQ' | 'GT' | 'GT_EQ' | 'DOT' | 'COMMA' | 'SEMICOLON' | 'LPAREN' | 'RPAREN' | 'LBRACE' | 'RBRACE' | 'LBRACKET' | 'RBRACKET' | 'ERROR' | 'EOF';
|
|
2
|
+
export interface Position {
|
|
3
|
+
offset: number;
|
|
4
|
+
line: number;
|
|
5
|
+
column: number;
|
|
6
|
+
}
|
|
7
|
+
export interface Span {
|
|
8
|
+
start: Position;
|
|
9
|
+
end: Position;
|
|
10
|
+
}
|
|
11
|
+
export interface Marker {
|
|
12
|
+
code: string;
|
|
13
|
+
span: Span;
|
|
14
|
+
}
|
|
15
|
+
export interface Token {
|
|
16
|
+
kind: TokenKind;
|
|
17
|
+
value: string;
|
|
18
|
+
span: Span;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/lexer/token.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,WAAW,GACX,SAAS,GACT,UAAU,GACV,UAAU,GACV,UAAU,GACV,MAAM,GACN,MAAM,GACN,OAAO,GACP,MAAM,GACN,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,SAAS,GACT,UAAU,GACV,SAAS,GACT,WAAW,GACX,OAAO,GACP,QAAQ,GACR,OAAO,GACP,SAAS,GACT,IAAI,GACJ,OAAO,GACP,IAAI,GACJ,OAAO,GACP,KAAK,GACL,OAAO,GACP,WAAW,GACX,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,UAAU,GACV,OAAO,GACP,KAAK,CAAC;AAEV,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,QAAQ,CAAC;IAChB,GAAG,EAAE,QAAQ,CAAC;CACf;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,IAAI,CAAC;CACZ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/lexer/token.ts"],"names":[],"mappings":""}
|
package/dist/lib.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { Lexer } from './lexer/index.js';
|
|
2
|
+
export type { LexResult } from './lexer/index.js';
|
|
3
|
+
export { Parser } from './parser/index.js';
|
|
4
|
+
export type { ParseResult } from './parser/index.js';
|
|
5
|
+
export { typecheck } from './parser/typechecker.js';
|
|
6
|
+
export type { TypeCheckResult } from './parser/typechecker.js';
|
|
7
|
+
export { Environment, evaluateExpr, executeStmt, executeProgram, } from './interpreter.js';
|
|
8
|
+
export type { RuntimeValue, AssignResult } from './interpreter.js';
|
|
9
|
+
export { formatExpr, formatStmt, formatValue } from './parser/printer.js';
|
|
10
|
+
export { formatTypedStmt } from './parser/typed-printer.js';
|
|
11
|
+
export * from './types/types.js';
|
|
12
|
+
export { ERRORS, byCode } from './errors/index.js';
|
|
13
|
+
export type { ErrorEntry, Category } from './errors/types.js';
|
|
14
|
+
//# sourceMappingURL=lib.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/lib.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Public programmatic API for the Ascent language toolchain.
|
|
2
|
+
// The `ascent` CLI (see index.ts) is the primary entry point, but the
|
|
3
|
+
// individual stages are re-exported here so tools can embed the pipeline:
|
|
4
|
+
//
|
|
5
|
+
// const { tokens, errorMarkers } = new Lexer(src).tokenize();
|
|
6
|
+
// const { program } = new Parser(tokens).parse();
|
|
7
|
+
// const { typedProgram } = typecheck(program!);
|
|
8
|
+
// const result = executeProgram(typedProgram!, new Environment());
|
|
9
|
+
export { Lexer } from './lexer/index.js';
|
|
10
|
+
export { Parser } from './parser/index.js';
|
|
11
|
+
export { typecheck } from './parser/typechecker.js';
|
|
12
|
+
export { Environment, evaluateExpr, executeStmt, executeProgram, } from './interpreter.js';
|
|
13
|
+
export { formatExpr, formatStmt, formatValue } from './parser/printer.js';
|
|
14
|
+
export { formatTypedStmt } from './parser/typed-printer.js';
|
|
15
|
+
export * from './types/types.js';
|
|
16
|
+
export { ERRORS, byCode } from './errors/index.js';
|
|
17
|
+
//# sourceMappingURL=lib.js.map
|
package/dist/lib.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,sEAAsE;AACtE,0EAA0E;AAC1E,EAAE;AACF,gEAAgE;AAChE,oDAAoD;AACpD,kDAAkD;AAClD,qEAAqE;AAErE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGzC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGpD,OAAO,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,cAAc,GACf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type { Span } from '../lexer/token.js';
|
|
2
|
+
export type TypeExpr = {
|
|
3
|
+
kind: 'TypeName';
|
|
4
|
+
name: 'Int' | 'Float' | 'Bool' | 'String';
|
|
5
|
+
span: Span;
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'ListType';
|
|
8
|
+
elem: TypeExpr;
|
|
9
|
+
span: Span;
|
|
10
|
+
};
|
|
11
|
+
export type Literal = ({
|
|
12
|
+
kind: 'literal';
|
|
13
|
+
valueType: 'Int';
|
|
14
|
+
value: bigint;
|
|
15
|
+
span: Span;
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'literal';
|
|
18
|
+
valueType: 'Float';
|
|
19
|
+
value: number;
|
|
20
|
+
span: Span;
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'literal';
|
|
23
|
+
valueType: 'Bool';
|
|
24
|
+
value: boolean;
|
|
25
|
+
span: Span;
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'literal';
|
|
28
|
+
valueType: 'String';
|
|
29
|
+
value: string;
|
|
30
|
+
span: Span;
|
|
31
|
+
} | {
|
|
32
|
+
kind: 'literal';
|
|
33
|
+
valueType: 'None';
|
|
34
|
+
span: Span;
|
|
35
|
+
} | {
|
|
36
|
+
kind: 'literal';
|
|
37
|
+
valueType: 'Done';
|
|
38
|
+
span: Span;
|
|
39
|
+
});
|
|
40
|
+
export type UnaryOp = '-';
|
|
41
|
+
export type ArithmeticOp = '+' | '-' | '*' | '/' | 'div' | 'mod';
|
|
42
|
+
export type ComparisonOp = '==' | '!=' | '<' | '<=' | '>' | '>=';
|
|
43
|
+
export type BinaryOp = ArithmeticOp | ComparisonOp;
|
|
44
|
+
export type Block = {
|
|
45
|
+
kind: 'block';
|
|
46
|
+
stmts: Statement[];
|
|
47
|
+
span: Span;
|
|
48
|
+
};
|
|
49
|
+
export type If = {
|
|
50
|
+
kind: 'if';
|
|
51
|
+
cond: Expr;
|
|
52
|
+
then: Block;
|
|
53
|
+
else: Block | If | null;
|
|
54
|
+
span: Span;
|
|
55
|
+
};
|
|
56
|
+
export type Expr = (Literal | {
|
|
57
|
+
kind: 'slot';
|
|
58
|
+
name: string;
|
|
59
|
+
span: Span;
|
|
60
|
+
} | {
|
|
61
|
+
kind: 'call';
|
|
62
|
+
callee: string;
|
|
63
|
+
args: Expr[];
|
|
64
|
+
span: Span;
|
|
65
|
+
} | {
|
|
66
|
+
kind: 'methodCall';
|
|
67
|
+
receiver: Expr;
|
|
68
|
+
method: string;
|
|
69
|
+
args: Expr[];
|
|
70
|
+
span: Span;
|
|
71
|
+
} | {
|
|
72
|
+
kind: 'list';
|
|
73
|
+
elements: Expr[];
|
|
74
|
+
span: Span;
|
|
75
|
+
} | {
|
|
76
|
+
kind: 'index';
|
|
77
|
+
list: Expr;
|
|
78
|
+
index: Expr;
|
|
79
|
+
span: Span;
|
|
80
|
+
} | {
|
|
81
|
+
kind: 'unary';
|
|
82
|
+
op: UnaryOp;
|
|
83
|
+
operand: Expr;
|
|
84
|
+
span: Span;
|
|
85
|
+
} | {
|
|
86
|
+
kind: 'binary';
|
|
87
|
+
op: BinaryOp;
|
|
88
|
+
left: Expr;
|
|
89
|
+
right: Expr;
|
|
90
|
+
span: Span;
|
|
91
|
+
} | Block | If);
|
|
92
|
+
export type Statement = ({
|
|
93
|
+
kind: 'fix';
|
|
94
|
+
name: string;
|
|
95
|
+
typeAnnotation: TypeExpr | null;
|
|
96
|
+
init: Expr;
|
|
97
|
+
span: Span;
|
|
98
|
+
} | {
|
|
99
|
+
kind: 'mut';
|
|
100
|
+
name: string;
|
|
101
|
+
typeAnnotation: TypeExpr | null;
|
|
102
|
+
init: Expr;
|
|
103
|
+
span: Span;
|
|
104
|
+
} | {
|
|
105
|
+
kind: 'assign';
|
|
106
|
+
name: string;
|
|
107
|
+
value: Expr;
|
|
108
|
+
span: Span;
|
|
109
|
+
} | {
|
|
110
|
+
kind: 'expr';
|
|
111
|
+
expr: Expr;
|
|
112
|
+
span: Span;
|
|
113
|
+
} | {
|
|
114
|
+
kind: 'while';
|
|
115
|
+
cond: Expr;
|
|
116
|
+
body: Block;
|
|
117
|
+
span: Span;
|
|
118
|
+
});
|
|
119
|
+
export type ArgType = 'Int' | 'Float' | 'Bool' | 'String';
|
|
120
|
+
export type ArgDef = {
|
|
121
|
+
name: string;
|
|
122
|
+
type: ArgType;
|
|
123
|
+
};
|
|
124
|
+
export type Program = {
|
|
125
|
+
args: ArgDef[];
|
|
126
|
+
stmts: Statement[];
|
|
127
|
+
};
|
|
128
|
+
//# sourceMappingURL=ast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAI9C,MAAM,MAAM,QAAQ,GAChB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC3E;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AAErD,MAAM,MAAM,OAAO,GAAG,CAClB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CACrD,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG,GAAG,CAAC;AAC1B,MAAM,MAAM,YAAY,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC;AACjE,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,YAAY,CAAC;AAInD,MAAM,MAAM,KAAK,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AAItE,MAAM,MAAM,EAAE,GAAG;IACf,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG,CACf,OAAO,GACP;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAChF;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GACrE,KAAK,GACL,EAAE,CACL,CAAC;AAKF,MAAM,MAAM,SAAS,GAAG,CACpB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,QAAQ,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GACtF;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,QAAQ,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GACtF;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CACzD,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAC1D,MAAM,MAAM,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAErD,MAAM,MAAM,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expr.d.ts","sourceRoot":"","sources":["../../src/parser/expr.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAqB,MAAM,UAAU,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA0ErD,wBAAgB,SAAS,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,SAAI,GAAG,IAAI,GAAG,IAAI,CA+DjE"}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { parseBlock, parseIf } from './stmt.js';
|
|
2
|
+
// ---- Pratt parsing ----------------------------------------------------
|
|
3
|
+
//
|
|
4
|
+
// A Pratt parser recognises an expression as an atom (a "nud" — null
|
|
5
|
+
// denotation, a value that doesn't look left at anything) optionally
|
|
6
|
+
// followed by a chain of infix or postfix operators (each a "led" —
|
|
7
|
+
// left denotation, because it combines the value already parsed with
|
|
8
|
+
// whatever comes after it).
|
|
9
|
+
//
|
|
10
|
+
// Every operator — prefix, infix, or postfix — has a binding power: a
|
|
11
|
+
// number saying how tightly it grabs its operands. Higher binds
|
|
12
|
+
// tighter — that's what encodes precedence: '*' outbinds '+', so
|
|
13
|
+
// `1 + 2 * 3` parses as `1 + (2 * 3)`, not `(1 + 2) * 3`. The parsing
|
|
14
|
+
// loop only accepts an operator when its binding power is at least
|
|
15
|
+
// `minBp` — the "how tight does the *caller* need things bound"
|
|
16
|
+
// threshold passed down on each recursive call.
|
|
17
|
+
//
|
|
18
|
+
// This ladder is the single source of truth for what binds tighter
|
|
19
|
+
// than what: postfix (`.method()`, `[index]`) binds tightest, then
|
|
20
|
+
// unary '-', then '*'/'/'/'div'/'mod', then '+'/'-', then the
|
|
21
|
+
// comparisons, loosest. Every table below is keyed off these numbers
|
|
22
|
+
// instead of inlining its own.
|
|
23
|
+
const BP = {
|
|
24
|
+
COMPARISON: 1,
|
|
25
|
+
ADDITIVE: 2,
|
|
26
|
+
MULTIPLICATIVE: 3,
|
|
27
|
+
UNARY: 4,
|
|
28
|
+
POSTFIX: 4,
|
|
29
|
+
};
|
|
30
|
+
// Every binary operator this parser knows about has one row in this
|
|
31
|
+
// table. Adding the next one means adding a row, never touching the
|
|
32
|
+
// loop below. '*', '/', 'div' and 'mod' all share a binding power —
|
|
33
|
+
// they're the same precedence tier — so all four outbind '+', which
|
|
34
|
+
// in turn outbinds the comparisons — `1 + 2 < 3 * 4` groups as
|
|
35
|
+
// `(1 + 2) < (3 * 4)`. Comparisons are also marked `assoc: 'none'`:
|
|
36
|
+
// unlike '+' or '*', two of them can never sit side by side
|
|
37
|
+
// (`a < b < c` is rejected, not silently grouped one way or the other).
|
|
38
|
+
const INFIX_OPS = {
|
|
39
|
+
EQ_EQ: { op: '==', bp: BP.COMPARISON, assoc: 'none' },
|
|
40
|
+
BANG_EQ: { op: '!=', bp: BP.COMPARISON, assoc: 'none' },
|
|
41
|
+
LT: { op: '<', bp: BP.COMPARISON, assoc: 'none' },
|
|
42
|
+
LT_EQ: { op: '<=', bp: BP.COMPARISON, assoc: 'none' },
|
|
43
|
+
GT: { op: '>', bp: BP.COMPARISON, assoc: 'none' },
|
|
44
|
+
GT_EQ: { op: '>=', bp: BP.COMPARISON, assoc: 'none' },
|
|
45
|
+
PLUS: { op: '+', bp: BP.ADDITIVE, assoc: 'left' },
|
|
46
|
+
MINUS: { op: '-', bp: BP.ADDITIVE, assoc: 'left' },
|
|
47
|
+
STAR: { op: '*', bp: BP.MULTIPLICATIVE, assoc: 'left' },
|
|
48
|
+
SLASH: { op: '/', bp: BP.MULTIPLICATIVE, assoc: 'left' },
|
|
49
|
+
KW_DIV: { op: 'div', bp: BP.MULTIPLICATIVE, assoc: 'left' },
|
|
50
|
+
KW_MOD: { op: 'mod', bp: BP.MULTIPLICATIVE, assoc: 'left' },
|
|
51
|
+
};
|
|
52
|
+
// Postfix table — dot-calls and indexing are "led" operators exactly
|
|
53
|
+
// like the binary ones above (they look left at the value already
|
|
54
|
+
// parsed), so they're declared here and dispatched on in the loop
|
|
55
|
+
// below instead of being special-cased ahead of the INFIX_OPS lookup.
|
|
56
|
+
// Both bind at POSTFIX — tighter than unary or any binary operator —
|
|
57
|
+
// which is why `-a.b()[0]` parses as `-(a.b()[0])`.
|
|
58
|
+
const POSTFIX_OPS = {
|
|
59
|
+
DOT: { bp: BP.POSTFIX },
|
|
60
|
+
LBRACKET: { bp: BP.POSTFIX },
|
|
61
|
+
};
|
|
62
|
+
// Prefix table — unary '-' is the Pratt parser's other operator kind
|
|
63
|
+
// (a "nud" that still takes an operand, parsed in parseAtom below).
|
|
64
|
+
// Only one entry today, but its binding power is declared here rather
|
|
65
|
+
// than inlined at the call site.
|
|
66
|
+
const PREFIX_OPS = {
|
|
67
|
+
MINUS: { op: '-', bp: BP.UNARY },
|
|
68
|
+
};
|
|
69
|
+
export function parseExpr(ts, minBp = 0) {
|
|
70
|
+
let left = parseAtom(ts);
|
|
71
|
+
if (left === null) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
// Tracks whether a non-associative (comparison-tier) operator has
|
|
75
|
+
// already been consumed at this call's level — a second one directly
|
|
76
|
+
// beside it (`a < b < c`) is a chain, not a grouping choice, so it's
|
|
77
|
+
// rejected here rather than silently parsed left- or right-first.
|
|
78
|
+
let chained = false;
|
|
79
|
+
while (true) {
|
|
80
|
+
const kind = ts.peek().kind;
|
|
81
|
+
// Postfix: expr.method(args) or expr[index] — dispatched by table
|
|
82
|
+
// rather than special-cased ahead of the INFIX_OPS lookup below.
|
|
83
|
+
const postfix = POSTFIX_OPS[kind];
|
|
84
|
+
if (postfix !== undefined) {
|
|
85
|
+
if (postfix.bp < minBp)
|
|
86
|
+
break;
|
|
87
|
+
left = kind === 'DOT' ? parseMethodCall(ts, left) : parseIndex(ts, left);
|
|
88
|
+
if (left === null)
|
|
89
|
+
return null;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const infix = INFIX_OPS[kind];
|
|
93
|
+
if (infix === undefined || infix.bp < minBp) {
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
if (infix.assoc === 'none') {
|
|
97
|
+
if (chained) {
|
|
98
|
+
ts.report('S0008', ts.peek().span);
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
chained = true;
|
|
102
|
+
}
|
|
103
|
+
ts.advance(); // consume the operator
|
|
104
|
+
// Left-associativity — `1 + 2 + 3` must parse as `(1 + 2) + 3`,
|
|
105
|
+
// not `1 + (2 + 3)`. Parsing the right-hand side with `bp + 1`
|
|
106
|
+
// (instead of `bp`) is what enforces that: it stops a second '+'
|
|
107
|
+
// from being absorbed into the *right* operand, forcing it to
|
|
108
|
+
// instead be picked up by the loop one level up. Non-associative
|
|
109
|
+
// operators reuse the same `bp + 1` call — it still keeps looser
|
|
110
|
+
// operators out of the right operand, and the `chained` check
|
|
111
|
+
// above is what stops them from reappearing at this level.
|
|
112
|
+
const right = parseExpr(ts, infix.bp + 1);
|
|
113
|
+
if (right === null) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
left = {
|
|
117
|
+
kind: 'binary',
|
|
118
|
+
op: infix.op,
|
|
119
|
+
left,
|
|
120
|
+
right,
|
|
121
|
+
span: { start: left.span.start, end: right.span.end }
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return left;
|
|
125
|
+
}
|
|
126
|
+
// 'receiver.method(args)' — DOT already confirmed on lookahead by the
|
|
127
|
+
// Pratt loop; this consumes it through the closing ')'.
|
|
128
|
+
function parseMethodCall(ts, receiver) {
|
|
129
|
+
ts.advance(); // consume '.'
|
|
130
|
+
const methodTok = ts.peek();
|
|
131
|
+
if (methodTok.kind !== 'SLOT') {
|
|
132
|
+
ts.report('S0012', methodTok.span);
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
ts.advance(); // consume method name
|
|
136
|
+
if (ts.peek().kind !== 'LPAREN') {
|
|
137
|
+
ts.report('S0001', ts.peek().span);
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
ts.advance(); // consume '('
|
|
141
|
+
const parsed = ts.parseSeparated(() => parseExpr(ts), 'COMMA', 'RPAREN', 'S0001');
|
|
142
|
+
if (parsed === null)
|
|
143
|
+
return null;
|
|
144
|
+
return {
|
|
145
|
+
kind: 'methodCall',
|
|
146
|
+
receiver,
|
|
147
|
+
method: methodTok.value,
|
|
148
|
+
args: parsed.items,
|
|
149
|
+
span: { start: receiver.span.start, end: parsed.close.span.end },
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
// 'list[index]' — LBRACKET already confirmed on lookahead by the Pratt loop.
|
|
153
|
+
function parseIndex(ts, list) {
|
|
154
|
+
ts.advance(); // consume '['
|
|
155
|
+
const index = parseExpr(ts);
|
|
156
|
+
if (index === null)
|
|
157
|
+
return null;
|
|
158
|
+
const rbracket = ts.expect('RBRACKET', 'S0013');
|
|
159
|
+
if (rbracket === null)
|
|
160
|
+
return null;
|
|
161
|
+
return {
|
|
162
|
+
kind: 'index',
|
|
163
|
+
list,
|
|
164
|
+
index,
|
|
165
|
+
span: { start: list.span.start, end: rbracket.span.end },
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
// parseAtom parses the smallest possible expression: a single literal
|
|
169
|
+
// that doesn't depend on any operator. This is the Pratt parser's nud —
|
|
170
|
+
// every future one (parenthesized groups, unary '-', identifiers) is
|
|
171
|
+
// just another case added here, never a change to the loop above.
|
|
172
|
+
function parseAtom(ts) {
|
|
173
|
+
const tok = ts.peek();
|
|
174
|
+
if (tok.kind === 'INT_LIT') {
|
|
175
|
+
ts.advance();
|
|
176
|
+
return {
|
|
177
|
+
kind: 'literal',
|
|
178
|
+
valueType: 'Int',
|
|
179
|
+
value: BigInt(tok.value),
|
|
180
|
+
span: tok.span
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
if (tok.kind === 'FLOAT_LIT') {
|
|
184
|
+
ts.advance();
|
|
185
|
+
return {
|
|
186
|
+
kind: 'literal',
|
|
187
|
+
valueType: 'Float',
|
|
188
|
+
value: parseFloat(tok.value),
|
|
189
|
+
span: tok.span
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
if (tok.kind === 'STR_LIT') {
|
|
193
|
+
ts.advance();
|
|
194
|
+
return { kind: 'literal', valueType: 'String', value: tok.value, span: tok.span };
|
|
195
|
+
}
|
|
196
|
+
if (tok.kind === 'BOOL_LIT') {
|
|
197
|
+
ts.advance();
|
|
198
|
+
return {
|
|
199
|
+
kind: 'literal',
|
|
200
|
+
valueType: 'Bool',
|
|
201
|
+
value: tok.value === 'True',
|
|
202
|
+
span: tok.span
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
if (tok.kind === 'NONE_LIT') {
|
|
206
|
+
ts.advance();
|
|
207
|
+
return { kind: 'literal', valueType: 'None', span: tok.span };
|
|
208
|
+
}
|
|
209
|
+
if (tok.kind === 'DONE_LIT') {
|
|
210
|
+
ts.advance();
|
|
211
|
+
return { kind: 'literal', valueType: 'Done', span: tok.span };
|
|
212
|
+
}
|
|
213
|
+
if (tok.kind === 'SLOT') {
|
|
214
|
+
ts.advance();
|
|
215
|
+
if (ts.peek().kind === 'LPAREN') {
|
|
216
|
+
return parseCall(ts, tok);
|
|
217
|
+
}
|
|
218
|
+
return { kind: 'slot', name: tok.value, span: tok.span };
|
|
219
|
+
}
|
|
220
|
+
if (tok.kind === 'LPAREN') {
|
|
221
|
+
ts.advance();
|
|
222
|
+
const inner = parseExpr(ts);
|
|
223
|
+
if (inner === null) {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
const closing = ts.peek();
|
|
227
|
+
if (closing.kind !== 'RPAREN') {
|
|
228
|
+
ts.report('S0001', closing.span);
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
ts.advance(); // consume ')'
|
|
232
|
+
return inner;
|
|
233
|
+
}
|
|
234
|
+
const prefix = PREFIX_OPS[tok.kind];
|
|
235
|
+
if (prefix !== undefined) {
|
|
236
|
+
const start = tok.span.start;
|
|
237
|
+
ts.advance();
|
|
238
|
+
const operand = parseExpr(ts, prefix.bp);
|
|
239
|
+
if (operand === null) {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
return { kind: 'unary', op: prefix.op, operand, span: { start, end: operand.span.end } };
|
|
243
|
+
}
|
|
244
|
+
if (tok.kind === 'LBRACKET') {
|
|
245
|
+
return parseList(ts);
|
|
246
|
+
}
|
|
247
|
+
if (tok.kind === 'LBRACE') {
|
|
248
|
+
return parseBlock(ts);
|
|
249
|
+
}
|
|
250
|
+
if (tok.kind === 'KW_IF') {
|
|
251
|
+
return parseIf(ts);
|
|
252
|
+
}
|
|
253
|
+
ts.report('S0002', tok.span);
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
// 'name(arg, arg, …)' — callee token already consumed by parseAtom.
|
|
257
|
+
function parseCall(ts, callee) {
|
|
258
|
+
ts.advance(); // consume '('
|
|
259
|
+
const parsed = ts.parseSeparated(() => parseExpr(ts), 'COMMA', 'RPAREN', 'S0001');
|
|
260
|
+
if (parsed === null)
|
|
261
|
+
return null;
|
|
262
|
+
return {
|
|
263
|
+
kind: 'call',
|
|
264
|
+
callee: callee.value,
|
|
265
|
+
args: parsed.items,
|
|
266
|
+
span: { start: callee.span.start, end: parsed.close.span.end },
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
// '[' expr, expr, … ']' — list literal. Already peeked '[' in parseAtom.
|
|
270
|
+
function parseList(ts) {
|
|
271
|
+
const openTok = ts.advance(); // consume '['
|
|
272
|
+
const parsed = ts.parseSeparated(() => parseExpr(ts), 'COMMA', 'RBRACKET', 'S0013');
|
|
273
|
+
if (parsed === null)
|
|
274
|
+
return null;
|
|
275
|
+
return { kind: 'list', elements: parsed.items, span: { start: openTok.span.start, end: parsed.close.span.end } };
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=expr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expr.js","sourceRoot":"","sources":["../../src/parser/expr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Token, Marker } from '../lexer/token.js';
|
|
2
|
+
import type { Program } from './ast.js';
|
|
3
|
+
export interface ParseResult {
|
|
4
|
+
program: Program | null;
|
|
5
|
+
errorMarkers: Marker[];
|
|
6
|
+
}
|
|
7
|
+
export declare class Parser {
|
|
8
|
+
private readonly tokens;
|
|
9
|
+
constructor(tokens: Token[]);
|
|
10
|
+
parse(): ParseResult;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAU,OAAO,EAAE,MAAM,UAAU,CAAC;AAKhD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AA4BD,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;gBAEd,MAAM,EAAE,KAAK,EAAE;IAI3B,KAAK,IAAI,WAAW;CAK5B"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { TokenStream } from './token-stream.js';
|
|
2
|
+
import { parseStmt } from './stmt.js';
|
|
3
|
+
import { parseArgs } from './type-expr.js';
|
|
4
|
+
// The program is an optional 'args (…);' header followed by a
|
|
5
|
+
// semicolon-separated run of statements up to EOF — the same
|
|
6
|
+
// "item (sep item)* close" shape as a block, with EOF standing in for
|
|
7
|
+
// the closing brace. `recover` is on, so a malformed statement is
|
|
8
|
+
// synchronized past rather than aborting the whole parse.
|
|
9
|
+
function parseProgram(ts) {
|
|
10
|
+
let args = [];
|
|
11
|
+
if (ts.peek().kind === 'KW_ARGS') {
|
|
12
|
+
const result = parseArgs(ts);
|
|
13
|
+
if (result === null)
|
|
14
|
+
return null;
|
|
15
|
+
args = result;
|
|
16
|
+
if (ts.expect('SEMICOLON', 'S0011') === null)
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const parsed = ts.parseSeparated(() => parseStmt(ts), 'SEMICOLON', 'EOF', 'S0011', true);
|
|
20
|
+
if (parsed === null)
|
|
21
|
+
return null;
|
|
22
|
+
return { args, stmts: parsed.items };
|
|
23
|
+
}
|
|
24
|
+
// The parser's public entry point. Phase 5 moved the grammar into
|
|
25
|
+
// free functions over a TokenStream (token-stream.ts, expr.ts, stmt.ts,
|
|
26
|
+
// type-expr.ts); this class is the thin wiring that owns the stream for
|
|
27
|
+
// one parse and exposes the same `new Parser(tokens).parse()` API the
|
|
28
|
+
// rest of the toolchain calls.
|
|
29
|
+
export class Parser {
|
|
30
|
+
tokens;
|
|
31
|
+
constructor(tokens) {
|
|
32
|
+
this.tokens = tokens;
|
|
33
|
+
}
|
|
34
|
+
parse() {
|
|
35
|
+
const ts = new TokenStream(this.tokens);
|
|
36
|
+
const program = parseProgram(ts);
|
|
37
|
+
return { program, errorMarkers: ts.errors };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAO3C,8DAA8D;AAC9D,6DAA6D;AAC7D,sEAAsE;AACtE,kEAAkE;AAClE,0DAA0D;AAC1D,SAAS,YAAY,CAAC,EAAe;IACnC,IAAI,IAAI,GAAa,EAAE,CAAC;IACxB,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;QAC7B,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACjC,IAAI,GAAG,MAAM,CAAC;QAEd,IAAI,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;IAC5D,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACzF,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEjC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;AACvC,CAAC;AAED,kEAAkE;AAClE,wEAAwE;AACxE,wEAAwE;AACxE,sEAAsE;AACtE,+BAA+B;AAC/B,MAAM,OAAO,MAAM;IACA,MAAM,CAAU;IAEjC,YAAmB,MAAe;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAEM,KAAK;QACV,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;QACjC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC;IAC9C,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Expr, Statement } from './ast.js';
|
|
2
|
+
import type { RuntimeValue } from '../interpreter.js';
|
|
3
|
+
export declare const branch: (lines: string[], isLast: boolean) => string[];
|
|
4
|
+
export declare const formatExpr: (expr: Expr) => string;
|
|
5
|
+
export declare const formatStmt: (stmt: Statement) => string;
|
|
6
|
+
export declare const formatValue: (value: RuntimeValue) => string;
|
|
7
|
+
//# sourceMappingURL=printer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"printer.d.ts","sourceRoot":"","sources":["../../src/parser/printer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAY,MAAM,UAAU,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAsFtD,eAAO,MAAM,MAAM,GAAI,OAAO,MAAM,EAAE,EAAE,QAAQ,OAAO,KAAG,MAAM,EAI/D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,MAAM,IAAI,KAAG,MAEvC,CAAC;AA2BF,eAAO,MAAM,UAAU,GAAI,MAAM,SAAS,KAAG,MAAoC,CAAC;AAElF,eAAO,MAAM,WAAW,GAAI,OAAO,YAAY,KAAG,MAoBjD,CAAC"}
|