mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Enable defining Symbol.iterator on classes
This commit is contained in:
@@ -15,6 +15,7 @@ mod name_allocator;
|
||||
mod resolve_path;
|
||||
mod scope;
|
||||
mod scope_analysis;
|
||||
mod static_eval_expr;
|
||||
|
||||
pub use assembler::assemble;
|
||||
pub use assembly_parser::parse_module;
|
||||
|
||||
@@ -14,9 +14,10 @@ use crate::asm::{
|
||||
use crate::diagnostic::{Diagnostic, DiagnosticLevel};
|
||||
use crate::expression_compiler::{CompiledExpression, ExpressionCompiler};
|
||||
use crate::function_compiler::{FunctionCompiler, Functionish};
|
||||
use crate::name_allocator::NameAllocator;
|
||||
use crate::name_allocator::{ident_from_str, NameAllocator};
|
||||
use crate::scope::OwnerId;
|
||||
use crate::scope_analysis::ScopeAnalysis;
|
||||
use crate::static_eval_expr::static_eval_expr;
|
||||
|
||||
struct DiagnosticCollector {
|
||||
diagnostics: Arc<Mutex<Vec<Diagnostic>>>,
|
||||
@@ -781,14 +782,28 @@ impl ModuleCompiler {
|
||||
Constructor(_) => {}
|
||||
Method(method) => {
|
||||
let name = match &method.key {
|
||||
swc_ecma_ast::PropName::Ident(ident) => ident.sym.to_string(),
|
||||
swc_ecma_ast::PropName::Ident(ident) => Value::String(ident.sym.to_string()),
|
||||
swc_ecma_ast::PropName::Computed(computed) => match static_eval_expr(&computed.expr) {
|
||||
None => {
|
||||
self.todo(
|
||||
computed.span,
|
||||
"Couldn't statically evaluate computed prop name",
|
||||
);
|
||||
continue;
|
||||
}
|
||||
Some(value) => value,
|
||||
},
|
||||
_ => {
|
||||
self.todo(method.span, "Non-identifier method name");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let method_defn_name = self.allocate_defn(&format!("{}_{}", defn_name.name, name));
|
||||
let method_defn_name = self.allocate_defn(&ident_from_str(&format!(
|
||||
"{}_{}",
|
||||
defn_name.name,
|
||||
name.to_string()
|
||||
)));
|
||||
|
||||
dependent_definitions.append(&mut self.compile_fn(
|
||||
method_defn_name.clone(),
|
||||
@@ -798,7 +813,7 @@ impl ModuleCompiler {
|
||||
|
||||
methods
|
||||
.properties
|
||||
.push((Value::String(name), Value::Pointer(method_defn_name)));
|
||||
.push((name, Value::Pointer(method_defn_name)));
|
||||
}
|
||||
PrivateMethod(private_method) => self.todo(private_method.span, "PrivateMethod"),
|
||||
|
||||
|
||||
@@ -67,6 +67,43 @@ impl NameAllocator {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ident_from_str(str: &str) -> String {
|
||||
let mut res = "".to_string();
|
||||
let mut first = false;
|
||||
let mut last_sep = false;
|
||||
|
||||
for c in str.chars() {
|
||||
if first {
|
||||
first = false;
|
||||
|
||||
if c.is_ascii_alphabetic() {
|
||||
res.push(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
res.push('_');
|
||||
last_sep = true;
|
||||
}
|
||||
|
||||
if !c.is_ascii_alphanumeric() {
|
||||
if !last_sep {
|
||||
res.push('_');
|
||||
last_sep = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
res.push(c);
|
||||
last_sep = false;
|
||||
}
|
||||
|
||||
match last_sep && res.len() > 1 {
|
||||
false => res,
|
||||
true => res[0..res.len() - 1].to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PointerAllocator {
|
||||
alloc: NameAllocator,
|
||||
|
||||
30
valuescript_compiler/src/static_eval_expr.rs
Normal file
30
valuescript_compiler/src/static_eval_expr.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use crate::asm::{Builtin, Value};
|
||||
|
||||
pub fn static_eval_expr(expr: &swc_ecma_ast::Expr) -> Option<Value> {
|
||||
let member_expr = match expr {
|
||||
swc_ecma_ast::Expr::Member(member_expr) => member_expr,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
match &*member_expr.obj {
|
||||
swc_ecma_ast::Expr::Ident(ident) => {
|
||||
if ident.sym.to_string() != "Symbol" {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
match &member_expr.prop {
|
||||
swc_ecma_ast::MemberProp::Ident(ident) => {
|
||||
if ident.sym.to_string() != "iterator" {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
_ => return None,
|
||||
}
|
||||
|
||||
return Some(Value::Builtin(Builtin {
|
||||
name: "SymbolIterator".to_string(),
|
||||
}));
|
||||
}
|
||||
Reference in New Issue
Block a user