Skip to content

Commit

Permalink
basic support for optional chaining
Browse files Browse the repository at this point in the history
  • Loading branch information
y21 committed Dec 23, 2024
1 parent 52c80ea commit 38c8543
Show file tree
Hide file tree
Showing 11 changed files with 246 additions and 211 deletions.
65 changes: 29 additions & 36 deletions crates/dash_compiler/src/for_each_loop.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::mem;

use dash_middle::compiler::instruction::AssignKind;
use dash_middle::interner::{sym, Symbol};
use dash_middle::interner::{Symbol, sym};
use dash_middle::lexer::token::TokenType;
use dash_middle::parser::error::Error;
use dash_middle::parser::expr::{Expr, ExprKind};
Expand Down Expand Up @@ -99,60 +99,53 @@ impl<'a, 'cx, 'interner> ForEachDesugarCtxt<'a, 'cx, 'interner> {

/// Emits a loop, assuming that `iterator_local` has been initialized with the iterator
pub fn compile_loop(&mut self, label: Option<Symbol>, body: Box<Statement>) -> Result<(), Error> {
self.ib.visit_while_loop(
Span::COMPILER_GENERATED,
label,
WhileLoop {
condition: Expr {
self.ib.visit_while_loop(Span::COMPILER_GENERATED, label, WhileLoop {
condition: Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::unary(TokenType::LogicalNot, Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::unary(
TokenType::LogicalNot,
kind: ExprKind::property_access(
false,
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::property_access(
false,
kind: ExprKind::assignment_local_space(
self.gen_step_local,
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::assignment_local_space(
self.gen_step_local,
kind: ExprKind::function_call(
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::function_call(
kind: ExprKind::property_access(
false,
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::property_access(
kind: ExprKind::compiled(compile_local_load(
self.iterator_local,
false,
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::compiled(compile_local_load(
self.iterator_local,
false,
)),
},
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::identifier(sym::next),
},
),
)),
},
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::identifier(sym::next),
},
Vec::new(),
false,
),
},
TokenType::Assignment,
Vec::new(),
false,
),
},
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::identifier(sym::done),
},
TokenType::Assignment,
),
},
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::identifier(sym::done),
},
),
},
body,
}),
},
)?;
body,
})?;

Ok(())
}
Expand Down
88 changes: 51 additions & 37 deletions crates/dash_compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ use std::cell::{Cell, RefCell};
use std::collections::HashSet;
use std::rc::Rc;

use dash_log::{debug, span, Level};
use dash_log::{Level, debug, span};
use dash_middle::compiler::constant::{Buffer, ConstantPool, Function, NumberConstant, SymbolConstant};
use dash_middle::compiler::external::External;
use dash_middle::compiler::instruction::{AssignKind, Instruction, IntrinsicOperation};
use dash_middle::compiler::scope::{CompileValueType, LimitExceededError, Local, ScopeGraph};
use dash_middle::compiler::{CompileResult, DebugSymbols, FunctionCallMetadata, StaticImportKind};
use dash_middle::interner::{sym, StringInterner, Symbol};
use dash_middle::interner::{StringInterner, Symbol, sym};
use dash_middle::lexer::token::TokenType;
use dash_middle::parser::error::Error;
use dash_middle::parser::expr::{
ArrayLiteral, ArrayMemberKind, AssignmentExpr, AssignmentTarget, BinaryExpr, CallArgumentKind, ConditionalExpr,
Expr, ExprKind, FunctionCall, GroupingExpr, LiteralExpr, ObjectLiteral, ObjectMemberKind, Postfix,
PropertyAccessExpr, Seq, UnaryExpr,
Expr, ExprKind, FunctionCall, GroupingExpr, LiteralExpr, ObjectLiteral, ObjectMemberKind,
OptionalChainingComponent, OptionalChainingExpression, Postfix, PropertyAccessExpr, Seq, UnaryExpr,
};
use dash_middle::parser::statement::{
Asyncness, Binding, BlockStatement, Class, ClassMember, ClassMemberKey, ClassMemberValue, DoWhileLoop, ExportKind,
Expand All @@ -25,9 +25,9 @@ use dash_middle::parser::statement::{
use dash_middle::sourcemap::Span;
use dash_middle::util::Counter;
use dash_middle::visitor::Visitor;
use dash_optimizer::OptLevel;
use dash_optimizer::consteval::ConstFunctionEvalCtx;
use dash_optimizer::type_infer::{InferMode, LocalDeclToSlot, NameResolutionResults, TypeInferCtx};
use dash_optimizer::OptLevel;
use for_each_loop::{ForEachDesugarCtxt, ForEachLoopKind};
use instruction::compile_local_load;
use jump_container::JumpContainer;
Expand Down Expand Up @@ -414,6 +414,7 @@ impl Visitor<Result<(), Error>> for FunctionCompiler<'_> {
ExprKind::Class(e) => self.visit_class_expr(span, e),
ExprKind::Array(e) => self.visit_array_literal(span, e),
ExprKind::Object(e) => self.visit_object_literal(span, e),
ExprKind::Chaining(o) => self.visit_optional_chaining_expression(span, o),
ExprKind::Compiled(mut buf) => {
self.current_function_mut().buf.append(&mut buf);
Ok(())
Expand Down Expand Up @@ -1529,6 +1530,35 @@ impl Visitor<Result<(), Error>> for FunctionCompiler<'_> {
Ok(())
}

fn visit_optional_chaining_expression(
&mut self,
span: Span,
chain: OptionalChainingExpression,
) -> Result<(), Error> {
let mut ib = InstructionBuilder::new(self);
ib.accept_expr(*chain.base)?;

ib.build_jmpnullishnp(Label::IfBranch { branch_id: 0 }, true);

for component in chain.components {
match component {
OptionalChainingComponent::Ident(ident) => {
ib.build_static_prop_access(ident, false)
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;
}
}
}
ib.build_jmp(Label::IfEnd, true);

ib.add_local_label(Label::IfBranch { branch_id: 0 });
ib.build_undefined_constant()
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;

ib.add_local_label(Label::IfEnd);

Ok(())
}

fn visit_sequence_expr(&mut self, _span: Span, (expr1, expr2): Seq) -> Result<(), Error> {
self.accept_expr(*expr1)?;
InstructionBuilder::new(self).build_pop();
Expand Down Expand Up @@ -2222,14 +2252,10 @@ impl Visitor<Result<(), Error>> for FunctionCompiler<'_> {
// Class.prototype
let class_prototype = Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::property_access(
false,
load_class_binding.clone(),
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::identifier(sym::prototype),
},
),
kind: ExprKind::property_access(false, load_class_binding.clone(), Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::identifier(sym::prototype),
}),
};

let methods = class.members.iter().filter(|member| {
Expand Down Expand Up @@ -2260,25 +2286,17 @@ impl Visitor<Result<(), Error>> for FunctionCompiler<'_> {
kind: ExprKind::assignment(
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::property_access(
false,
class_prototype.clone(),
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::identifier(sym::__proto__),
},
),
kind: ExprKind::property_access(false, class_prototype.clone(), Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::identifier(sym::__proto__),
}),
},
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::property_access(
false,
super_id.clone(),
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::identifier(sym::prototype),
},
),
kind: ExprKind::property_access(false, super_id.clone(), Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::identifier(sym::prototype),
}),
},
TokenType::Assignment,
),
Expand All @@ -2291,14 +2309,10 @@ impl Visitor<Result<(), Error>> for FunctionCompiler<'_> {
kind: ExprKind::assignment(
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::property_access(
false,
load_class_binding.clone(),
Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::identifier(sym::__proto__),
},
),
kind: ExprKind::property_access(false, load_class_binding.clone(), Expr {
span: Span::COMPILER_GENERATED,
kind: ExprKind::identifier(sym::__proto__),
}),
},
super_id,
TokenType::Assignment,
Expand Down
22 changes: 8 additions & 14 deletions crates/dash_compiler/src/transformations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,10 @@ pub fn hoist_declarations(
}

if !stmts.is_empty() {
stmts.insert(
0,
Statement {
span: Span::COMPILER_GENERATED,
kind: StatementKind::Block(BlockStatement(prepend, *id)),
},
);
stmts.insert(0, Statement {
span: Span::COMPILER_GENERATED,
kind: StatementKind::Block(BlockStatement(prepend, *id)),
});
}
}

Expand Down Expand Up @@ -200,12 +197,9 @@ pub fn hoist_declarations(
if !ast.is_empty() {
let block_id = scopes.add_empty_block_scope(at, counter);

ast.insert(
0,
Statement {
span: Span::COMPILER_GENERATED,
kind: StatementKind::Block(BlockStatement(prepend_function_assigns, block_id)),
},
);
ast.insert(0, Statement {
span: Span::COMPILER_GENERATED,
kind: StatementKind::Block(BlockStatement(prepend_function_assigns, block_id)),
});
}
}
Loading

0 comments on commit 38c8543

Please sign in to comment.