Move constancy into Dynamic.
This commit is contained in:
@@ -3,12 +3,11 @@
|
||||
use crate::ast::{
|
||||
BinaryExpr, CustomExpr, Expr, FnCallExpr, Ident, IdentX, ReturnType, ScriptFnDef, Stmt,
|
||||
};
|
||||
use crate::dynamic::Union;
|
||||
use crate::dynamic::{AccessType, Union};
|
||||
use crate::engine::{KEYWORD_THIS, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT};
|
||||
use crate::module::NamespaceRef;
|
||||
use crate::optimize::optimize_into_ast;
|
||||
use crate::optimize::OptimizationLevel;
|
||||
use crate::scope::EntryType as ScopeEntryType;
|
||||
use crate::stdlib::{
|
||||
borrow::Cow,
|
||||
boxed::Box,
|
||||
@@ -49,7 +48,7 @@ struct ParseState<'e> {
|
||||
/// Interned strings.
|
||||
strings: HashMap<String, ImmutableString>,
|
||||
/// Encapsulates a local stack with variable names to simulate an actual runtime scope.
|
||||
stack: Vec<(ImmutableString, ScopeEntryType)>,
|
||||
stack: Vec<(ImmutableString, AccessType)>,
|
||||
/// Size of the local variables stack upon entry of the current block scope.
|
||||
entry_stack_len: usize,
|
||||
/// Tracks a list of external variables (variables that are not explicitly declared in the scope).
|
||||
@@ -1291,11 +1290,11 @@ fn make_assignment_stmt<'a>(
|
||||
},
|
||||
) = x.as_ref();
|
||||
match state.stack[(state.stack.len() - index.unwrap().get())].1 {
|
||||
ScopeEntryType::Normal => {
|
||||
AccessType::Normal => {
|
||||
Ok(Stmt::Assignment(Box::new((lhs, fn_name.into(), rhs)), pos))
|
||||
}
|
||||
// Constant values cannot be assigned to
|
||||
ScopeEntryType::Constant => {
|
||||
AccessType::Constant => {
|
||||
Err(PERR::AssignmentToConstant(name.to_string()).into_err(*name_pos))
|
||||
}
|
||||
}
|
||||
@@ -1318,11 +1317,11 @@ fn make_assignment_stmt<'a>(
|
||||
},
|
||||
) = x.as_ref();
|
||||
match state.stack[(state.stack.len() - index.unwrap().get())].1 {
|
||||
ScopeEntryType::Normal => {
|
||||
AccessType::Normal => {
|
||||
Ok(Stmt::Assignment(Box::new((lhs, fn_name.into(), rhs)), pos))
|
||||
}
|
||||
// Constant values cannot be assigned to
|
||||
ScopeEntryType::Constant => {
|
||||
AccessType::Constant => {
|
||||
Err(PERR::AssignmentToConstant(name.to_string()).into_err(*name_pos))
|
||||
}
|
||||
}
|
||||
@@ -1811,7 +1810,7 @@ fn parse_custom_syntax(
|
||||
// Variable searches stop at the first empty variable name.
|
||||
state.stack.resize(
|
||||
state.stack.len() + delta as usize,
|
||||
("".into(), ScopeEntryType::Normal),
|
||||
("".into(), AccessType::Normal),
|
||||
);
|
||||
}
|
||||
delta if delta < 0 && state.stack.len() <= delta.abs() as usize => state.stack.clear(),
|
||||
@@ -2110,7 +2109,7 @@ fn parse_for(
|
||||
|
||||
let loop_var = state.get_interned_string(name.clone());
|
||||
let prev_stack_len = state.stack.len();
|
||||
state.stack.push((loop_var, ScopeEntryType::Normal));
|
||||
state.stack.push((loop_var, AccessType::Normal));
|
||||
|
||||
settings.is_breakable = true;
|
||||
let body = parse_block(input, state, lib, settings.level_up())?;
|
||||
@@ -2125,7 +2124,7 @@ fn parse_let(
|
||||
input: &mut TokenStream,
|
||||
state: &mut ParseState,
|
||||
lib: &mut FunctionsLib,
|
||||
var_type: ScopeEntryType,
|
||||
var_type: AccessType,
|
||||
export: bool,
|
||||
mut settings: ParseSettings,
|
||||
) -> Result<Stmt, ParseError> {
|
||||
@@ -2156,16 +2155,16 @@ fn parse_let(
|
||||
|
||||
match var_type {
|
||||
// let name = expr
|
||||
ScopeEntryType::Normal => {
|
||||
AccessType::Normal => {
|
||||
let var_name = state.get_interned_string(name.clone());
|
||||
state.stack.push((var_name, ScopeEntryType::Normal));
|
||||
state.stack.push((var_name, AccessType::Normal));
|
||||
let var_def = Ident::new(name, pos);
|
||||
Ok(Stmt::Let(Box::new(var_def), init_expr, export, token_pos))
|
||||
}
|
||||
// const name = { expr:constant }
|
||||
ScopeEntryType::Constant => {
|
||||
AccessType::Constant => {
|
||||
let var_name = state.get_interned_string(name.clone());
|
||||
state.stack.push((var_name, ScopeEntryType::Constant));
|
||||
state.stack.push((var_name, AccessType::Constant));
|
||||
let var_def = Ident::new(name, pos);
|
||||
Ok(Stmt::Const(Box::new(var_def), init_expr, export, token_pos))
|
||||
}
|
||||
@@ -2232,13 +2231,13 @@ fn parse_export(
|
||||
match input.peek().unwrap() {
|
||||
(Token::Let, pos) => {
|
||||
let pos = *pos;
|
||||
let mut stmt = parse_let(input, state, lib, ScopeEntryType::Normal, true, settings)?;
|
||||
let mut stmt = parse_let(input, state, lib, AccessType::Normal, true, settings)?;
|
||||
stmt.set_position(pos);
|
||||
return Ok(stmt);
|
||||
}
|
||||
(Token::Const, pos) => {
|
||||
let pos = *pos;
|
||||
let mut stmt = parse_let(input, state, lib, ScopeEntryType::Constant, true, settings)?;
|
||||
let mut stmt = parse_let(input, state, lib, AccessType::Constant, true, settings)?;
|
||||
stmt.set_position(pos);
|
||||
return Ok(stmt);
|
||||
}
|
||||
@@ -2393,7 +2392,7 @@ fn parse_stmt(
|
||||
lib: &mut FunctionsLib,
|
||||
mut settings: ParseSettings,
|
||||
) -> Result<Option<Stmt>, ParseError> {
|
||||
use ScopeEntryType::{Constant, Normal};
|
||||
use AccessType::{Constant, Normal};
|
||||
|
||||
let (token, token_pos) = match input.peek().unwrap() {
|
||||
(Token::EOF, pos) => return Ok(Some(Stmt::Noop(*pos))),
|
||||
@@ -2637,7 +2636,7 @@ fn parse_fn(
|
||||
return Err(PERR::FnDuplicatedParam(name, s).into_err(pos));
|
||||
}
|
||||
let s = state.get_interned_string(s);
|
||||
state.stack.push((s.clone(), ScopeEntryType::Normal));
|
||||
state.stack.push((s.clone(), AccessType::Normal));
|
||||
params.push((s, pos))
|
||||
}
|
||||
(Token::LexError(err), pos) => return Err(err.into_err(pos)),
|
||||
@@ -2770,7 +2769,7 @@ fn parse_anon_fn(
|
||||
return Err(PERR::FnDuplicatedParam("".to_string(), s).into_err(pos));
|
||||
}
|
||||
let s = state.get_interned_string(s);
|
||||
state.stack.push((s.clone(), ScopeEntryType::Normal));
|
||||
state.stack.push((s.clone(), AccessType::Normal));
|
||||
params.push((s, pos))
|
||||
}
|
||||
(Token::LexError(err), pos) => return Err(err.into_err(pos)),
|
||||
@@ -3005,15 +3004,15 @@ impl Engine {
|
||||
pub fn map_dynamic_to_expr(value: Dynamic, pos: Position) -> Option<Expr> {
|
||||
match value.0 {
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
Union::Float(value) => Some(Expr::FloatConstant(value, pos)),
|
||||
Union::Float(value, _) => Some(Expr::FloatConstant(value, pos)),
|
||||
|
||||
Union::Unit(_) => Some(Expr::Unit(pos)),
|
||||
Union::Int(value) => Some(Expr::IntegerConstant(value, pos)),
|
||||
Union::Char(value) => Some(Expr::CharConstant(value, pos)),
|
||||
Union::Str(value) => Some(Expr::StringConstant(value, pos)),
|
||||
Union::Bool(value) => Some(Expr::BoolConstant(value, pos)),
|
||||
Union::Unit(_, _) => Some(Expr::Unit(pos)),
|
||||
Union::Int(value, _) => Some(Expr::IntegerConstant(value, pos)),
|
||||
Union::Char(value, _) => Some(Expr::CharConstant(value, pos)),
|
||||
Union::Str(value, _) => Some(Expr::StringConstant(value, pos)),
|
||||
Union::Bool(value, _) => Some(Expr::BoolConstant(value, pos)),
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Union::Array(array) => {
|
||||
Union::Array(array, _) => {
|
||||
let items: Vec<_> = array
|
||||
.into_iter()
|
||||
.map(|x| map_dynamic_to_expr(x, pos))
|
||||
@@ -3029,7 +3028,7 @@ pub fn map_dynamic_to_expr(value: Dynamic, pos: Position) -> Option<Expr> {
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Union::Map(map) => {
|
||||
Union::Map(map, _) => {
|
||||
let items: Vec<_> = map
|
||||
.into_iter()
|
||||
.map(|(k, v)| (IdentX::new(k, pos), map_dynamic_to_expr(v, pos)))
|
||||
|
Reference in New Issue
Block a user