mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Use asm::Pointer during compilation
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::scope::scope_reg;
|
||||
use crate::{asm::Pointer, scope::scope_reg};
|
||||
|
||||
use super::scope::{MappedName, Scope, ScopeTrait};
|
||||
use super::scope::{MappedName, Scope};
|
||||
|
||||
pub struct CaptureFinder {
|
||||
outside_scope: Scope,
|
||||
@@ -222,7 +222,12 @@ impl CaptureFinder {
|
||||
Fn(fn_) => {
|
||||
let fn_name = fn_.ident.sym.to_string();
|
||||
|
||||
scope.set(fn_name.clone(), MappedName::Definition("".to_string()));
|
||||
scope.set(
|
||||
fn_name.clone(),
|
||||
MappedName::Definition(Pointer {
|
||||
name: "".to_string(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
Var(var_decl) => self.populate_block_scope_var_decl(scope, var_decl),
|
||||
TsInterface(_) => {}
|
||||
|
||||
@@ -7,11 +7,13 @@ use swc_common::{errors::Handler, FileName, SourceMap, Spanned};
|
||||
use swc_ecma_ast::EsVersion;
|
||||
use swc_ecma_parser::{Syntax, TsConfig};
|
||||
|
||||
use crate::asm::Pointer;
|
||||
|
||||
use super::diagnostic::{Diagnostic, DiagnosticLevel};
|
||||
use super::expression_compiler::{string_literal, CompiledExpression, ExpressionCompiler};
|
||||
use super::function_compiler::{FunctionCompiler, Functionish};
|
||||
use super::name_allocator::NameAllocator;
|
||||
use super::scope::{init_std_scope, MappedName, Scope, ScopeTrait};
|
||||
use super::scope::{init_std_scope, MappedName, Scope};
|
||||
use super::scope_analysis::ScopeAnalysis;
|
||||
|
||||
struct DiagnosticCollector {
|
||||
@@ -112,6 +114,28 @@ struct Compiler {
|
||||
}
|
||||
|
||||
impl Compiler {
|
||||
fn allocate_defn(&mut self, name: &str) -> Pointer {
|
||||
let allocated_name = self
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate(&name.to_string());
|
||||
|
||||
Pointer {
|
||||
name: allocated_name,
|
||||
}
|
||||
}
|
||||
|
||||
fn allocate_defn_numbered(&mut self, name: &str) -> Pointer {
|
||||
let allocated_name = self
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate_numbered(&name.to_string());
|
||||
|
||||
Pointer {
|
||||
name: allocated_name,
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_program(&mut self, program: &swc_ecma_ast::Program) {
|
||||
use swc_ecma_ast::Program::*;
|
||||
|
||||
@@ -137,7 +161,7 @@ impl Compiler {
|
||||
use swc_ecma_ast::ModuleItem;
|
||||
use swc_ecma_ast::Stmt;
|
||||
|
||||
let mut default_export_name = None;
|
||||
let mut default_export_pointer = None;
|
||||
|
||||
// Populate scope with top-level declarations
|
||||
for module_item in &module.body {
|
||||
@@ -169,22 +193,14 @@ impl Compiler {
|
||||
swc_ecma_ast::DefaultDecl::Fn(fn_) => {
|
||||
match &fn_.ident {
|
||||
Some(id) => {
|
||||
let allocated_name = self
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate(&id.sym.to_string());
|
||||
let allocated_name = self.allocate_defn(&id.sym.to_string());
|
||||
|
||||
default_export_name = Some(allocated_name.clone());
|
||||
default_export_pointer = Some(allocated_name.clone());
|
||||
|
||||
scope.set(id.sym.to_string(), MappedName::Definition(allocated_name));
|
||||
}
|
||||
None => {
|
||||
default_export_name = Some(
|
||||
self
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate_numbered(&"_anon".to_string()),
|
||||
);
|
||||
default_export_pointer = Some(self.allocate_defn_numbered("_anon"));
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -365,23 +381,13 @@ impl Compiler {
|
||||
Decl::Class(class) => {
|
||||
scope.set(
|
||||
class.ident.sym.to_string(),
|
||||
MappedName::Definition(
|
||||
self
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate(&class.ident.sym.to_string()),
|
||||
),
|
||||
MappedName::Definition(self.allocate_defn(&class.ident.sym.to_string())),
|
||||
);
|
||||
}
|
||||
Decl::Fn(fn_) => {
|
||||
scope.set(
|
||||
fn_.ident.sym.to_string(),
|
||||
MappedName::Definition(
|
||||
self
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate(&fn_.ident.sym.to_string()),
|
||||
),
|
||||
MappedName::Definition(self.allocate_defn(&fn_.ident.sym.to_string())),
|
||||
);
|
||||
}
|
||||
Decl::Var(var_decl) => {
|
||||
@@ -423,15 +429,15 @@ impl Compiler {
|
||||
}
|
||||
|
||||
// First compile default
|
||||
match default_export_name {
|
||||
Some(default_export_name) => {
|
||||
match default_export_pointer {
|
||||
Some(default_export_pointer) => {
|
||||
for module_item in &module.body {
|
||||
match module_item {
|
||||
ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultDecl(edd)) => self
|
||||
.compile_export_default_decl(
|
||||
edd,
|
||||
// FIXME: clone() shouldn't be necessary here (we want to move)
|
||||
default_export_name.clone(),
|
||||
default_export_pointer.name.clone(),
|
||||
&scope,
|
||||
),
|
||||
_ => {}
|
||||
@@ -625,7 +631,7 @@ impl Compiler {
|
||||
use swc_ecma_ast::Decl::*;
|
||||
|
||||
match decl {
|
||||
Class(class) => self.compile_class_decl(class, self.definition_allocator.clone(), scope),
|
||||
Class(class) => self.compile_class_decl(class, scope),
|
||||
Fn(fn_) => {
|
||||
let fn_name = fn_.ident.sym.to_string();
|
||||
|
||||
@@ -646,7 +652,6 @@ impl Compiler {
|
||||
defn,
|
||||
Some(fn_.ident.sym.to_string()),
|
||||
Functionish::Fn(fn_.function.clone()),
|
||||
self.definition_allocator.clone(),
|
||||
scope,
|
||||
)
|
||||
}
|
||||
@@ -705,7 +710,6 @@ impl Compiler {
|
||||
defn,
|
||||
Some(fn_name),
|
||||
Functionish::Fn(fn_.function.clone()),
|
||||
self.definition_allocator.clone(),
|
||||
scope,
|
||||
);
|
||||
}
|
||||
@@ -721,17 +725,16 @@ impl Compiler {
|
||||
|
||||
fn compile_fn(
|
||||
&mut self,
|
||||
defn_name: String,
|
||||
defn_pointer: Pointer,
|
||||
fn_name: Option<String>,
|
||||
functionish: Functionish,
|
||||
definition_allocator: Rc<RefCell<NameAllocator>>,
|
||||
parent_scope: &Scope,
|
||||
) {
|
||||
let (defn, mut diagnostics) = FunctionCompiler::compile(
|
||||
defn_name,
|
||||
defn_pointer,
|
||||
fn_name,
|
||||
functionish,
|
||||
definition_allocator,
|
||||
self.definition_allocator.clone(),
|
||||
parent_scope,
|
||||
);
|
||||
|
||||
@@ -739,12 +742,7 @@ impl Compiler {
|
||||
self.diagnostics.append(&mut diagnostics);
|
||||
}
|
||||
|
||||
fn compile_class_decl(
|
||||
&mut self,
|
||||
class_decl: &swc_ecma_ast::ClassDecl,
|
||||
definition_allocator: Rc<RefCell<NameAllocator>>,
|
||||
parent_scope: &Scope,
|
||||
) {
|
||||
fn compile_class_decl(&mut self, class_decl: &swc_ecma_ast::ClassDecl, parent_scope: &Scope) {
|
||||
let mut defn = Vec::<String>::new();
|
||||
|
||||
let class_name = class_decl.ident.sym.to_string();
|
||||
@@ -762,9 +760,9 @@ impl Compiler {
|
||||
}
|
||||
};
|
||||
|
||||
let mut constructor_defn_name: Option<String> = None;
|
||||
let mut constructor_defn_name: Option<Pointer> = None;
|
||||
|
||||
let mut member_initializers_fnc = FunctionCompiler::new(definition_allocator.clone());
|
||||
let mut member_initializers_fnc = FunctionCompiler::new(self.definition_allocator.clone());
|
||||
|
||||
for class_member in &class_decl.class.body {
|
||||
match class_member {
|
||||
@@ -829,15 +827,12 @@ impl Compiler {
|
||||
swc_ecma_ast::ClassMember::Constructor(constructor) => {
|
||||
has_constructor = true;
|
||||
|
||||
let ctor_defn_name = definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate(&format!("{}_constructor", class_name));
|
||||
let ctor_defn_name = self.allocate_defn(&format!("{}_constructor", class_name));
|
||||
|
||||
self.compile_fn(
|
||||
ctor_defn_name.clone(),
|
||||
None,
|
||||
Functionish::Constructor(member_initializers_assembly.clone(), constructor.clone()),
|
||||
definition_allocator.clone(),
|
||||
parent_scope,
|
||||
);
|
||||
|
||||
@@ -848,11 +843,9 @@ impl Compiler {
|
||||
}
|
||||
|
||||
if member_initializers_assembly.len() > 0 && !has_constructor {
|
||||
let ctor_defn_name = definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate(&format!("{}_constructor", class_name));
|
||||
let ctor_defn_name = self.allocate_defn(&format!("{}_constructor", class_name));
|
||||
|
||||
defn.push(format!("@{} = function() {{", &ctor_defn_name));
|
||||
defn.push(format!("{} = function() {{", ctor_defn_name));
|
||||
|
||||
for line in member_initializers_assembly {
|
||||
defn.push(line.clone());
|
||||
@@ -865,11 +858,11 @@ impl Compiler {
|
||||
}
|
||||
|
||||
defn.push(format!(
|
||||
"@{} = class({}, {{",
|
||||
"{} = class({}, {{",
|
||||
defn_name,
|
||||
match constructor_defn_name {
|
||||
None => "void".to_string(),
|
||||
Some(d) => format!("@{}", d),
|
||||
Some(d) => format!("{}", d),
|
||||
},
|
||||
));
|
||||
|
||||
@@ -892,20 +885,17 @@ impl Compiler {
|
||||
}
|
||||
};
|
||||
|
||||
let method_defn_name = definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate(&format!("{}_{}", defn_name, name));
|
||||
let method_defn_name = self.allocate_defn(&format!("{}_{}", defn_name.name, name));
|
||||
|
||||
self.compile_fn(
|
||||
method_defn_name.clone(),
|
||||
None,
|
||||
Functionish::Fn(method.function.clone()),
|
||||
definition_allocator.clone(),
|
||||
parent_scope,
|
||||
);
|
||||
|
||||
defn.push(format!(
|
||||
" {}: @{},",
|
||||
" {}: {},",
|
||||
string_literal(&name),
|
||||
method_defn_name,
|
||||
));
|
||||
|
||||
@@ -2,12 +2,12 @@ use queues::*;
|
||||
|
||||
use swc_common::Spanned;
|
||||
|
||||
use crate::asm::Register;
|
||||
use crate::asm::{Pointer, Register};
|
||||
|
||||
use super::capture_finder::CaptureFinder;
|
||||
use super::diagnostic::{Diagnostic, DiagnosticLevel};
|
||||
use super::function_compiler::{FunctionCompiler, Functionish, QueuedFunction};
|
||||
use super::scope::{init_std_scope, MappedName, Scope, ScopeTrait};
|
||||
use super::scope::{init_std_scope, MappedName, Scope};
|
||||
|
||||
pub struct CompiledExpression {
|
||||
/** It is usually better to access this via functionCompiler.use_ */
|
||||
@@ -1058,13 +1058,9 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
.clone()
|
||||
.and_then(|ident| Some(ident.sym.to_string()));
|
||||
|
||||
let definition_name = match &fn_name {
|
||||
Some(name) => self.fnc.definition_allocator.borrow_mut().allocate(&name),
|
||||
None => self
|
||||
.fnc
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate_numbered(&"_anon".to_string()),
|
||||
let definition_pointer = match &fn_name {
|
||||
Some(name) => self.fnc.allocate_defn(&name),
|
||||
None => self.fnc.allocate_defn_numbered(&"_anon".to_string()),
|
||||
};
|
||||
|
||||
let mut cf = CaptureFinder::new(self.scope.clone());
|
||||
@@ -1074,7 +1070,7 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
.fnc
|
||||
.queue
|
||||
.add(QueuedFunction {
|
||||
definition_name: definition_name.clone(),
|
||||
definition_pointer: definition_pointer.clone(),
|
||||
fn_name: fn_name.clone(),
|
||||
capture_params: cf.ordered_names.clone(),
|
||||
functionish: Functionish::Fn(fn_.function.clone()),
|
||||
@@ -1082,13 +1078,13 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
.expect("Failed to queue function");
|
||||
|
||||
if cf.ordered_names.len() == 0 {
|
||||
return self.inline(format!("@{}", definition_name), target_register);
|
||||
return self.inline(format!("{}", definition_pointer), target_register);
|
||||
}
|
||||
|
||||
return self.capturing_fn_ref(
|
||||
fn_name,
|
||||
fn_.ident.span(),
|
||||
&definition_name,
|
||||
&definition_pointer,
|
||||
&cf.ordered_names,
|
||||
target_register,
|
||||
);
|
||||
@@ -1099,11 +1095,7 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
arrow_expr: &swc_ecma_ast::ArrowExpr,
|
||||
target_register: Option<Register>,
|
||||
) -> CompiledExpression {
|
||||
let definition_name = self
|
||||
.fnc
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate_numbered(&"_anon".to_string());
|
||||
let definition_pointer = self.fnc.allocate_defn_numbered(&"_anon".to_string());
|
||||
|
||||
let mut cf = CaptureFinder::new(self.scope.clone());
|
||||
cf.arrow_expr(&init_std_scope(), arrow_expr);
|
||||
@@ -1112,7 +1104,7 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
.fnc
|
||||
.queue
|
||||
.add(QueuedFunction {
|
||||
definition_name: definition_name.clone(),
|
||||
definition_pointer: definition_pointer.clone(),
|
||||
fn_name: None,
|
||||
capture_params: cf.ordered_names.clone(),
|
||||
functionish: Functionish::Arrow(arrow_expr.clone()),
|
||||
@@ -1120,13 +1112,13 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
.expect("Failed to queue function");
|
||||
|
||||
if cf.ordered_names.len() == 0 {
|
||||
return self.inline(format!("@{}", definition_name), target_register);
|
||||
return self.inline(format!("{}", definition_pointer), target_register);
|
||||
}
|
||||
|
||||
return self.capturing_fn_ref(
|
||||
None,
|
||||
arrow_expr.span(),
|
||||
&definition_name,
|
||||
&definition_pointer,
|
||||
&cf.ordered_names,
|
||||
target_register,
|
||||
);
|
||||
@@ -1136,7 +1128,7 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
&mut self,
|
||||
fn_name: Option<String>,
|
||||
span: swc_common::Span,
|
||||
definition_name: &String,
|
||||
definition_pointer: &Pointer,
|
||||
captures: &Vec<String>,
|
||||
target_register: Option<Register>,
|
||||
) -> CompiledExpression {
|
||||
@@ -1157,7 +1149,7 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
Some(tr) => tr.clone(),
|
||||
};
|
||||
|
||||
let mut bind_instr = format!(" bind @{} [", definition_name);
|
||||
let mut bind_instr = format!(" bind {} [", definition_pointer);
|
||||
|
||||
for i in 0..captures.len() {
|
||||
let captured_name = &captures[i];
|
||||
@@ -1208,7 +1200,7 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
Functionish::Arrow(arrow) => arrow.span,
|
||||
Functionish::Constructor(_, constructor) => constructor.span,
|
||||
},
|
||||
&qfn.definition_name,
|
||||
&qfn.definition_pointer,
|
||||
&qfn.capture_params,
|
||||
None,
|
||||
);
|
||||
@@ -1360,7 +1352,7 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
|
||||
return match mapped {
|
||||
MappedName::Register(reg) => self.inline(format!("{}", reg), target_register),
|
||||
MappedName::Definition(def) => self.inline("@".to_string() + &def, target_register),
|
||||
MappedName::Definition(def) => self.inline(format!("{}", def), target_register),
|
||||
MappedName::QueuedFunction(qfn) => self.capturing_fn_ref(
|
||||
qfn.fn_name.clone(),
|
||||
match &qfn.functionish {
|
||||
@@ -1368,7 +1360,7 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
Functionish::Arrow(arrow) => arrow.span,
|
||||
Functionish::Constructor(_, constructor) => constructor.span,
|
||||
},
|
||||
&qfn.definition_name,
|
||||
&qfn.definition_pointer,
|
||||
&qfn.capture_params,
|
||||
target_register,
|
||||
),
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::rc::Rc;
|
||||
|
||||
use swc_common::Spanned;
|
||||
|
||||
use crate::asm::Register;
|
||||
use crate::asm::{Pointer, Register};
|
||||
use crate::scope::scope_reg;
|
||||
|
||||
use super::capture_finder::CaptureFinder;
|
||||
@@ -13,7 +13,7 @@ use super::diagnostic::{Diagnostic, DiagnosticLevel};
|
||||
use super::expression_compiler::CompiledExpression;
|
||||
use super::expression_compiler::ExpressionCompiler;
|
||||
use super::name_allocator::NameAllocator;
|
||||
use super::scope::{init_std_scope, MappedName, Scope, ScopeTrait};
|
||||
use super::scope::{init_std_scope, MappedName, Scope};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Functionish {
|
||||
@@ -24,7 +24,7 @@ pub enum Functionish {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct QueuedFunction {
|
||||
pub definition_name: String,
|
||||
pub definition_pointer: Pointer,
|
||||
pub fn_name: Option<String>,
|
||||
pub capture_params: Vec<String>,
|
||||
pub functionish: Functionish,
|
||||
@@ -71,6 +71,28 @@ impl FunctionCompiler {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn allocate_defn(&mut self, name: &str) -> Pointer {
|
||||
let allocated_name = self
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate(&name.to_string());
|
||||
|
||||
Pointer {
|
||||
name: allocated_name,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allocate_defn_numbered(&mut self, name: &str) -> Pointer {
|
||||
let allocated_name = self
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate_numbered(&name.to_string());
|
||||
|
||||
Pointer {
|
||||
name: allocated_name,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allocate_tmp(&mut self) -> Register {
|
||||
return Register::Named(self.reg_allocator.allocate(&"_tmp".to_string()));
|
||||
}
|
||||
@@ -99,7 +121,7 @@ impl FunctionCompiler {
|
||||
}
|
||||
|
||||
pub fn compile(
|
||||
definition_name: String,
|
||||
definition_pointer: Pointer,
|
||||
fn_name: Option<String>,
|
||||
functionish: Functionish,
|
||||
definition_allocator: Rc<RefCell<NameAllocator>>,
|
||||
@@ -110,7 +132,7 @@ impl FunctionCompiler {
|
||||
self_
|
||||
.queue
|
||||
.add(QueuedFunction {
|
||||
definition_name: definition_name.clone(),
|
||||
definition_pointer: definition_pointer.clone(),
|
||||
fn_name,
|
||||
capture_params: Vec::new(),
|
||||
functionish,
|
||||
@@ -126,7 +148,7 @@ impl FunctionCompiler {
|
||||
loop {
|
||||
match self.queue.remove() {
|
||||
Ok(qfn) => self.compile_functionish(
|
||||
qfn.definition_name,
|
||||
qfn.definition_pointer,
|
||||
qfn.fn_name,
|
||||
qfn.capture_params,
|
||||
&qfn.functionish,
|
||||
@@ -141,7 +163,7 @@ impl FunctionCompiler {
|
||||
|
||||
fn compile_functionish(
|
||||
&mut self,
|
||||
definition_name: String,
|
||||
definition_pointer: Pointer,
|
||||
fn_name: Option<String>,
|
||||
capture_params: Vec<String>,
|
||||
functionish: &Functionish,
|
||||
@@ -154,13 +176,11 @@ impl FunctionCompiler {
|
||||
|
||||
match fn_name {
|
||||
// TODO: Capture propagation when using this name recursively
|
||||
Some(fn_name_) => scope.set(fn_name_, MappedName::Definition(definition_name.clone())),
|
||||
Some(fn_name_) => scope.set(fn_name_, MappedName::Definition(definition_pointer.clone())),
|
||||
None => {}
|
||||
}
|
||||
|
||||
let mut heading = "@".to_string();
|
||||
heading += &definition_name;
|
||||
heading += " = function(";
|
||||
let mut heading = format!("{} = function(", definition_pointer);
|
||||
|
||||
let mut param_count = 0;
|
||||
|
||||
@@ -640,10 +660,10 @@ impl FunctionCompiler {
|
||||
|
||||
let fn_name = fn_.ident.sym.to_string();
|
||||
|
||||
let definition_name = self.definition_allocator.borrow_mut().allocate(&fn_name);
|
||||
let definition_pointer = self.allocate_defn(&fn_name);
|
||||
|
||||
let qf = QueuedFunction {
|
||||
definition_name: definition_name,
|
||||
definition_pointer,
|
||||
fn_name: Some(fn_name.clone()),
|
||||
capture_params: full_captures,
|
||||
functionish: Functionish::Fn(fn_.function.clone()),
|
||||
@@ -677,7 +697,7 @@ impl FunctionCompiler {
|
||||
self.statement(stmt, false, &block_scope);
|
||||
}
|
||||
|
||||
for mapping in block_scope.borrow().name_map.values() {
|
||||
for mapping in block_scope.rc.borrow().name_map.values() {
|
||||
match mapping {
|
||||
MappedName::Register(reg) => {
|
||||
self.release_reg(reg);
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::asm;
|
||||
use crate::asm::{Pointer, Register};
|
||||
|
||||
use super::function_compiler::QueuedFunction;
|
||||
|
||||
@@ -23,8 +23,8 @@ impl std::fmt::Display for Builtin {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum MappedName {
|
||||
Register(asm::Register),
|
||||
Definition(String),
|
||||
Register(Register),
|
||||
Definition(Pointer),
|
||||
QueuedFunction(QueuedFunction),
|
||||
Builtin(Builtin),
|
||||
}
|
||||
@@ -34,35 +34,31 @@ pub fn scope_reg(name: String) -> MappedName {
|
||||
std::panic!("Invalid register name (use Register enum)");
|
||||
}
|
||||
|
||||
MappedName::Register(asm::Register::Named(name))
|
||||
MappedName::Register(Register::Named(name))
|
||||
}
|
||||
|
||||
pub struct ScopeData {
|
||||
pub name_map: HashMap<String, MappedName>,
|
||||
pub parent: Option<Rc<RefCell<ScopeData>>>,
|
||||
pub parent: Option<Scope>,
|
||||
}
|
||||
|
||||
pub type Scope = Rc<RefCell<ScopeData>>;
|
||||
|
||||
pub trait ScopeTrait {
|
||||
fn get(&self, name: &String) -> Option<MappedName>;
|
||||
fn get_defn(&self, name: &String) -> Option<String>;
|
||||
fn set(&self, name: String, mapped_name: MappedName);
|
||||
fn nest(&self) -> Rc<RefCell<ScopeData>>;
|
||||
#[derive(Clone)]
|
||||
pub struct Scope {
|
||||
pub rc: Rc<RefCell<ScopeData>>,
|
||||
}
|
||||
|
||||
impl ScopeTrait for Scope {
|
||||
fn get(&self, name: &String) -> Option<MappedName> {
|
||||
match self.borrow().name_map.get(name) {
|
||||
impl Scope {
|
||||
pub fn get(&self, name: &String) -> Option<MappedName> {
|
||||
match self.rc.borrow().name_map.get(name) {
|
||||
Some(mapped_name) => Some(mapped_name.clone()),
|
||||
None => match &self.borrow().parent {
|
||||
None => match &self.rc.borrow().parent {
|
||||
Some(parent) => parent.get(name),
|
||||
None => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn get_defn(&self, name: &String) -> Option<String> {
|
||||
pub fn get_defn(&self, name: &String) -> Option<Pointer> {
|
||||
let get_result = self.get(name);
|
||||
|
||||
return match get_result {
|
||||
@@ -71,36 +67,42 @@ impl ScopeTrait for Scope {
|
||||
};
|
||||
}
|
||||
|
||||
fn set(&self, name: String, mapped_name: MappedName) {
|
||||
let old_mapping = self.borrow_mut().name_map.insert(name, mapped_name);
|
||||
pub fn set(&self, name: String, mapped_name: MappedName) {
|
||||
let old_mapping = self.rc.borrow_mut().name_map.insert(name, mapped_name);
|
||||
|
||||
if old_mapping.is_some() {
|
||||
std::panic!("Scope overwrite occurred (not implemented: being permissive about this)");
|
||||
}
|
||||
}
|
||||
|
||||
fn nest(&self) -> Rc<RefCell<ScopeData>> {
|
||||
return Rc::new(RefCell::new(ScopeData {
|
||||
name_map: Default::default(),
|
||||
parent: Some(self.clone()),
|
||||
}));
|
||||
pub fn nest(&self) -> Scope {
|
||||
return Scope {
|
||||
rc: Rc::new(RefCell::new(ScopeData {
|
||||
name_map: Default::default(),
|
||||
parent: Some(self.clone()),
|
||||
})),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn _init_scope() -> Scope {
|
||||
return Rc::new(RefCell::new(ScopeData {
|
||||
name_map: Default::default(),
|
||||
parent: None,
|
||||
}));
|
||||
return Scope {
|
||||
rc: Rc::new(RefCell::new(ScopeData {
|
||||
name_map: Default::default(),
|
||||
parent: None,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn init_std_scope() -> Scope {
|
||||
return Rc::new(RefCell::new(ScopeData {
|
||||
name_map: HashMap::from([
|
||||
("Math".to_string(), MappedName::Builtin(Builtin::Math)),
|
||||
("Debug".to_string(), MappedName::Builtin(Builtin::Debug)),
|
||||
]),
|
||||
parent: None,
|
||||
}))
|
||||
.nest();
|
||||
Scope {
|
||||
rc: Rc::new(RefCell::new(ScopeData {
|
||||
name_map: HashMap::from([
|
||||
("Math".to_string(), MappedName::Builtin(Builtin::Math)),
|
||||
("Debug".to_string(), MappedName::Builtin(Builtin::Debug)),
|
||||
]),
|
||||
parent: None,
|
||||
})),
|
||||
}
|
||||
.nest()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user