mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
wip
This commit is contained in:
@@ -11,6 +11,7 @@ mod ident;
|
||||
mod import_pattern;
|
||||
mod instruction;
|
||||
mod link_module;
|
||||
mod minify;
|
||||
mod module_compiler;
|
||||
mod name_allocator;
|
||||
mod optimization;
|
||||
|
||||
94
valuescript_compiler/src/minify.rs
Normal file
94
valuescript_compiler/src/minify.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
use std::{
|
||||
iter::{Peekable, Skip, Take},
|
||||
str::Chars,
|
||||
};
|
||||
|
||||
use swc_common::BytePos;
|
||||
|
||||
pub fn minify(source: &str, span: swc_common::Span) -> String {
|
||||
let mut minifier = Minifier::new(source, span);
|
||||
minifier.run();
|
||||
|
||||
minifier.res
|
||||
}
|
||||
|
||||
struct Minifier<'a> {
|
||||
chars: Peekable<Take<Skip<Chars<'a>>>>,
|
||||
res: String,
|
||||
}
|
||||
|
||||
impl<'a> Minifier<'a> {
|
||||
fn new(source: &'a str, span: swc_common::Span) -> Self {
|
||||
let BytePos(start) = span.lo;
|
||||
let BytePos(end) = span.hi;
|
||||
|
||||
let chars = source
|
||||
.chars()
|
||||
.skip(start as usize)
|
||||
.take((end - start) as usize)
|
||||
.peekable();
|
||||
|
||||
Minifier {
|
||||
chars,
|
||||
res: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn run(&mut self) {
|
||||
let mut punctuation_last = true;
|
||||
|
||||
while let Some(c) = self.chars.peek().cloned() {
|
||||
if c.is_ascii_whitespace() {
|
||||
self.skip_ws(punctuation_last);
|
||||
continue;
|
||||
}
|
||||
|
||||
self.res.push(c);
|
||||
self.chars.next();
|
||||
|
||||
punctuation_last = is_js_punctuation(c);
|
||||
|
||||
match c {
|
||||
'\'' | '"' => self.simple_string(c),
|
||||
'`' => self.template_string(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn skip_ws(&mut self, punctuation_last: bool) {
|
||||
while let Some(c) = self.chars.peek().cloned() {
|
||||
if !c.is_ascii_whitespace() {
|
||||
if !punctuation_last && !is_js_punctuation(c) {
|
||||
self.res.push(' ');
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
self.chars.next();
|
||||
}
|
||||
}
|
||||
|
||||
fn simple_string(&mut self, quote_c: char) {
|
||||
let mut escaping = false;
|
||||
|
||||
for c in &mut self.chars {
|
||||
self.res.push(c);
|
||||
|
||||
if !escaping && c == quote_c {
|
||||
break;
|
||||
}
|
||||
|
||||
escaping = c == '\\';
|
||||
}
|
||||
}
|
||||
|
||||
fn template_string(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn is_js_punctuation(c: char) -> bool {
|
||||
c.is_ascii_punctuation() && !matches!(c, '$' | '_')
|
||||
}
|
||||
@@ -15,6 +15,7 @@ use crate::diagnostic::{Diagnostic, DiagnosticContainer, DiagnosticReporter};
|
||||
use crate::expression_compiler::{CompiledExpression, ExpressionCompiler};
|
||||
use crate::function_compiler::{FunctionCompiler, Functionish};
|
||||
use crate::ident::Ident;
|
||||
use crate::minify::minify;
|
||||
use crate::name_allocator::{ident_from_str, NameAllocator};
|
||||
use crate::scope::OwnerId;
|
||||
use crate::scope_analysis::{class_to_owner_id, ScopeAnalysis};
|
||||
@@ -70,8 +71,8 @@ pub struct CompilerOutput {
|
||||
pub module: Module,
|
||||
}
|
||||
|
||||
pub fn compile_program(program: &swc_ecma_ast::Program) -> CompilerOutput {
|
||||
let compiler = ModuleCompiler::compile_program(program);
|
||||
pub fn compile_program(source: &str, program: &swc_ecma_ast::Program) -> CompilerOutput {
|
||||
let compiler = ModuleCompiler::compile_program(source, program);
|
||||
|
||||
CompilerOutput {
|
||||
diagnostics: compiler.diagnostics.take(),
|
||||
@@ -83,7 +84,7 @@ pub fn compile_module(source: &str) -> CompilerOutput {
|
||||
let (program_optional, mut diagnostics) = parse(source);
|
||||
|
||||
let mut compiler_output = match program_optional {
|
||||
Some(program) => compile_program(&program),
|
||||
Some(program) => compile_program(source, &program),
|
||||
None => CompilerOutput::default(),
|
||||
};
|
||||
|
||||
@@ -99,6 +100,7 @@ pub struct ModuleCompiler {
|
||||
pub definition_allocator: NameAllocator,
|
||||
pub scope_analysis: ScopeAnalysis,
|
||||
pub constants_map: HashMap<Pointer, Value>,
|
||||
pub source: String,
|
||||
pub module: Module,
|
||||
}
|
||||
|
||||
@@ -125,7 +127,7 @@ impl ModuleCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_program(program: &swc_ecma_ast::Program) -> Self {
|
||||
fn compile_program(source: &str, program: &swc_ecma_ast::Program) -> Self {
|
||||
use swc_ecma_ast::Program::*;
|
||||
|
||||
let module = match program {
|
||||
@@ -144,6 +146,7 @@ impl ModuleCompiler {
|
||||
let mut self_ = Self {
|
||||
scope_analysis,
|
||||
diagnostics: RefCell::new(diagnostics),
|
||||
source: source.to_string(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@@ -153,6 +156,8 @@ impl ModuleCompiler {
|
||||
}
|
||||
|
||||
fn compile_module(&mut self, module: &swc_ecma_ast::Module) {
|
||||
println!("Min: {}", minify(&self.source, module.span));
|
||||
|
||||
for module_item in &module.body {
|
||||
self.compile_module_item(module_item);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user