Skip to content

Commit 96ba7b4

Browse files
committed
0.1.0
0 parents  commit 96ba7b4

32 files changed

+4472
-0
lines changed

Diff for: .gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
.dist/

Diff for: .gitmodules

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[submodule "aiscript"]
2+
path = aiscript
3+
url = https://github.com/aiscript-dev/aiscript
4+
branch = aiscript-next

Diff for: aiscript

Submodule aiscript added at b9df8a4

Diff for: features/cli/index.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {
2+
createConnection,
3+
ProposedFeatures,
4+
} from "vscode-languageserver/node.js";
5+
import { LanguageServer } from "../core/server/LanguageServer.js";
6+
import { initAiScriptI18n } from "../core/i18n/aiscript/index.js";
7+
8+
const i18n = initAiScriptI18n("ja");
9+
10+
const server = new LanguageServer(i18n, createConnection(ProposedFeatures.all));
11+
12+
server.listen();

Diff for: features/core/errors/AiSyntaxError.ts

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { Token } from "@syuilo/aiscript/parser/token.js";
2+
import { SourceLocation } from "../parser/SourceRange.js";
3+
import { Ast } from "@syuilo/aiscript";
4+
5+
export enum AiSyntaxErrorId {
6+
invalidAttribute,
7+
UnExpectedToken,
8+
MultipleStatementsOnSingleLine,
9+
MissingThenClause,
10+
MissingCondition,
11+
SeparatorExpected,
12+
NonNumericSign,
13+
CanNotUseSpacesInReference,
14+
MissingIdentifier,
15+
MissingType,
16+
MissingParams,
17+
MissingFunctionBody,
18+
MissingExpr,
19+
MissingKeyword,
20+
MissingBody,
21+
MissingBracket,
22+
MissingAttribute,
23+
MissingLineBreak,
24+
MissingStatement,
25+
}
26+
27+
export class AiSyntaxError extends Error {
28+
constructor(
29+
public messageId: AiSyntaxErrorId,
30+
public token: Token | Ast.Node,
31+
public location: SourceLocation,
32+
) {
33+
super(AiSyntaxErrorId[messageId]);
34+
}
35+
}
36+
37+
export class AiMissingKeywordError extends AiSyntaxError {
38+
constructor(
39+
public keyword: string,
40+
token: Token | Ast.Node,
41+
location: SourceLocation,
42+
) {
43+
super(AiSyntaxErrorId.MissingKeyword, token, location);
44+
}
45+
}
46+
47+
export class AiMissingBracketError extends AiSyntaxError {
48+
constructor(
49+
public bracket: string,
50+
token: Token | Ast.Node,
51+
location: SourceLocation,
52+
) {
53+
super(AiSyntaxErrorId.MissingBracket, token, location);
54+
}
55+
}

Diff for: features/core/errors/AiTypeError.ts

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { I18nLocalizer } from "../index.js";
2+
import { SourceLocation } from "../parser/SourceRange.js";
3+
4+
export enum AiTypeErrorKind {
5+
AlreadyDeclaredVariable,
6+
NotAssignableType,
7+
CanNotCall,
8+
MissingArgumentError,
9+
InvalidArgumentError,
10+
CanNotAssignToImmutableVariable,
11+
}
12+
13+
export class AiTypeError extends Error {
14+
constructor(public kind: AiTypeErrorKind, public location: SourceLocation) {
15+
super(AiTypeErrorKind[kind]);
16+
}
17+
}
18+
19+
export class AiAlreadyDeclaredVariableError extends AiTypeError {
20+
constructor(public name: string, location: SourceLocation) {
21+
super(AiTypeErrorKind.AlreadyDeclaredVariable, location);
22+
}
23+
}
24+
25+
export class AiNotAssignableTypeError extends AiTypeError {
26+
constructor(
27+
public left: string,
28+
public right: string,
29+
location: SourceLocation
30+
) {
31+
super(AiTypeErrorKind.NotAssignableType, location);
32+
}
33+
}
34+
35+
export class AiCanNotCallError extends AiTypeError {
36+
constructor(public type: string, location: SourceLocation) {
37+
super(AiTypeErrorKind.CanNotCall, location);
38+
}
39+
}
40+
41+
export class AiMissingArgumentError extends AiTypeError {
42+
constructor(
43+
public pos: number,
44+
public expectType: string,
45+
location: SourceLocation
46+
) {
47+
super(AiTypeErrorKind.MissingArgumentError, location);
48+
}
49+
}
50+
51+
export class AiInvalidArgumentError extends AiTypeError {
52+
constructor(
53+
public pos: number,
54+
public expectType: string,
55+
public butType: string,
56+
location: SourceLocation
57+
) {
58+
super(AiTypeErrorKind.InvalidArgumentError, location);
59+
}
60+
}
61+
62+
export class AiCanNotAssignToImmutableVariableError extends AiTypeError {
63+
constructor(public name: string, location: SourceLocation) {
64+
super(AiTypeErrorKind.CanNotAssignToImmutableVariable, location);
65+
}
66+
}

