@hatchingpoint/point 0.0.5 → 0.0.7
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/LICENSE +21 -21
- package/README.md +34 -21
- package/package.json +34 -30
- package/src/cli.ts +7 -7
- package/src/core/ast.ts +162 -124
- package/src/core/check.ts +590 -479
- package/src/core/cli.ts +497 -216
- package/src/core/context.ts +394 -217
- package/src/core/emit-javascript.ts +124 -0
- package/src/core/emit-typescript.ts +166 -133
- package/src/core/format.ts +6 -104
- package/src/core/incremental.ts +53 -0
- package/src/core/index.ts +12 -7
- package/src/core/lexer.ts +245 -240
- package/src/core/parser.ts +11 -612
- package/src/core/semantic-source.ts +26 -0
- package/src/core/serialize.ts +18 -0
- package/src/core/test-only/core-text-parser.ts +415 -0
- package/src/core/test-only/format-core.ts +120 -0
- package/src/core/test-only/index.ts +3 -0
- package/src/core/test-only/legacy-lowering.ts +1047 -0
- package/src/index.ts +1 -1
- package/src/semantic/ast.ts +230 -0
- package/src/semantic/callables.ts +51 -0
- package/src/semantic/context.ts +347 -0
- package/src/semantic/desugar.ts +665 -0
- package/src/semantic/expressions.ts +347 -0
- package/src/semantic/format.ts +222 -0
- package/src/semantic/index.ts +10 -0
- package/src/semantic/metadata.ts +37 -0
- package/src/semantic/naming.ts +33 -0
- package/src/semantic/parse.ts +945 -0
- package/src/semantic/serialize.ts +18 -0
package/src/core/lexer.ts
CHANGED
|
@@ -1,240 +1,245 @@
|
|
|
1
|
-
import type { PointSourceSpan } from "./ast.ts";
|
|
2
|
-
|
|
3
|
-
export type PointCoreTokenType =
|
|
4
|
-
| "identifier"
|
|
5
|
-
| "number"
|
|
6
|
-
| "string"
|
|
7
|
-
| "leftBrace"
|
|
8
|
-
| "rightBrace"
|
|
9
|
-
| "leftBracket"
|
|
10
|
-
| "rightBracket"
|
|
11
|
-
| "leftParen"
|
|
12
|
-
| "rightParen"
|
|
13
|
-
| "comma"
|
|
14
|
-
| "colon"
|
|
15
|
-
| "dot"
|
|
16
|
-
| "equals"
|
|
17
|
-
| "plusEquals"
|
|
18
|
-
| "
|
|
19
|
-
| "
|
|
20
|
-
| "
|
|
21
|
-
| "
|
|
22
|
-
| "
|
|
23
|
-
| "
|
|
24
|
-
| "
|
|
25
|
-
| "
|
|
26
|
-
| "
|
|
27
|
-
| "
|
|
28
|
-
| "
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
private
|
|
51
|
-
private
|
|
52
|
-
private
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
this.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
this.tokens.push({
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
return {
|
|
239
|
-
}
|
|
240
|
-
|
|
1
|
+
import type { PointSourceSpan } from "./ast.ts";
|
|
2
|
+
|
|
3
|
+
export type PointCoreTokenType =
|
|
4
|
+
| "identifier"
|
|
5
|
+
| "number"
|
|
6
|
+
| "string"
|
|
7
|
+
| "leftBrace"
|
|
8
|
+
| "rightBrace"
|
|
9
|
+
| "leftBracket"
|
|
10
|
+
| "rightBracket"
|
|
11
|
+
| "leftParen"
|
|
12
|
+
| "rightParen"
|
|
13
|
+
| "comma"
|
|
14
|
+
| "colon"
|
|
15
|
+
| "dot"
|
|
16
|
+
| "equals"
|
|
17
|
+
| "plusEquals"
|
|
18
|
+
| "minusEquals"
|
|
19
|
+
| "equalsEquals"
|
|
20
|
+
| "bangEquals"
|
|
21
|
+
| "less"
|
|
22
|
+
| "lessEquals"
|
|
23
|
+
| "greater"
|
|
24
|
+
| "greaterEquals"
|
|
25
|
+
| "plus"
|
|
26
|
+
| "minus"
|
|
27
|
+
| "star"
|
|
28
|
+
| "slash"
|
|
29
|
+
| "eof";
|
|
30
|
+
|
|
31
|
+
export interface PointCoreToken {
|
|
32
|
+
type: PointCoreTokenType;
|
|
33
|
+
value: string;
|
|
34
|
+
span: PointSourceSpan;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class PointCoreLexerError extends Error {
|
|
38
|
+
constructor(message: string, public readonly span: PointSourceSpan) {
|
|
39
|
+
super(`${message} at ${span.start.line}:${span.start.column}`);
|
|
40
|
+
this.name = "PointCoreLexerError";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function lexPointCore(source: string): PointCoreToken[] {
|
|
45
|
+
const lexer = new CoreLexer(source);
|
|
46
|
+
return lexer.lex();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
class CoreLexer {
|
|
50
|
+
private index = 0;
|
|
51
|
+
private line = 1;
|
|
52
|
+
private column = 1;
|
|
53
|
+
private readonly tokens: PointCoreToken[] = [];
|
|
54
|
+
|
|
55
|
+
constructor(private readonly source: string) {}
|
|
56
|
+
|
|
57
|
+
lex(): PointCoreToken[] {
|
|
58
|
+
while (!this.done()) {
|
|
59
|
+
const char = this.peek();
|
|
60
|
+
if (/\s/.test(char)) {
|
|
61
|
+
this.advance();
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (char === "/" && this.peek(1) === "/") {
|
|
65
|
+
while (!this.done() && this.peek() !== "\n") this.advance();
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (char === "{") {
|
|
69
|
+
this.push("leftBrace", this.advance());
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (char === "}") {
|
|
73
|
+
this.push("rightBrace", this.advance());
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (char === "(") {
|
|
77
|
+
this.push("leftParen", this.advance());
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (char === "[") {
|
|
81
|
+
this.push("leftBracket", this.advance());
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (char === "]") {
|
|
85
|
+
this.push("rightBracket", this.advance());
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (char === ")") {
|
|
89
|
+
this.push("rightParen", this.advance());
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (char === ",") {
|
|
93
|
+
this.push("comma", this.advance());
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (char === ":") {
|
|
97
|
+
this.push("colon", this.advance());
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (char === ".") {
|
|
101
|
+
this.push("dot", this.advance());
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (char === "=") {
|
|
105
|
+
if (this.peek(1) === "=") {
|
|
106
|
+
this.push("equalsEquals", `${this.advance()}${this.advance()}`);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
this.push("equals", this.advance());
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (char === "!" && this.peek(1) === "=") {
|
|
113
|
+
this.push("bangEquals", `${this.advance()}${this.advance()}`);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (char === "<") {
|
|
117
|
+
if (this.peek(1) === "=") {
|
|
118
|
+
this.push("lessEquals", `${this.advance()}${this.advance()}`);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
this.push("less", this.advance());
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (char === ">") {
|
|
125
|
+
if (this.peek(1) === "=") {
|
|
126
|
+
this.push("greaterEquals", `${this.advance()}${this.advance()}`);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
this.push("greater", this.advance());
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (char === "+") {
|
|
133
|
+
if (this.peek(1) === "=") {
|
|
134
|
+
this.push("plusEquals", `${this.advance()}${this.advance()}`);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
this.push("plus", this.advance());
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (char === "-") {
|
|
141
|
+
if (this.peek(1) === "=") {
|
|
142
|
+
this.push("minusEquals", `${this.advance()}${this.advance()}`);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
this.push("minus", this.advance());
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (char === "*") {
|
|
149
|
+
this.push("star", this.advance());
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (char === "/") {
|
|
153
|
+
this.push("slash", this.advance());
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (char === "\"") {
|
|
157
|
+
this.readString();
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (/[0-9]/.test(char)) {
|
|
161
|
+
this.readNumber();
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (/[A-Za-z_]/.test(char)) {
|
|
165
|
+
this.readIdentifier();
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
throw new PointCoreLexerError(`Unexpected character ${JSON.stringify(char)}`, this.spanAt());
|
|
169
|
+
}
|
|
170
|
+
this.tokens.push({ type: "eof", value: "", span: this.spanAt() });
|
|
171
|
+
return this.tokens;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
private readString() {
|
|
175
|
+
const start = this.position();
|
|
176
|
+
this.advance();
|
|
177
|
+
let value = "";
|
|
178
|
+
while (!this.done() && this.peek() !== "\"") {
|
|
179
|
+
const next = this.advance();
|
|
180
|
+
if (next === "\\") {
|
|
181
|
+
const escaped = this.advance();
|
|
182
|
+
value += escaped === "n" ? "\n" : escaped;
|
|
183
|
+
} else {
|
|
184
|
+
value += next;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (this.peek() !== "\"") throw new PointCoreLexerError("Unterminated string", { start, end: this.position() });
|
|
188
|
+
this.advance();
|
|
189
|
+
this.tokens.push({ type: "string", value, span: { start, end: this.position() } });
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
private readNumber() {
|
|
193
|
+
const start = this.position();
|
|
194
|
+
let value = "";
|
|
195
|
+
while (/[0-9.]/.test(this.peek())) value += this.advance();
|
|
196
|
+
this.tokens.push({ type: "number", value, span: { start, end: this.position() } });
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private readIdentifier() {
|
|
200
|
+
const start = this.position();
|
|
201
|
+
let value = "";
|
|
202
|
+
while (/[A-Za-z0-9_]/.test(this.peek())) value += this.advance();
|
|
203
|
+
this.tokens.push({ type: "identifier", value, span: { start, end: this.position() } });
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
private push(type: PointCoreTokenType, value: string) {
|
|
207
|
+
const end = this.position();
|
|
208
|
+
this.tokens.push({
|
|
209
|
+
type,
|
|
210
|
+
value,
|
|
211
|
+
span: {
|
|
212
|
+
start: { line: end.line, column: end.column - value.length, offset: end.offset - value.length },
|
|
213
|
+
end,
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
private advance() {
|
|
219
|
+
const char = this.source[this.index++] ?? "";
|
|
220
|
+
if (char === "\n") {
|
|
221
|
+
this.line += 1;
|
|
222
|
+
this.column = 1;
|
|
223
|
+
} else {
|
|
224
|
+
this.column += 1;
|
|
225
|
+
}
|
|
226
|
+
return char;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
private peek(offset = 0) {
|
|
230
|
+
return this.source[this.index + offset] ?? "";
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
private done() {
|
|
234
|
+
return this.index >= this.source.length;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private position() {
|
|
238
|
+
return { line: this.line, column: this.column, offset: this.index };
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private spanAt(): PointSourceSpan {
|
|
242
|
+
const position = this.position();
|
|
243
|
+
return { start: position, end: position };
|
|
244
|
+
}
|
|
245
|
+
}
|