mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
DEV: Reserved word enforcement for bindings.
This commit is contained in:
parent
506036d888
commit
f6a6a3ac32
@ -14,8 +14,8 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::ast::Position;
|
||||
use super::Value;
|
||||
use crate::ast::Position;
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub struct Stack {
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
use std::path::Path;
|
||||
|
||||
use crate::ast::{Token, BinaryExprType, Expression, FormatArgs, Position, Statement, Value};
|
||||
use crate::ast::{BinaryExprType, Expression, FormatArgs, Position, Statement, Token, Value};
|
||||
use crate::ast::{FuncOpDef, TemplatePart};
|
||||
use crate::build::format::{ExpressionTemplate, SimpleTemplate, TemplateParser};
|
||||
use crate::build::opcode::Primitive;
|
||||
@ -212,9 +212,7 @@ impl AST {
|
||||
Value::Int(sym) => {
|
||||
ops.push(Op::Val(Primitive::Int(sym.val)), sym.pos);
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
ops.push(Op::Index, copy_def.pos.clone());
|
||||
Self::translate_copy(ops, copy_def.fields, copy_def.pos, root);
|
||||
@ -234,9 +232,7 @@ impl AST {
|
||||
Value::Int(sym) => {
|
||||
ops.push(Op::Val(Primitive::Int(sym.val)), sym.pos);
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
ops.push(Op::FCall, func_pos);
|
||||
return;
|
||||
@ -529,7 +525,12 @@ impl AST {
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_copy(mut ops: &mut PositionMap, flds: Vec<(Token, Expression)>, pos: Position, root: &Path) {
|
||||
fn translate_copy(
|
||||
mut ops: &mut PositionMap,
|
||||
flds: Vec<(Token, Expression)>,
|
||||
pos: Position,
|
||||
root: &Path,
|
||||
) {
|
||||
ops.push(Op::PushSelf, pos.clone());
|
||||
ops.push(Op::InitTuple, pos.clone());
|
||||
for (t, e) in flds {
|
||||
|
@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
use std::cell::RefCell;
|
||||
use std::collections::BTreeSet;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::ast::Position;
|
||||
@ -28,6 +29,17 @@ use super::Value::{C, F, M, P, S, T};
|
||||
use super::{Error, Op, Primitive, Value};
|
||||
use super::{Func, Module};
|
||||
|
||||
fn construct_reserved_word_set() -> BTreeSet<&'static str> {
|
||||
let mut words = BTreeSet::new();
|
||||
for word in vec![
|
||||
"let", "module", "func", "out", "assert", "self", "import", "include", "as", "map",
|
||||
"filter", "convert", "fail", "NULL", "in", "is", "TRACE",
|
||||
] {
|
||||
words.insert(word);
|
||||
}
|
||||
words
|
||||
}
|
||||
|
||||
pub struct VM<O, E>
|
||||
where
|
||||
O: std::io::Write,
|
||||
@ -40,6 +52,7 @@ where
|
||||
pub env: Rc<RefCell<Environment<O, E>>>,
|
||||
pub last: Option<(Rc<Value>, Position)>,
|
||||
self_stack: Vec<(Rc<Value>, Position)>,
|
||||
reserved_words: BTreeSet<&'static str>,
|
||||
}
|
||||
|
||||
impl<'a, O, E> VM<O, E>
|
||||
@ -60,6 +73,7 @@ where
|
||||
env: env,
|
||||
last: None,
|
||||
self_stack: Vec::new(),
|
||||
reserved_words: construct_reserved_word_set(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,6 +86,7 @@ where
|
||||
env: self.env.clone(),
|
||||
last: self.last,
|
||||
self_stack: self.self_stack,
|
||||
reserved_words: self.reserved_words,
|
||||
}
|
||||
}
|
||||
|
||||
@ -389,7 +404,7 @@ where
|
||||
// TODO(jwall): This should do a better error if there is
|
||||
// nothing on the stack.
|
||||
let (val, pos) = stack.pop().unwrap();
|
||||
vm.binding_push(nm.clone(), val, false, &pos)?;
|
||||
vm.binding_push(nm.clone(), val, false, &pos, &pos)?;
|
||||
}
|
||||
// proceed to the function body
|
||||
vm.run()?;
|
||||
@ -597,9 +612,10 @@ where
|
||||
// pop val off stack.
|
||||
let (val, val_pos) = self.pop()?;
|
||||
// pop name off stack.
|
||||
let (name, _) = self.pop()?;
|
||||
let (name, name_pos) = self.pop()?;
|
||||
// TODO(jwall): We need to restrict against our reserved word list.
|
||||
if let &S(ref name) = name.as_ref() {
|
||||
self.binding_push(name.clone(), val, strict, &val_pos)?;
|
||||
self.binding_push(name.clone(), val, strict, &val_pos, &name_pos)?;
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
@ -785,7 +801,14 @@ where
|
||||
val: Rc<Value>,
|
||||
strict: bool,
|
||||
pos: &Position,
|
||||
name_pos: &Position,
|
||||
) -> Result<(), Error> {
|
||||
if self.reserved_words.contains(name.as_str()) {
|
||||
return Err(dbg!(Error::new(
|
||||
format!("{} is a reserved word.", name),
|
||||
name_pos.clone(),
|
||||
)));
|
||||
}
|
||||
if self.symbols.is_bound(&name) && strict {
|
||||
return Err(dbg!(Error::new(
|
||||
format!("Binding {} already exists", name),
|
||||
@ -813,7 +836,6 @@ where
|
||||
match self.symbols.get(name) {
|
||||
Some((ref v, ref pos)) => Ok((v.clone(), pos.clone())),
|
||||
None => {
|
||||
// TODO(jwall): Look in the last item?
|
||||
return Err(dbg!(Error::new(
|
||||
format!("No such binding {}", name),
|
||||
pos.clone()
|
||||
|
Loading…
x
Reference in New Issue
Block a user