Refactor interpolation
This commit is contained in:
parent
709ed5c6b5
commit
43866eb142
50
src/utils.rs
50
src/utils.rs
@ -1,4 +1,5 @@
|
|||||||
use crate::common::{Pos, Symbol, Whitespace};
|
use crate::common::{Pos, Symbol};
|
||||||
|
use crate::value::Value;
|
||||||
use crate::{Scope, Token, TokenKind};
|
use crate::{Scope, Token, TokenKind};
|
||||||
use std::iter::{Iterator, Peekable};
|
use std::iter::{Iterator, Peekable};
|
||||||
|
|
||||||
@ -38,33 +39,6 @@ pub(crate) fn devour_whitespace_or_comment<I: Iterator<Item = W>, W: IsWhitespac
|
|||||||
found_whitespace
|
found_whitespace
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "nightly", track_caller)]
|
|
||||||
pub(crate) fn deref_variable(name: &str, scope: &Scope) -> Vec<Token> {
|
|
||||||
let mut toks = scope
|
|
||||||
.vars
|
|
||||||
.get(name)
|
|
||||||
.expect("todo! expected variable to exist")
|
|
||||||
.iter()
|
|
||||||
.peekable();
|
|
||||||
let mut val = Vec::with_capacity(toks.len());
|
|
||||||
while let Some(tok) = toks.next() {
|
|
||||||
match tok.kind {
|
|
||||||
TokenKind::Variable(ref v) => val.extend(deref_variable(v, scope)),
|
|
||||||
TokenKind::Whitespace(_) => {
|
|
||||||
devour_whitespace(&mut toks);
|
|
||||||
if toks.peek().is_some() {
|
|
||||||
val.push(Token {
|
|
||||||
kind: TokenKind::Whitespace(Whitespace::Space),
|
|
||||||
pos: tok.pos,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => val.push(tok.clone()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn eat_interpolation<I: Iterator<Item = Token>>(
|
pub(crate) fn eat_interpolation<I: Iterator<Item = Token>>(
|
||||||
tokens: &mut I,
|
tokens: &mut I,
|
||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
@ -76,7 +50,10 @@ pub(crate) fn eat_interpolation<I: Iterator<Item = Token>>(
|
|||||||
TokenKind::Symbol(Symbol::OpenCurlyBrace) => {
|
TokenKind::Symbol(Symbol::OpenCurlyBrace) => {
|
||||||
todo!("invalid character in interpolation")
|
todo!("invalid character in interpolation")
|
||||||
}
|
}
|
||||||
TokenKind::Variable(ref v) => val.extend(deref_variable(v, scope)),
|
TokenKind::Variable(ref v) => val.push(Token {
|
||||||
|
pos: tok.pos,
|
||||||
|
kind: TokenKind::Ident(scope.vars.get(v).unwrap().to_string()),
|
||||||
|
}),
|
||||||
TokenKind::Interpolation => val.extend(eat_interpolation(tokens, scope)),
|
TokenKind::Interpolation => val.extend(eat_interpolation(tokens, scope)),
|
||||||
_ => val.push(tok),
|
_ => val.push(tok),
|
||||||
}
|
}
|
||||||
@ -87,17 +64,12 @@ pub(crate) fn eat_interpolation<I: Iterator<Item = Token>>(
|
|||||||
pub(crate) fn eat_variable_value<I: Iterator<Item = Token>>(
|
pub(crate) fn eat_variable_value<I: Iterator<Item = Token>>(
|
||||||
toks: &mut Peekable<I>,
|
toks: &mut Peekable<I>,
|
||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
) -> Result<Vec<Token>, (Pos, String)> {
|
) -> Result<Value, (Pos, String)> {
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
// todo!(line might not end with semicolon)
|
// todo!(line might not end with semicolon)
|
||||||
let iter1 = toks.take_while(|x| x.kind != TokenKind::Symbol(Symbol::SemiColon));
|
let iter1: Vec<Token> = toks
|
||||||
let mut iter2 = Vec::new();
|
.take_while(|x| x.kind != TokenKind::Symbol(Symbol::SemiColon))
|
||||||
for tok in iter1 {
|
.collect();
|
||||||
match tok.kind {
|
|
||||||
TokenKind::Variable(ref name) => iter2.extend(deref_variable(name, scope)),
|
|
||||||
_ => iter2.push(tok),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
Ok(iter2)
|
Ok(Value::from_tokens(&mut iter1.into_iter().peekable(), scope).unwrap())
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ use crate::builtin::GLOBAL_FUNCTIONS;
|
|||||||
use crate::color::Color;
|
use crate::color::Color;
|
||||||
use crate::common::{Keyword, Op, Scope, Symbol};
|
use crate::common::{Keyword, Op, Scope, Symbol};
|
||||||
use crate::units::Unit;
|
use crate::units::Unit;
|
||||||
use crate::utils::{deref_variable, devour_whitespace_or_comment, eat_interpolation};
|
use crate::utils::{devour_whitespace_or_comment, eat_interpolation};
|
||||||
use crate::{Token, TokenKind};
|
use crate::{Token, TokenKind};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
@ -275,7 +275,7 @@ impl Value {
|
|||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
toks.next();
|
toks.next();
|
||||||
let args = eat_call_args(toks);
|
let args = eat_call_args(toks, scope);
|
||||||
let func = match scope.functions.get(&s) {
|
let func = match scope.functions.get(&s) {
|
||||||
Some(f) => f,
|
Some(f) => f,
|
||||||
None => match GLOBAL_FUNCTIONS.get(&s) {
|
None => match GLOBAL_FUNCTIONS.get(&s) {
|
||||||
@ -308,9 +308,7 @@ impl Value {
|
|||||||
}
|
}
|
||||||
Some(Value::Ident(s, QuoteKind::Single))
|
Some(Value::Ident(s, QuoteKind::Single))
|
||||||
}
|
}
|
||||||
TokenKind::Variable(ref v) => {
|
TokenKind::Variable(ref v) => Some(scope.vars.get(v).unwrap().clone()),
|
||||||
Value::from_tokens(&mut deref_variable(v, scope).into_iter().peekable(), scope)
|
|
||||||
}
|
|
||||||
TokenKind::Interpolation => {
|
TokenKind::Interpolation => {
|
||||||
let mut s = eat_interpolation(toks, scope)
|
let mut s = eat_interpolation(toks, scope)
|
||||||
.iter()
|
.iter()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user