Skip to content

feat: WIP enums implementation #374

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
22 changes: 19 additions & 3 deletions nova_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -88,11 +96,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
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() {
Expand All @@ -107,7 +119,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
exit_with_parse_errors(result.errors, &path, &file);
}

println!("{:?}", result.program);
if pretty {
println!("{:#?}", result.program);
} else {
println!("{:?}", result.program);
}
}
Command::Eval {
verbose,
Expand Down
49 changes: 33 additions & 16 deletions nova_vm/src/ecmascript/syntax_directed_operations/scope_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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(_) |
Expand Down Expand Up @@ -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!(),
Expand Down Expand Up @@ -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!(),
Expand Down Expand Up @@ -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!(),
Expand Down Expand Up @@ -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!(),
Expand Down
24 changes: 21 additions & 3 deletions nova_vm/src/engine/bytecode/executable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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!(),
Expand All @@ -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!(),
Expand Down