diff --git a/nova_cli/src/main.rs b/nova_cli/src/main.rs index 9d75ef8f6..98bd43e34 100644 --- a/nova_cli/src/main.rs +++ b/nova_cli/src/main.rs @@ -37,6 +37,14 @@ enum Command { Parse { /// The path of the file to parse path: String, + + /// Whether to parse as TypeScript + #[arg(long)] + typescript: bool, + + /// Whether to pretty print the AST + #[arg(long)] + pretty: bool, }, /// Evaluates a file @@ -88,11 +96,15 @@ fn main() -> Result<(), Box> { let args = Cli::parse(); match args.command { - Command::Parse { path } => { + Command::Parse { + path, + typescript, + pretty, + } => { let file = std::fs::read_to_string(&path)?; let allocator = Default::default(); let source_type: SourceType = Default::default(); - let parser = Parser::new(&allocator, &file, source_type.with_typescript(false)); + let parser = Parser::new(&allocator, &file, source_type.with_typescript(typescript)); let result = parser.parse(); if !result.errors.is_empty() { @@ -107,7 +119,11 @@ fn main() -> Result<(), Box> { exit_with_parse_errors(result.errors, &path, &file); } - println!("{:?}", result.program); + if pretty { + println!("{:#?}", result.program); + } else { + println!("{:?}", result.program); + } } Command::Eval { verbose, diff --git a/nova_vm/src/ecmascript/syntax_directed_operations/scope_analysis.rs b/nova_vm/src/ecmascript/syntax_directed_operations/scope_analysis.rs index 285a949d8..2d57dd77d 100644 --- a/nova_vm/src/ecmascript/syntax_directed_operations/scope_analysis.rs +++ b/nova_vm/src/ecmascript/syntax_directed_operations/scope_analysis.rs @@ -711,6 +711,9 @@ impl<'a> VarDeclaredNames<'a> for Statement<'a> { } // 4. Return the list-concatenation of names1, names2, and names3. }, + #[cfg(feature = "typescript")] + Statement::TSEnumDeclaration(_) => {}, + Statement::WhileStatement(st) => { // WhileStatement : while ( Expression ) Statement // 1. Return the VarDeclaredNames of Statement. @@ -737,7 +740,8 @@ impl<'a> VarDeclaredNames<'a> for Statement<'a> { } } }, - Statement::TSEnumDeclaration(_) | + #[cfg(not(feature = "typescript"))] + Statement::TSEnumDeclaration(_) => unreachable!(), Statement::TSExportAssignment(_) | Statement::TSImportEqualsDeclaration(_) | Statement::TSInterfaceDeclaration(_) | @@ -1080,15 +1084,18 @@ impl<'a> TopLevelLexicallyDeclaredNames<'a> for Statement<'a> { Statement::ImportDeclaration(decl) => decl.bound_names(f), Statement::ExportNamedDeclaration(decl) => decl.bound_names(f), #[cfg(feature = "typescript")] - Statement::TSTypeAliasDeclaration(_) | Statement::TSInterfaceDeclaration(_) => {} + Statement::TSTypeAliasDeclaration(_) + | Statement::TSInterfaceDeclaration(_) + | Statement::TSEnumDeclaration(_) => {} #[cfg(not(feature = "typescript"))] - Statement::TSTypeAliasDeclaration(_) | Statement::TSInterfaceDeclaration(_) => { + Statement::TSTypeAliasDeclaration(_) + | Statement::TSInterfaceDeclaration(_) + | Statement::TSEnumDeclaration(_) => { unreachable!() } // Note: No bounds names for export all and export default declarations. Statement::ExportAllDeclaration(_) | Statement::ExportDefaultDeclaration(_) => {} - Statement::TSEnumDeclaration(_) - | Statement::TSModuleDeclaration(_) + Statement::TSModuleDeclaration(_) | Statement::TSImportEqualsDeclaration(_) | Statement::TSExportAssignment(_) | Statement::TSNamespaceExportDeclaration(_) => unreachable!(), @@ -1163,13 +1170,16 @@ impl<'a> TopLevelLexicallyScopedDeclarations<'a> for Statement<'a> { Statement::ClassDeclaration(decl) => f(LexicallyScopedDeclaration::Class(decl)), Statement::UsingDeclaration(_) => todo!(), #[cfg(feature = "typescript")] - Statement::TSTypeAliasDeclaration(_) | Statement::TSInterfaceDeclaration(_) => {} + Statement::TSTypeAliasDeclaration(_) + | Statement::TSInterfaceDeclaration(_) + | Statement::TSEnumDeclaration(_) => {} #[cfg(not(feature = "typescript"))] - Statement::TSTypeAliasDeclaration(_) | Statement::TSInterfaceDeclaration(_) => { + Statement::TSTypeAliasDeclaration(_) + | Statement::TSInterfaceDeclaration(_) + | Statement::TSEnumDeclaration(_) => { unreachable!() } - Statement::TSEnumDeclaration(_) - | Statement::TSExportAssignment(_) + Statement::TSExportAssignment(_) | Statement::TSImportEqualsDeclaration(_) | Statement::TSModuleDeclaration(_) | Statement::TSNamespaceExportDeclaration(_) => unreachable!(), @@ -1250,13 +1260,16 @@ impl<'a> TopLevelVarDeclaredNames<'a> for Statement<'a> { | Statement::WhileStatement(_) | Statement::WithStatement(_) => self.var_declared_names(f), #[cfg(feature = "typescript")] + Statement::TSEnumDeclaration(_) => self.var_declared_names(f), + #[cfg(feature = "typescript")] Statement::TSTypeAliasDeclaration(_) | Statement::TSInterfaceDeclaration(_) => {} #[cfg(not(feature = "typescript"))] - Statement::TSTypeAliasDeclaration(_) | Statement::TSInterfaceDeclaration(_) => { + Statement::TSTypeAliasDeclaration(_) + | Statement::TSInterfaceDeclaration(_) + | Statement::TSEnumDeclaration(_) => { unreachable!() } - Statement::TSEnumDeclaration(_) - | Statement::TSExportAssignment(_) + Statement::TSExportAssignment(_) | Statement::TSImportEqualsDeclaration(_) | Statement::TSModuleDeclaration(_) | Statement::TSNamespaceExportDeclaration(_) => unreachable!(), @@ -1379,14 +1392,18 @@ impl<'a> TopLevelVarScopedDeclarations<'a> for Statement<'a> { // 2. Return a new empty List. } #[cfg(feature = "typescript")] - Statement::TSTypeAliasDeclaration(_) | Statement::TSInterfaceDeclaration(_) => {} + Statement::TSTypeAliasDeclaration(_) + | Statement::TSInterfaceDeclaration(_) + | Statement::TSEnumDeclaration(_) => {} #[cfg(not(feature = "typescript"))] - Statement::TSTypeAliasDeclaration(_) | Statement::TSInterfaceDeclaration(_) => { + Statement::TSTypeAliasDeclaration(_) + | Statement::TSInterfaceDeclaration(_) + | Statement::TSEnumDeclaration(_) => { unreachable!() } Statement::UsingDeclaration(_) => todo!(), - Statement::TSEnumDeclaration(_) - | Statement::TSExportAssignment(_) + + Statement::TSExportAssignment(_) | Statement::TSImportEqualsDeclaration(_) | Statement::TSModuleDeclaration(_) | Statement::TSNamespaceExportDeclaration(_) => unreachable!(), diff --git a/nova_vm/src/engine/bytecode/executable.rs b/nova_vm/src/engine/bytecode/executable.rs index bac5ec944..08a786af5 100644 --- a/nova_vm/src/engine/bytecode/executable.rs +++ b/nova_vm/src/engine/bytecode/executable.rs @@ -2891,6 +2891,21 @@ impl CompileEvaluation for ast::TryStatement<'_> { ctx.exe.set_jump_target_here(jump_to_end); } } +#[cfg(feature = "typescript")] +impl CompileEvaluation for ast::TSEnumDeclaration<'_> { + fn compile(&self, ctx: &mut CompileContext) { + // TODO: implement enum declaration + // NOTE: remember not to forget to treat const enums differently + + // content of the enum is not evaluated, it is just a declaration + ctx.exe.add_instruction(Instruction::ObjectCreate); + for _prop in self.members.iter() { + todo!("enum member"); + } + // 3. Return enumObj. + ctx.exe.add_instruction(Instruction::Store); + } +} impl CompileEvaluation for ast::WhileStatement<'_> { fn compile(&self, ctx: &mut CompileContext) { @@ -3005,6 +3020,8 @@ impl CompileEvaluation for ast::Statement<'_> { ast::Statement::ForStatement(x) => x.compile(ctx), ast::Statement::ThrowStatement(x) => x.compile(ctx), ast::Statement::TryStatement(x) => x.compile(ctx), + #[cfg(feature = "typescript")] + Statement::TSEnumDeclaration(statement) => statement.compile(ctx), Statement::BreakStatement(statement) => statement.compile(ctx), Statement::ContinueStatement(statement) => statement.compile(ctx), Statement::DebuggerStatement(_) => todo!(), @@ -3024,11 +3041,12 @@ impl CompileEvaluation for ast::Statement<'_> { #[cfg(feature = "typescript")] Statement::TSTypeAliasDeclaration(_) | Statement::TSInterfaceDeclaration(_) => {} #[cfg(not(feature = "typescript"))] - Statement::TSTypeAliasDeclaration(_) | Statement::TSInterfaceDeclaration(_) => { + Statement::TSTypeAliasDeclaration(_) + | Statement::TSInterfaceDeclaration(_) + | Statement::TSEnumDeclaration(_) => { unreachable!() } - Statement::TSEnumDeclaration(_) - | Statement::TSExportAssignment(_) + Statement::TSExportAssignment(_) | Statement::TSImportEqualsDeclaration(_) | Statement::TSModuleDeclaration(_) | Statement::TSNamespaceExportDeclaration(_) => unreachable!(),