Diff for: features/core/errors/index.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import {
2+
AiMissingBracketError,
3+
AiMissingKeywordError,
4+
AiSyntaxError,
5+
} from "./AiSyntaxError.js";
6+
import {
7+
AiAlreadyDeclaredVariableError,
8+
AiTypeError,
9+
AiNotAssignableTypeError,
10+
AiCanNotCallError,
11+
AiMissingArgumentError,
12+
AiInvalidArgumentError,
13+
AiCanNotAssignToImmutableVariableError,
14+
} from "./AiTypeError.js";
15+
16+
export type ParserError =
17+
| AiSyntaxError
18+
| AiMissingKeywordError
19+
| AiMissingBracketError;
20+
21+
export type TypeError =
22+
| AiTypeError
23+
| AiAlreadyDeclaredVariableError
24+
| AiNotAssignableTypeError
25+
| AiCanNotCallError
26+
| AiMissingArgumentError
27+
| AiInvalidArgumentError
28+
| AiCanNotAssignToImmutableVariableError;

Diff for: features/core/i18n/aiscript/index.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { I18n } from "../core.js";
2+
import { syntaxErrorMessage } from "./syntaxError.js";
3+
import { typeErrorMessage } from "./typeError.js";
4+
5+
export const initAiScriptI18n = <L extends "ja">(lang: L) =>
6+
new I18n(lang, {
7+
syntax: syntaxErrorMessage,
8+
typing: typeErrorMessage,
9+
});
10+
11+
export type AiScriptI18n = ReturnType<typeof initAiScriptI18n>;
12+
13+
export type AiScriptI18nMessages = AiScriptI18n extends I18n<any, infer T>
14+
? T
15+
: never;

Diff for: features/core/i18n/aiscript/syntaxError.ts

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import {
2+
AiMissingBracketError,
3+
AiMissingKeywordError,
4+
AiSyntaxErrorId,
5+
} from "../../errors/AiSyntaxError.js";
6+
import { ParserError } from "../../errors/index.js";
7+
import { Enum2Name } from "../../utils/type.js";
8+
import {
9+
I18n,
10+
I18nLangs,
11+
I18nLocalizerResult,
12+
I18nMessage,
13+
I18nMessages,
14+
I18nPath,
15+
} from "../core.js";
16+
import { AiScriptI18nMessages } from "./index.js";
17+
18+
export const syntaxErrorMessage = {
19+
ja: {
20+
invalidAttribute() {
21+
return "不正なAttributeです。";
22+
},
23+
UnExpectedToken() {
24+
return `予期しないトークンが現れました。`;
25+
},
26+
MultipleStatementsOnSingleLine() {
27+
return "複数のステートメントは同じ行に置くことはできません。";
28+
},
29+
MissingThenClause() {
30+
return "if文にはthen節が必要です。";
31+
},
32+
MissingCondition() {
33+
return "if文には条件が必要です。";
34+
},
35+
SeparatorExpected() {
36+
return "セパレーターが必要です。";
37+
},
38+
NonNumericSign() {
39+
return "数値以外にはこの演算子は使えません。";
40+
},
41+
CanNotUseSpacesInReference() {
42+
return "識別子に空白は使用できません。";
43+
},
44+
MissingIdentifier() {
45+
return "識別子が必要です。";
46+
},
47+
MissingType() {
48+
return "型が必要です。";
49+
},
50+
MissingParams() {
51+
return "引数部分が必要です。";
52+
},
53+
MissingFunctionBody() {
54+
return "関数には内容が必要です。";
55+
},
56+
MissingExpr() {
57+
return "式が必要です。";
58+
},
59+
MissingKeyword(name: string) {
60+
return `\`${name}\`キーワードが必要です。`;
61+
},
62+
MissingBody() {
63+
return `コードブロックが必要です。`;
64+
},
65+
MissingBracket(bracket: string) {
66+
return `\`${bracket}\`が必要です。`;
67+
},
68+
MissingAttribute() {
69+
return "Attributeが必要です。";
70+
},
71+
MissingLineBreak() {
72+
return "改行が必要です。";
73+
},
74+
MissingStatement() {
75+
return "ステートメントが必要です。";
76+
},
77+
} satisfies I18nMessage<keyof typeof AiSyntaxErrorId>,
78+
} satisfies I18nMessages;
79+
80+
export const parserErrorLocalizer = (
81+
err: ParserError
82+
): I18nLocalizerResult<AiScriptI18nMessages> => {
83+
if (err instanceof AiMissingBracketError) {
84+
return ["syntax.MissingBracket", [err.bracket]];
85+
} else if (err instanceof AiMissingKeywordError) {
86+
return ["syntax.MissingKeyword", [err.keyword]];
87+
}
88+
89+
switch (err.messageId) {
90+
case AiSyntaxErrorId.MissingBracket: {
91+
return ["syntax.MissingBracket", ["<unknown>"]];
92+
}
93+
94+
case AiSyntaxErrorId.MissingKeyword: {
95+
return ["syntax.MissingKeyword", ["<unknown>"]];
96+
}
97+
98+
default: {
99+
const id = err.messageId as Exclude<
100+
typeof err.messageId,
101+
AiSyntaxErrorId.MissingBracket | AiSyntaxErrorId.MissingKeyword
102+
>;
103+
104+
return [
105+
`syntax.${
106+
AiSyntaxErrorId[id] as Enum2Name<typeof AiSyntaxErrorId, typeof id>
107+
}`,
108+
[],
109+
];
110+
}
111+
}
112+
};

