Clean
This commit is contained in:
parent
8064118490
commit
a3877817dd
|
|
@ -75,7 +75,7 @@ pub fn for_(out: &mut String, f: &For, value: &dyn Value, arena: &AstArena) {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
while let Some(value) = value.for_(idx) {
|
while let Some(value) = value.index(idx) {
|
||||||
let nodes = arena.deref_many(&f.body);
|
let nodes = arena.deref_many(&f.body);
|
||||||
execute_(out, nodes, value, arena);
|
execute_(out, nodes, value, arena);
|
||||||
idx += 1;
|
idx += 1;
|
||||||
|
|
@ -100,7 +100,7 @@ pub fn if_(out: &mut String, f: &If, value: &dyn Value, arena: &AstArena) {
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
if value.if_() {
|
if value.is_truthy() {
|
||||||
let nodes = arena.deref_many(&f.then);
|
let nodes = arena.deref_many(&f.then);
|
||||||
execute_(out, nodes, value, arena);
|
execute_(out, nodes, value, arena);
|
||||||
} else if let Some(else_) = f.else_.as_ref() {
|
} else if let Some(else_) = f.else_.as_ref() {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,2 @@
|
||||||
//! NOTE: Anything marked pub within this module or its children should not be
|
|
||||||
//! considered stable when it comes to semver. However, they are exposed for
|
|
||||||
//! advanced use cases.
|
|
||||||
|
|
||||||
pub mod execute;
|
|
||||||
pub mod parse;
|
pub mod parse;
|
||||||
mod parse_backup;
|
pub mod vm;
|
||||||
pub(crate) mod vm;
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,3 @@
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
pub use super::parse_backup::*;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum AstNodeKind {
|
pub enum AstNodeKind {
|
||||||
If(If),
|
If(If),
|
||||||
|
|
@ -56,10 +52,12 @@ struct ParseResult<'a, T>(
|
||||||
T, // output
|
T, // output
|
||||||
);
|
);
|
||||||
impl<'a, T> ParseResult<'a, T> {
|
impl<'a, T> ParseResult<'a, T> {
|
||||||
|
#[allow(dead_code)]
|
||||||
fn remaining(&self) -> &'a str {
|
fn remaining(&self) -> &'a str {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn output(&self) -> &T {
|
fn output(&self) -> &T {
|
||||||
&self.1
|
&self.1
|
||||||
}
|
}
|
||||||
|
|
@ -472,7 +470,7 @@ fn parse_many_until(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if remaining == "" {
|
if remaining.is_empty() {
|
||||||
return ParseResult("", None);
|
return ParseResult("", None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ pub(crate) mod ops {
|
||||||
|
|
||||||
pub(crate) fn lower_ast(ast: &[AstNodeKind]) -> Ops {
|
pub(crate) fn lower_ast(ast: &[AstNodeKind]) -> Ops {
|
||||||
let mut ops = Ops::new();
|
let mut ops = Ops::new();
|
||||||
lower_many(&mut ops, &ast);
|
lower_many(&mut ops, ast);
|
||||||
ops.emit(Op::Exit);
|
ops.emit(Op::Exit);
|
||||||
|
|
||||||
ops
|
ops
|
||||||
|
|
@ -162,8 +162,8 @@ pub(crate) mod ops {
|
||||||
macro_rules! go {
|
macro_rules! go {
|
||||||
($src:expr, $expected:expr) => {
|
($src:expr, $expected:expr) => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
crate::internal::vm::ops::lower_ast(
|
$crate::internal::vm::ops::lower_ast(
|
||||||
&crate::internal::parse::parse($src)
|
&$crate::internal::parse::parse($src)
|
||||||
),
|
),
|
||||||
Ops($expected),
|
Ops($expected),
|
||||||
)
|
)
|
||||||
|
|
@ -342,7 +342,7 @@ impl<'a> VmState<'a> {
|
||||||
self.stack_values.pop().expect("stack_values is empty");
|
self.stack_values.pop().expect("stack_values is empty");
|
||||||
},
|
},
|
||||||
Op::ValueLookup(field) => {
|
Op::ValueLookup(field) => {
|
||||||
let new_value = self.reg_value.lookup(&field);
|
let new_value = self.reg_value.lookup(field);
|
||||||
match new_value {
|
match new_value {
|
||||||
Some(v) => {
|
Some(v) => {
|
||||||
self.reg_value = v;
|
self.reg_value = v;
|
||||||
|
|
@ -356,7 +356,7 @@ impl<'a> VmState<'a> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Op::ValueIndex => {
|
Op::ValueIndex => {
|
||||||
let value = self.reg_value.for_(self.reg_counter);
|
let value = self.reg_value.index(self.reg_counter);
|
||||||
if let Some(value) = value {
|
if let Some(value) = value {
|
||||||
self.reg_value = value;
|
self.reg_value = value;
|
||||||
self.reg_cond = true;
|
self.reg_cond = true;
|
||||||
|
|
@ -368,7 +368,7 @@ impl<'a> VmState<'a> {
|
||||||
self.reg_value.print(&mut self.output);
|
self.reg_value.print(&mut self.output);
|
||||||
},
|
},
|
||||||
Op::ValueTruthy => {
|
Op::ValueTruthy => {
|
||||||
self.reg_cond = self.reg_value.if_();
|
self.reg_cond = self.reg_value.is_truthy();
|
||||||
},
|
},
|
||||||
Op::ValueHas => {
|
Op::ValueHas => {
|
||||||
if let Some(value) = self.reg_value.has() {
|
if let Some(value) = self.reg_value.has() {
|
||||||
|
|
|
||||||
98
src/lib.rs
98
src/lib.rs
|
|
@ -3,8 +3,7 @@ use core::fmt::Write;
|
||||||
pub mod internal;
|
pub mod internal;
|
||||||
|
|
||||||
use internal::{
|
use internal::{
|
||||||
execute::execute,
|
parse::parse,
|
||||||
parse::{parse, Ast},
|
|
||||||
vm::{
|
vm::{
|
||||||
ops::{lower_ast, Ops},
|
ops::{lower_ast, Ops},
|
||||||
VmState,
|
VmState,
|
||||||
|
|
@ -15,8 +14,8 @@ pub trait Value: core::fmt::Debug {
|
||||||
fn print(&self, out: &mut String);
|
fn print(&self, out: &mut String);
|
||||||
fn lookup(&self, name: &str) -> Option<&dyn Value>;
|
fn lookup(&self, name: &str) -> Option<&dyn Value>;
|
||||||
fn has(&self) -> Option<&dyn Value>;
|
fn has(&self) -> Option<&dyn Value>;
|
||||||
fn if_(&self) -> bool;
|
fn is_truthy(&self) -> bool;
|
||||||
fn for_(&self, index: usize) -> Option<&dyn Value>;
|
fn index(&self, index: usize) -> Option<&dyn Value>;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! value_for_int {
|
macro_rules! value_for_int {
|
||||||
|
|
@ -31,18 +30,18 @@ macro_rules! value_for_int {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has(&self) -> Option<&dyn Value> {
|
fn has(&self) -> Option<&dyn Value> {
|
||||||
if self.if_() {
|
if self.is_truthy() {
|
||||||
Some(self)
|
Some(self)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn if_(&self) -> bool {
|
fn is_truthy(&self) -> bool {
|
||||||
*self != 0
|
*self != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_(&self, _: usize) -> Option<&dyn Value> {
|
fn index(&self, _: usize) -> Option<&dyn Value> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -66,23 +65,23 @@ where
|
||||||
T: Value + ?Sized,
|
T: Value + ?Sized,
|
||||||
{
|
{
|
||||||
fn print(&self, out: &mut String) {
|
fn print(&self, out: &mut String) {
|
||||||
(&**self).print(out)
|
(**self).print(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup(&self, name: &str) -> Option<&dyn Value> {
|
fn lookup(&self, name: &str) -> Option<&dyn Value> {
|
||||||
(&**self).lookup(name)
|
(**self).lookup(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has(&self) -> Option<&dyn Value> {
|
fn has(&self) -> Option<&dyn Value> {
|
||||||
(&**self).has()
|
(**self).has()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn if_(&self) -> bool {
|
fn is_truthy(&self) -> bool {
|
||||||
(&**self).if_()
|
(**self).is_truthy()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_(&self, index: usize) -> Option<&dyn Value> {
|
fn index(&self, index: usize) -> Option<&dyn Value> {
|
||||||
(&**self).for_(index)
|
(**self).index(index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,23 +90,23 @@ where
|
||||||
T: Value + ?Sized,
|
T: Value + ?Sized,
|
||||||
{
|
{
|
||||||
fn print(&self, out: &mut String) {
|
fn print(&self, out: &mut String) {
|
||||||
(&**self).print(out)
|
(**self).print(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup(&self, name: &str) -> Option<&dyn Value> {
|
fn lookup(&self, name: &str) -> Option<&dyn Value> {
|
||||||
(&**self).lookup(name)
|
(**self).lookup(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has(&self) -> Option<&dyn Value> {
|
fn has(&self) -> Option<&dyn Value> {
|
||||||
(&**self).has()
|
(**self).has()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn if_(&self) -> bool {
|
fn is_truthy(&self) -> bool {
|
||||||
(&**self).if_()
|
(**self).is_truthy()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_(&self, index: usize) -> Option<&dyn Value> {
|
fn index(&self, index: usize) -> Option<&dyn Value> {
|
||||||
(&**self).for_(index)
|
(**self).index(index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,18 +120,18 @@ impl Value for &str {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has(&self) -> Option<&dyn Value> {
|
fn has(&self) -> Option<&dyn Value> {
|
||||||
if self.if_() {
|
if self.is_truthy() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn if_(&self) -> bool {
|
fn is_truthy(&self) -> bool {
|
||||||
!self.is_empty()
|
!self.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_(&self, index: usize) -> Option<&dyn Value> {
|
fn index(&self, index: usize) -> Option<&dyn Value> {
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
Some(self)
|
Some(self)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -151,18 +150,18 @@ impl Value for String {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has(&self) -> Option<&dyn Value> {
|
fn has(&self) -> Option<&dyn Value> {
|
||||||
if self.if_() {
|
if self.is_truthy() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn if_(&self) -> bool {
|
fn is_truthy(&self) -> bool {
|
||||||
!self.is_empty()
|
!self.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_(&self, index: usize) -> Option<&dyn Value> {
|
fn index(&self, index: usize) -> Option<&dyn Value> {
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
Some(self)
|
Some(self)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -193,11 +192,11 @@ where
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn if_(&self) -> bool {
|
fn is_truthy(&self) -> bool {
|
||||||
self.0.if_() && self.1.if_()
|
self.0.is_truthy() && self.1.is_truthy()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_(&self, index: usize) -> Option<&dyn Value> {
|
fn index(&self, index: usize) -> Option<&dyn Value> {
|
||||||
match index {
|
match index {
|
||||||
0 => Some(&self.0),
|
0 => Some(&self.0),
|
||||||
1 => Some(&self.1),
|
1 => Some(&self.1),
|
||||||
|
|
@ -210,7 +209,7 @@ where
|
||||||
pub struct ValuesListMap<'a>(pub &'a [(&'a str, &'a dyn Value)]);
|
pub struct ValuesListMap<'a>(pub &'a [(&'a str, &'a dyn Value)]);
|
||||||
impl<'a> Value for ValuesListMap<'a> {
|
impl<'a> Value for ValuesListMap<'a> {
|
||||||
fn print(&self, w: &mut String) {
|
fn print(&self, w: &mut String) {
|
||||||
for (name, v) in self.0.iter() {
|
for (name, v) in self.0 {
|
||||||
let _ = write!(w, "{name}");
|
let _ = write!(w, "{name}");
|
||||||
v.print(w);
|
v.print(w);
|
||||||
}
|
}
|
||||||
|
|
@ -228,11 +227,11 @@ impl<'a> Value for ValuesListMap<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn if_(&self) -> bool {
|
fn is_truthy(&self) -> bool {
|
||||||
!self.0.is_empty()
|
!self.0.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_(&self, index: usize) -> Option<&dyn Value> {
|
fn index(&self, index: usize) -> Option<&dyn Value> {
|
||||||
self.0.get(index).map(|v| v as &dyn Value)
|
self.0.get(index).map(|v| v as &dyn Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -242,8 +241,8 @@ where
|
||||||
T: Value,
|
T: Value,
|
||||||
{
|
{
|
||||||
fn print(&self, w: &mut String) {
|
fn print(&self, w: &mut String) {
|
||||||
for v in self.iter() {
|
for v in self {
|
||||||
v.print(w)
|
v.print(w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -260,11 +259,11 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn if_(&self) -> bool {
|
fn is_truthy(&self) -> bool {
|
||||||
self.is_empty()
|
self.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_(&self, index: usize) -> Option<&dyn Value> {
|
fn index(&self, index: usize) -> Option<&dyn Value> {
|
||||||
self.get(index).map(|v| v as &dyn Value)
|
self.get(index).map(|v| v as &dyn Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -275,7 +274,7 @@ where
|
||||||
{
|
{
|
||||||
fn print(&self, out: &mut String) {
|
fn print(&self, out: &mut String) {
|
||||||
if let Some(v) = self {
|
if let Some(v) = self {
|
||||||
v.print(out)
|
v.print(out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -287,11 +286,11 @@ where
|
||||||
self.as_ref().map(|v| v as &dyn Value)
|
self.as_ref().map(|v| v as &dyn Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn if_(&self) -> bool {
|
fn is_truthy(&self) -> bool {
|
||||||
self.is_some()
|
self.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_(&self, index: usize) -> Option<&dyn Value> {
|
fn index(&self, index: usize) -> Option<&dyn Value> {
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
self.has()
|
self.has()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -305,8 +304,8 @@ where
|
||||||
T: Value,
|
T: Value,
|
||||||
{
|
{
|
||||||
fn print(&self, w: &mut String) {
|
fn print(&self, w: &mut String) {
|
||||||
for v in self.iter() {
|
for v in self {
|
||||||
v.print(w)
|
v.print(w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -323,11 +322,11 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn if_(&self) -> bool {
|
fn is_truthy(&self) -> bool {
|
||||||
self.is_empty()
|
self.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_(&self, index: usize) -> Option<&dyn Value> {
|
fn index(&self, index: usize) -> Option<&dyn Value> {
|
||||||
self.get(index).map(|v| v as &dyn Value)
|
self.get(index).map(|v| v as &dyn Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -344,18 +343,18 @@ impl Value for () {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn if_(&self) -> bool {
|
fn is_truthy(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_(&self, _: usize) -> Option<&dyn Value> {
|
fn index(&self, _: usize) -> Option<&dyn Value> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Value for bool {
|
impl Value for bool {
|
||||||
fn print(&self, out: &mut String) {
|
fn print(&self, out: &mut String) {
|
||||||
let _ = write!(out, "{}", self);
|
let _ = write!(out, "{self}");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup(&self, _name: &str) -> Option<&dyn Value> {
|
fn lookup(&self, _name: &str) -> Option<&dyn Value> {
|
||||||
|
|
@ -366,11 +365,11 @@ impl Value for bool {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn if_(&self) -> bool {
|
fn is_truthy(&self) -> bool {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_(&self, _index: usize) -> Option<&dyn Value> {
|
fn index(&self, _index: usize) -> Option<&dyn Value> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -379,6 +378,7 @@ pub struct Newt {
|
||||||
ops: Ops,
|
ops: Ops,
|
||||||
}
|
}
|
||||||
impl Newt {
|
impl Newt {
|
||||||
|
#[must_use]
|
||||||
pub fn build(tmpl: &str) -> Self {
|
pub fn build(tmpl: &str) -> Self {
|
||||||
let ast = parse(tmpl);
|
let ast = parse(tmpl);
|
||||||
let ops = lower_ast(&ast);
|
let ops = lower_ast(&ast);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue