mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Update ExportStar representation
This commit is contained in:
@@ -11,10 +11,36 @@ pub use crate::instruction::{Instruction, InstructionFieldMut};
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Module {
|
||||
pub export_default: Value,
|
||||
pub export_star: Object,
|
||||
pub export_star: ExportStar,
|
||||
pub definitions: Vec<Definition>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ExportStar {
|
||||
pub includes: Vec<Pointer>,
|
||||
pub local: Object,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ExportStar {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if self.local.properties.is_empty() && self.includes.is_empty() {
|
||||
return write!(f, "{{}}");
|
||||
}
|
||||
|
||||
writeln!(f, "{{")?;
|
||||
|
||||
for p in &self.includes {
|
||||
writeln!(f, " include {},", p)?;
|
||||
}
|
||||
|
||||
for (name, value) in &self.local.properties {
|
||||
writeln!(f, " {}: {},", name, value)?;
|
||||
}
|
||||
|
||||
write!(f, "}}")
|
||||
}
|
||||
}
|
||||
|
||||
impl Module {
|
||||
pub fn as_lines(&self) -> Vec<String> {
|
||||
let assembly_str = self.to_string();
|
||||
@@ -26,17 +52,7 @@ impl Module {
|
||||
|
||||
impl std::fmt::Display for Module {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
if self.export_star.properties.is_empty() {
|
||||
write!(f, "export {} {}", self.export_default, self.export_star)?;
|
||||
} else {
|
||||
writeln!(f, "export {} {{", self.export_default)?;
|
||||
|
||||
for (name, value) in &self.export_star.properties {
|
||||
writeln!(f, " {}: {},", name, value)?;
|
||||
}
|
||||
|
||||
write!(f, "}}")?;
|
||||
}
|
||||
write!(f, "export {} {}", self.export_default, self.export_star)?;
|
||||
|
||||
for definition in &self.definitions {
|
||||
write!(f, "\n\n{}", definition)?;
|
||||
|
||||
@@ -36,7 +36,14 @@ struct Assembler {
|
||||
impl Assembler {
|
||||
fn module(&mut self, module: &Module) {
|
||||
self.value(&module.export_default);
|
||||
self.object(&module.export_star);
|
||||
self.output.push(ValueType::ExportStar as u8);
|
||||
self.varsize_uint(module.export_star.includes.len());
|
||||
|
||||
for p in &module.export_star.includes {
|
||||
self.pointer(p);
|
||||
}
|
||||
|
||||
self.object(&module.export_star.local);
|
||||
|
||||
for definition in &module.definitions {
|
||||
self.definition(definition);
|
||||
@@ -448,6 +455,7 @@ pub enum ValueType {
|
||||
Lazy = 0x12,
|
||||
BigInt = 0x13,
|
||||
GeneratorFunction = 0x14,
|
||||
ExportStar = 0x15,
|
||||
// External = TBD,
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ use num_bigint::BigInt;
|
||||
use valuescript_common::{InstructionByte, BUILTIN_NAMES};
|
||||
|
||||
use crate::asm::{
|
||||
Array, Builtin, Class, Definition, DefinitionContent, FnLine, Function, Instruction, Label,
|
||||
LabelRef, Module, Number, Object, Pointer, Register, Value,
|
||||
Array, Builtin, Class, Definition, DefinitionContent, ExportStar, FnLine, Function, Instruction,
|
||||
Label, LabelRef, Module, Number, Object, Pointer, Register, Value,
|
||||
};
|
||||
|
||||
pub struct AssemblyParser<'a> {
|
||||
@@ -22,7 +22,7 @@ impl<'a> AssemblyParser<'a> {
|
||||
let export_default = self.assemble_value();
|
||||
self.parse_whitespace();
|
||||
|
||||
let export_star = self.assemble_object();
|
||||
let export_star = self.assemble_export_star();
|
||||
self.parse_whitespace();
|
||||
|
||||
let mut definitions = Vec::<Definition>::new();
|
||||
@@ -777,11 +777,7 @@ impl<'a> AssemblyParser<'a> {
|
||||
panic!("{}", self.render_pos(0, &"Expected value".to_string()));
|
||||
}
|
||||
Some('%') => Value::Register(self.assemble_register()),
|
||||
Some('@') => {
|
||||
self.parse_exact("@");
|
||||
let name = self.parse_identifier();
|
||||
Value::Pointer(Pointer { name })
|
||||
}
|
||||
Some('@') => Value::Pointer(self.assemble_pointer()),
|
||||
Some('$') => Value::Builtin(self.assemble_builtin()),
|
||||
Some('[') => Value::Array(Box::new(self.assemble_array())),
|
||||
Some('-' | '.' | '0'..='9') => self.assemble_number(),
|
||||
@@ -826,6 +822,12 @@ impl<'a> AssemblyParser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn assemble_pointer(&mut self) -> Pointer {
|
||||
self.parse_exact("@");
|
||||
let name = self.parse_identifier();
|
||||
Pointer { name }
|
||||
}
|
||||
|
||||
fn assemble_array(&mut self) -> Array {
|
||||
let mut array = Array::default();
|
||||
|
||||
@@ -964,26 +966,14 @@ impl<'a> AssemblyParser<'a> {
|
||||
self.parse_exact("{");
|
||||
|
||||
loop {
|
||||
self.parse_optional_whitespace();
|
||||
let mut c = *self.pos.peek().expect("Expected object content or end");
|
||||
|
||||
let key = match c {
|
||||
'}' => {
|
||||
self.pos.next();
|
||||
break object;
|
||||
}
|
||||
_ => self.assemble_value(),
|
||||
match self.assemble_object_kv() {
|
||||
None => break object,
|
||||
Some(kv) => object.properties.push(kv),
|
||||
};
|
||||
|
||||
self.parse_optional_whitespace();
|
||||
self.parse_exact(":");
|
||||
let value = self.assemble_value();
|
||||
|
||||
object.properties.push((key, value));
|
||||
|
||||
self.parse_optional_whitespace();
|
||||
|
||||
c = *self.pos.peek().expect("Expected comma or object end");
|
||||
let c = *self.pos.peek().expect("Expected comma or object end");
|
||||
|
||||
match c {
|
||||
',' => {
|
||||
@@ -1002,6 +992,87 @@ impl<'a> AssemblyParser<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn assemble_object_kv(&mut self) -> Option<(Value, Value)> {
|
||||
self.parse_optional_whitespace();
|
||||
let c = *self.pos.peek().expect("Expected object content or end");
|
||||
|
||||
let key = match c {
|
||||
'}' => {
|
||||
self.pos.next();
|
||||
return None;
|
||||
}
|
||||
_ => self.assemble_value(),
|
||||
};
|
||||
|
||||
self.parse_optional_whitespace();
|
||||
self.parse_exact(":");
|
||||
let value = self.assemble_value();
|
||||
|
||||
Some((key, value))
|
||||
}
|
||||
|
||||
fn assemble_export_star(&mut self) -> ExportStar {
|
||||
let mut export_star = ExportStar::default();
|
||||
|
||||
self.parse_exact("{");
|
||||
|
||||
loop {
|
||||
self.parse_optional_whitespace();
|
||||
|
||||
if self.parse_one_of(&["include ", ""]) == "" {
|
||||
break;
|
||||
}
|
||||
|
||||
export_star.includes.push(self.assemble_pointer());
|
||||
self.parse_optional_whitespace();
|
||||
|
||||
let c = *self.pos.peek().expect("Expected comma or object end");
|
||||
|
||||
match c {
|
||||
',' => {
|
||||
self.pos.next();
|
||||
}
|
||||
'}' => {
|
||||
self.pos.next();
|
||||
return export_star;
|
||||
}
|
||||
_ => {
|
||||
panic!(
|
||||
"{}",
|
||||
self.render_pos(0, &format!("Unexpected character {}", c))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
match self.assemble_object_kv() {
|
||||
None => break export_star,
|
||||
Some(kv) => export_star.local.properties.push(kv),
|
||||
};
|
||||
|
||||
self.parse_optional_whitespace();
|
||||
|
||||
let c = *self.pos.peek().expect("Expected comma or object end");
|
||||
|
||||
match c {
|
||||
',' => {
|
||||
self.pos.next();
|
||||
}
|
||||
'}' => {
|
||||
self.pos.next();
|
||||
break export_star;
|
||||
}
|
||||
_ => {
|
||||
panic!(
|
||||
"{}",
|
||||
self.render_pos(0, &format!("Unexpected character {}", c))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_module(content: &str) -> Module {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::asm::{Definition, DefinitionContent, FnLine, Instruction, Object, Pointer, Value};
|
||||
use crate::asm::{Definition, DefinitionContent, ExportStar, FnLine, Instruction, Pointer, Value};
|
||||
use crate::gather_modules::PathAndModule;
|
||||
use crate::import_pattern::{ImportKind, ImportPattern};
|
||||
use crate::name_allocator::NameAllocator;
|
||||
@@ -25,7 +25,7 @@ pub fn link_module(
|
||||
};
|
||||
|
||||
let mut pointer_allocator = NameAllocator::default();
|
||||
let mut included_modules = HashMap::<ResolvedPath, (Value, Object)>::new();
|
||||
let mut included_modules = HashMap::<ResolvedPath, (Value, ExportStar)>::new();
|
||||
|
||||
let mut path_and_module = match modules.get(&entry_point.clone()) {
|
||||
Some(path_and_module) => path_and_module.clone(),
|
||||
@@ -171,7 +171,7 @@ fn resolve_and_rewrite_import_patterns(path_and_module: &mut PathAndModule) -> V
|
||||
|
||||
fn link_import_patterns(
|
||||
module: &mut Module,
|
||||
included_modules: &HashMap<ResolvedPath, (Value, Object)>,
|
||||
included_modules: &HashMap<ResolvedPath, (Value, ExportStar)>,
|
||||
diagnostics: &mut Vec<Diagnostic>,
|
||||
) {
|
||||
for definition in &mut module.definitions {
|
||||
@@ -194,10 +194,15 @@ fn link_import_patterns(
|
||||
pointer: import_pattern.pointer,
|
||||
content: match import_pattern.kind {
|
||||
ImportKind::Default => DefinitionContent::Value(default.clone()),
|
||||
ImportKind::Star => DefinitionContent::Value(Value::Object(Box::new(namespace.clone()))),
|
||||
ImportKind::Name(name) => match namespace.try_resolve_key(&name) {
|
||||
ImportKind::Star => {
|
||||
// TODO: namespace.includes
|
||||
DefinitionContent::Value(Value::Object(Box::new(namespace.local.clone())))
|
||||
}
|
||||
ImportKind::Name(name) => match namespace.local.try_resolve_key(&name) {
|
||||
Some(value) => DefinitionContent::Value(value.clone()),
|
||||
None => {
|
||||
// TODO: namespace.includes
|
||||
|
||||
diagnostics.push(Diagnostic {
|
||||
level: DiagnosticLevel::Error,
|
||||
message: format!(
|
||||
|
||||
@@ -284,7 +284,7 @@ impl ModuleCompiler {
|
||||
});
|
||||
|
||||
if export {
|
||||
self.module.export_star.properties.push((
|
||||
self.module.export_star.local.properties.push((
|
||||
Value::String(ident.sym.to_string()),
|
||||
Value::Pointer(pointer),
|
||||
));
|
||||
@@ -312,7 +312,7 @@ impl ModuleCompiler {
|
||||
};
|
||||
|
||||
if export {
|
||||
self.module.export_star.properties.push((
|
||||
self.module.export_star.local.properties.push((
|
||||
Value::String(fn_name.clone()),
|
||||
Value::Pointer(pointer.clone()),
|
||||
));
|
||||
@@ -341,7 +341,7 @@ impl ModuleCompiler {
|
||||
};
|
||||
|
||||
if export {
|
||||
self.module.export_star.properties.push((
|
||||
self.module.export_star.local.properties.push((
|
||||
Value::String(ts_enum.id.sym.to_string()),
|
||||
Value::Pointer(pointer.clone()),
|
||||
));
|
||||
@@ -503,6 +503,7 @@ impl ModuleCompiler {
|
||||
self
|
||||
.module
|
||||
.export_star
|
||||
.local
|
||||
.properties
|
||||
.push((Value::String(export_name), Value::Pointer(defn)));
|
||||
}
|
||||
@@ -549,6 +550,7 @@ impl ModuleCompiler {
|
||||
self
|
||||
.module
|
||||
.export_star
|
||||
.local
|
||||
.properties
|
||||
.push((Value::String(namespace_name), Value::Pointer(defn)));
|
||||
}
|
||||
@@ -714,7 +716,7 @@ impl ModuleCompiler {
|
||||
};
|
||||
|
||||
if let Some(export_name) = export_name {
|
||||
self.module.export_star.properties.push((
|
||||
self.module.export_star.local.properties.push((
|
||||
Value::String(export_name),
|
||||
Value::Pointer(defn_name.clone()),
|
||||
));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::asm::{
|
||||
Array, Definition, DefinitionContent, FnLine, Instruction, Module, Object, Pointer, Value,
|
||||
Array, Definition, DefinitionContent, ExportStar, FnLine, Instruction, Module, Object, Pointer,
|
||||
Value,
|
||||
};
|
||||
|
||||
pub fn visit_pointers<Visitor>(module: &mut Module, visitor: Visitor)
|
||||
@@ -34,7 +35,7 @@ where
|
||||
|
||||
pub fn module(&mut self, module: &mut Module) {
|
||||
self.value(None, &mut module.export_default);
|
||||
self.object(None, &mut module.export_star);
|
||||
self.export_star(None, &mut module.export_star);
|
||||
|
||||
for definition in &mut module.definitions {
|
||||
self.definition(definition);
|
||||
@@ -70,6 +71,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn export_star(&mut self, owner: Option<&Pointer>, export_star: &mut ExportStar) {
|
||||
for p in &mut export_star.includes {
|
||||
self.pointer(owner, p);
|
||||
}
|
||||
|
||||
self.object(owner, &mut export_star.local);
|
||||
}
|
||||
|
||||
fn value(&mut self, owner: Option<&Pointer>, value: &mut Value) {
|
||||
use Value::*;
|
||||
|
||||
@@ -88,14 +97,18 @@ where
|
||||
self.value(owner, &mut class.static_);
|
||||
}
|
||||
Pointer(pointer) => {
|
||||
(self.visitor)(match owner {
|
||||
Some(owner) => PointerVisitation::Reference(owner, pointer),
|
||||
None => PointerVisitation::Export(pointer),
|
||||
});
|
||||
self.pointer(owner, pointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn pointer(&mut self, owner: Option<&Pointer>, pointer: &mut Pointer) {
|
||||
(self.visitor)(match owner {
|
||||
Some(owner) => PointerVisitation::Reference(owner, pointer),
|
||||
None => PointerVisitation::Export(pointer),
|
||||
});
|
||||
}
|
||||
|
||||
fn instruction(&mut self, owner: &Pointer, instruction: &mut Instruction) {
|
||||
use Instruction::*;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user