Diff for: features/core/i18n/aiscript/typeError.ts

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import {
2+
AiAlreadyDeclaredVariableError,
3+
AiCanNotAssignToImmutableVariableError,
4+
AiCanNotCallError,
5+
AiInvalidArgumentError,
6+
AiMissingArgumentError,
7+
AiNotAssignableTypeError,
8+
AiTypeErrorKind,
9+
} from "../../errors/AiTypeError.js";
10+
import { TypeError } from "../../index.js";
11+
import { I18nLocalizerResult, I18nMessage, I18nMessages } from "../core.js";
12+
import { AiScriptI18nMessages } from "./index.js";
13+
14+
export const typeErrorMessage = {
15+
ja: {
16+
NotAssignableType(dest: string, value: string) {
17+
return `型\`${dest}\`に、\`${value}\`は代入できません。`;
18+
},
19+
AlreadyDeclaredVariable(name: string) {
20+
return `変数\`${name}\`はすでに定義されています。`;
21+
},
22+
CanNotCall(type: string) {
23+
return `型\`${type}\`は関数型ではありません。`;
24+
},
25+
InvalidArgumentError(pos: number, dest: string, but: string) {
26+
return `${pos}番目の引数には型\`${dest}\`が必要ですが、\`${but}\`が与えられました。`;
27+
},
28+
MissingArgumentError(pos: number, dest: string) {
29+
return `${pos}番目の引数には型\`${dest}\`が必要ですが、何も与えられていません。`;
30+
},
31+
CanNotAssignToImmutableVariable(name: string) {
32+
return `変数\`${name}\`は不変なので、新たに代入することはできません。`;
33+
},
34+
} satisfies I18nMessage<keyof typeof AiTypeErrorKind>,
35+
} satisfies I18nMessages;
36+
37+
export const typeErrorLocalizer = (
38+
error: TypeError
39+
): I18nLocalizerResult<AiScriptI18nMessages> => {
40+
if (error instanceof AiNotAssignableTypeError) {
41+
return ["typing.NotAssignableType", [error.left, error.right]];
42+
} else if (error instanceof AiAlreadyDeclaredVariableError) {
43+
return ["typing.AlreadyDeclaredVariable", [error.name]];
44+
} else if (error instanceof AiCanNotCallError) {
45+
return ["typing.CanNotCall", [error.type]];
46+
} else if (error instanceof AiInvalidArgumentError) {
47+
return [
48+
"typing.InvalidArgumentError",
49+
[error.pos, error.expectType, error.butType],
50+
];
51+
} else if (error instanceof AiMissingArgumentError) {
52+
return ["typing.MissingArgumentError", [error.pos, error.expectType]];
53+
} else if (error instanceof AiCanNotAssignToImmutableVariableError) {
54+
return ["typing.CanNotAssignToImmutableVariable", [error.name]];
55+
}
56+
57+
switch (error.kind) {
58+
case AiTypeErrorKind.AlreadyDeclaredVariable:
59+
return ["typing.AlreadyDeclaredVariable", ["<:unknown:>"]];
60+
61+
case AiTypeErrorKind.NotAssignableType:
62+
return ["typing.NotAssignableType", ["<:unknown:>", "<:unknown:>"]];
63+
64+
case AiTypeErrorKind.CanNotCall:
65+
return ["typing.CanNotCall", ["<:unknown:>"]];
66+
67+
case AiTypeErrorKind.InvalidArgumentError:
68+
return [
69+
"typing.InvalidArgumentError",
70+
[-1, "<:unknown:>", "<:unknown:>"],
71+
];
72+
73+
case AiTypeErrorKind.MissingArgumentError:
74+
return ["typing.MissingArgumentError", [-1, "<:unknown:>"]];
75+
76+
case AiTypeErrorKind.CanNotAssignToImmutableVariable:
77+
return ["typing.CanNotAssignToImmutableVariable", ["<:unknown:>"]];
78+
}
79+
};

0 commit comments

Comments
 (0)