forked from AbleScript/ablescript
Satisfied most of THE ALLMIGHTY CLIPPY's requests.
This commit is contained in:
parent
a3c0e65f6b
commit
81f433e633
|
@ -50,19 +50,21 @@ pub enum AssignableKind {
|
||||||
Index { indices: Vec<Expr> },
|
Index { indices: Vec<Expr> },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct InvalidAssignable;
|
||||||
|
|
||||||
impl Assignable {
|
impl Assignable {
|
||||||
pub fn from_expr(expr: Expr) -> Result<Assignable, ()> {
|
pub fn from_expr(expr: Expr) -> Result<Assignable, InvalidAssignable> {
|
||||||
match expr.kind {
|
match expr.kind {
|
||||||
ExprKind::Variable(ident) => Ok(Assignable {
|
ExprKind::Variable(ident) => Ok(Assignable {
|
||||||
ident: Ident::new(ident, expr.span),
|
ident: Ident::new(ident, expr.span),
|
||||||
kind: AssignableKind::Variable,
|
kind: AssignableKind::Variable,
|
||||||
}),
|
}),
|
||||||
ExprKind::Index { expr, index } => Self::from_index(*expr, *index),
|
ExprKind::Index { expr, index } => Self::from_index(*expr, *index),
|
||||||
_ => Err(()),
|
_ => Err(InvalidAssignable),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_index(mut buf: Expr, index: Expr) -> Result<Assignable, ()> {
|
fn from_index(mut buf: Expr, index: Expr) -> Result<Assignable, InvalidAssignable> {
|
||||||
let mut indices = vec![index];
|
let mut indices = vec![index];
|
||||||
let ident = loop {
|
let ident = loop {
|
||||||
match buf.kind {
|
match buf.kind {
|
||||||
|
@ -71,7 +73,7 @@ impl Assignable {
|
||||||
indices.push(*index);
|
indices.push(*index);
|
||||||
buf = *expr;
|
buf = *expr;
|
||||||
}
|
}
|
||||||
_ => return Err(()),
|
_ => return Err(InvalidAssignable),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,15 @@ struct Scope {
|
||||||
variables: HashMap<String, Variable>,
|
variables: HashMap<String, Variable>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for ExecEnv {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
stack: vec![Default::default()],
|
||||||
|
read_buf: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for Scope {
|
impl Default for Scope {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -80,11 +89,7 @@ impl ExecEnv {
|
||||||
/// Create a new Scope with no predefined variable definitions or
|
/// Create a new Scope with no predefined variable definitions or
|
||||||
/// other information.
|
/// other information.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self::default()
|
||||||
// We always need at least one stackframe.
|
|
||||||
stack: vec![Default::default()],
|
|
||||||
read_buf: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new Scope with predefined variables
|
/// Create a new Scope with predefined variables
|
||||||
|
@ -190,7 +195,7 @@ impl ExecEnv {
|
||||||
.map(|x| x.borrow().clone())
|
.map(|x| x.borrow().clone())
|
||||||
.unwrap_or(Value::Nul)
|
.unwrap_or(Value::Nul)
|
||||||
}
|
}
|
||||||
Len(expr) => Value::Int(self.eval_expr(expr)?.len()),
|
Len(expr) => Value::Int(self.eval_expr(expr)?.length()),
|
||||||
|
|
||||||
// TODO: not too happy with constructing an artificial
|
// TODO: not too happy with constructing an artificial
|
||||||
// Ident here.
|
// Ident here.
|
||||||
|
@ -476,7 +481,7 @@ impl ExecEnv {
|
||||||
.chain(
|
.chain(
|
||||||
args[2 * n_alternations..]
|
args[2 * n_alternations..]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|r| Rc::clone(r))
|
.map(Rc::clone)
|
||||||
.take(extra_l),
|
.take(extra_l),
|
||||||
)
|
)
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -486,7 +491,7 @@ impl ExecEnv {
|
||||||
.chain(
|
.chain(
|
||||||
args[2 * n_alternations..]
|
args[2 * n_alternations..]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|r| Rc::clone(r))
|
.map(Rc::clone)
|
||||||
.take(extra_r),
|
.take(extra_r),
|
||||||
)
|
)
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use logos::{Lexer, Logos};
|
use logos::{Lexer, Logos};
|
||||||
|
|
||||||
use crate::variables::Abool;
|
|
||||||
|
|
||||||
#[derive(Logos, Debug, PartialEq, Clone)]
|
#[derive(Logos, Debug, PartialEq, Clone)]
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
// Symbols
|
// Symbols
|
||||||
|
@ -121,8 +119,8 @@ pub enum Token {
|
||||||
#[regex(r"-?[0-9]+", get_value)]
|
#[regex(r"-?[0-9]+", get_value)]
|
||||||
Integer(isize),
|
Integer(isize),
|
||||||
|
|
||||||
/// A C-complaint identifier
|
/// An identifier
|
||||||
#[regex(r"[a-zA-Z_][a-zA-Z_0-9]*", get_ident)]
|
#[regex(r"\p{XID_Start}\p{XID_Continue}*", get_ident)]
|
||||||
Identifier(String),
|
Identifier(String),
|
||||||
|
|
||||||
#[regex(r"owo .*")]
|
#[regex(r"owo .*")]
|
||||||
|
|
|
@ -104,7 +104,7 @@ impl std::fmt::Debug for BuiltinFunctio {
|
||||||
|
|
||||||
impl PartialEq for BuiltinFunctio {
|
impl PartialEq for BuiltinFunctio {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
Rc::ptr_eq(&self.function, &other.function) && self.arity == other.arity
|
self.fn_addr() == other.fn_addr() && self.arity == other.arity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ impl Value {
|
||||||
.into_abool(),
|
.into_abool(),
|
||||||
Functio::Able { params, body } => {
|
Functio::Able { params, body } => {
|
||||||
let str_to_isize = |x: String| -> isize {
|
let str_to_isize = |x: String| -> isize {
|
||||||
x.as_bytes().into_iter().map(|x| *x as isize).sum()
|
x.as_bytes().iter().map(|x| *x as isize).sum()
|
||||||
};
|
};
|
||||||
|
|
||||||
let params: isize = params.into_iter().map(str_to_isize).sum();
|
let params: isize = params.into_iter().map(str_to_isize).sum();
|
||||||
|
@ -482,8 +482,8 @@ impl Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a lenght of a value
|
/// Get a length of a value
|
||||||
pub fn len(&self) -> isize {
|
pub fn length(&self) -> isize {
|
||||||
match self {
|
match self {
|
||||||
Value::Nul => 0,
|
Value::Nul => 0,
|
||||||
Value::Str(s) => s.len() as _,
|
Value::Str(s) => s.len() as _,
|
||||||
|
@ -547,7 +547,7 @@ impl ops::Add for Value {
|
||||||
Value::Functio(_) => Value::Functio(self.into_functio()) + rhs,
|
Value::Functio(_) => Value::Functio(self.into_functio()) + rhs,
|
||||||
Value::Cart(_) => Value::Cart(self.into_cart()) + rhs,
|
Value::Cart(_) => Value::Cart(self.into_cart()) + rhs,
|
||||||
},
|
},
|
||||||
Value::Str(s) => Value::Str(format!("{}{}", s, rhs.to_string())),
|
Value::Str(s) => Value::Str(format!("{s}{rhs}")),
|
||||||
Value::Int(i) => Value::Int(i.wrapping_add(rhs.into_isize())),
|
Value::Int(i) => Value::Int(i.wrapping_add(rhs.into_isize())),
|
||||||
Value::Bool(b) => Value::Bool(b || rhs.into_bool()),
|
Value::Bool(b) => Value::Bool(b || rhs.into_bool()),
|
||||||
Value::Abool(_) => {
|
Value::Abool(_) => {
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub fn repl(ast_print: bool) {
|
||||||
rl.add_history_entry(readline);
|
rl.add_history_entry(readline);
|
||||||
|
|
||||||
let partial_data = match partial {
|
let partial_data = match partial {
|
||||||
Some(line) => line + &readline,
|
Some(line) => line + readline,
|
||||||
None => readline.to_owned(),
|
None => readline.to_owned(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue