diff --git a/src/interpreter/index.ts b/src/interpreter/index.ts index 3e4124d2..80cfbd7d 100644 --- a/src/interpreter/index.ts +++ b/src/interpreter/index.ts @@ -205,7 +205,7 @@ export class Interpreter { } const value = await this._eval(node.expr, nsScope); - this.define(nsScope, node.dest, value, node.mut); + await this.define(nsScope, node.dest, value, node.mut); break; } @@ -396,7 +396,7 @@ export class Interpreter { } value.attr = attrs; } - this.define(scope, node.dest, value, node.mut); + await this.define(scope, node.dest, value, node.mut); return NULL; } diff --git a/src/parser/plugins/validate-keyword.ts b/src/parser/plugins/validate-keyword.ts index d42db44d..6bd4bbb4 100644 --- a/src/parser/plugins/validate-keyword.ts +++ b/src/parser/plugins/validate-keyword.ts @@ -56,15 +56,33 @@ function throwReservedWordError(name: string, loc: Ast.Loc): void { throw new AiScriptSyntaxError(`Reserved word "${name}" cannot be used as variable name.`, loc.start); } +function validateDest(node: Ast.Node): Ast.Node { + return visitNode(node, node => { + switch (node.type) { + case 'null': { + throwReservedWordError(node.type, node.loc); + break; + } + case 'bool': { + throwReservedWordError(`${node.value}`, node.loc); + break; + } + case 'identifier': { + if (reservedWord.includes(node.name)) { + throwReservedWordError(node.name, node.loc); + } + break; + } + } + + return node; + }); +} + function validateNode(node: Ast.Node): Ast.Node { switch (node.type) { case 'def': { - visitNode(node, node => { - if (node.type === 'identifier' && reservedWord.includes(node.name)) { - throwReservedWordError(node.name, node.loc); - } - return node; - }); + validateDest(node.dest); break; } case 'ns': diff --git a/src/parser/syntaxes/statements.ts b/src/parser/syntaxes/statements.ts index 3ccf24d9..0a844871 100644 --- a/src/parser/syntaxes/statements.ts +++ b/src/parser/syntaxes/statements.ts @@ -100,7 +100,7 @@ export function parseBlockOrStatement(s: ITokenStream): Ast.Statement | Ast.Expr /** * ```abnf - * VarDef = ("let" / "var") IDENT [":" Type] "=" Expr + * VarDef = ("let" / "var") (IDENT / Expr) [":" Type] "=" Expr * ``` */ function parseVarDef(s: ITokenStream): Ast.Definition { @@ -123,7 +123,7 @@ function parseVarDef(s: ITokenStream): Ast.Definition { s.next(); let dest: Ast.Expression; - // 全部parseExprに任せるとparseReferenceが型注釈を巻き込んでしまうためIdentifierのみ個別に処理。 + // 全部parseExprに任せるとparseReferenceが型注釈を巻き込んでパースしてしまうためIdentifierのみ個別に処理。 if (s.is(TokenKind.Identifier)) { const nameStartPos = s.getPos(); const name = s.getTokenValue();