This commit is contained in:
soup 2024-05-31 15:41:22 -04:00
parent 8064118490
commit a3877817dd
No known key found for this signature in database
5 changed files with 61 additions and 69 deletions

View file

@ -75,7 +75,7 @@ pub fn for_(out: &mut String, f: &For, value: &dyn Value, arena: &AstArena) {
};
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);
execute_(out, nodes, value, arena);
idx += 1;
@ -100,7 +100,7 @@ pub fn if_(out: &mut String, f: &If, value: &dyn Value, arena: &AstArena) {
None => return,
};
if value.if_() {
if value.is_truthy() {
let nodes = arena.deref_many(&f.then);
execute_(out, nodes, value, arena);
} else if let Some(else_) = f.else_.as_ref() {

View file

@ -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;
mod parse_backup;
pub(crate) mod vm;
pub mod vm;

View file

@ -1,7 +1,3 @@
use std::ops::ControlFlow;
pub use super::parse_backup::*;
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum AstNodeKind {
If(If),
@ -56,10 +52,12 @@ struct ParseResult<'a, T>(
T, // output
);
impl<'a, T> ParseResult<'a, T> {
#[allow(dead_code)]
fn remaining(&self) -> &'a str {
self.0
}
#[allow(dead_code)]
fn output(&self) -> &T {
&self.1
}
@ -472,7 +470,7 @@ fn parse_many_until(
break;
}
if remaining == "" {
if remaining.is_empty() {
return ParseResult("", None);
}

View file

@ -71,7 +71,7 @@ pub(crate) mod ops {
pub(crate) fn lower_ast(ast: &[AstNodeKind]) -> Ops {
let mut ops = Ops::new();
lower_many(&mut ops, &ast);
lower_many(&mut ops, ast);
ops.emit(Op::Exit);
ops
@ -162,8 +162,8 @@ pub(crate) mod ops {
macro_rules! go {
($src:expr, $expected:expr) => {
assert_eq!(
crate::internal::vm::ops::lower_ast(
&crate::internal::parse::parse($src)
$crate::internal::vm::ops::lower_ast(
&$crate::internal::parse::parse($src)
),
Ops($expected),
)
@ -342,7 +342,7 @@ impl<'a> VmState<'a> {
self.stack_values.pop().expect("stack_values is empty");
},
Op::ValueLookup(field) => {
let new_value = self.reg_value.lookup(&field);
let new_value = self.reg_value.lookup(field);
match new_value {
Some(v) => {
self.reg_value = v;
@ -356,7 +356,7 @@ impl<'a> VmState<'a> {
}
},
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 {
self.reg_value = value;
self.reg_cond = true;
@ -368,7 +368,7 @@ impl<'a> VmState<'a> {
self.reg_value.print(&mut self.output);
},
Op::ValueTruthy => {
self.reg_cond = self.reg_value.if_();
self.reg_cond = self.reg_value.is_truthy();
},
Op::ValueHas => {
if let Some(value) = self.reg_value.has() {

View file

@ -3,8 +3,7 @@ use core::fmt::Write;
pub mod internal;
use internal::{
execute::execute,
parse::{parse, Ast},
parse::parse,
vm::{
ops::{lower_ast, Ops},
VmState,
@ -15,8 +14,8 @@ pub trait Value: core::fmt::Debug {
fn print(&self, out: &mut String);
fn lookup(&self, name: &str) -> Option<&dyn Value>;
fn has(&self) -> Option<&dyn Value>;
fn if_(&self) -> bool;
fn for_(&self, index: usize) -> Option<&dyn Value>;
fn is_truthy(&self) -> bool;
fn index(&self, index: usize) -> Option<&dyn Value>;
}
macro_rules! value_for_int {
@ -31,18 +30,18 @@ macro_rules! value_for_int {
}
fn has(&self) -> Option<&dyn Value> {
if self.if_() {
if self.is_truthy() {
Some(self)
} else {
None
}
}
fn if_(&self) -> bool {
fn is_truthy(&self) -> bool {
*self != 0
}
fn for_(&self, _: usize) -> Option<&dyn Value> {
fn index(&self, _: usize) -> Option<&dyn Value> {
None
}
}
@ -66,23 +65,23 @@ where
T: Value + ?Sized,
{
fn print(&self, out: &mut String) {
(&**self).print(out)
(**self).print(out);
}
fn lookup(&self, name: &str) -> Option<&dyn Value> {
(&**self).lookup(name)
(**self).lookup(name)
}
fn has(&self) -> Option<&dyn Value> {
(&**self).has()
(**self).has()
}
fn if_(&self) -> bool {
(&**self).if_()
fn is_truthy(&self) -> bool {
(**self).is_truthy()
}
fn for_(&self, index: usize) -> Option<&dyn Value> {
(&**self).for_(index)
fn index(&self, index: usize) -> Option<&dyn Value> {
(**self).index(index)
}
}
@ -91,23 +90,23 @@ where
T: Value + ?Sized,
{
fn print(&self, out: &mut String) {
(&**self).print(out)
(**self).print(out);
}
fn lookup(&self, name: &str) -> Option<&dyn Value> {
(&**self).lookup(name)
(**self).lookup(name)
}
fn has(&self) -> Option<&dyn Value> {
(&**self).has()
(**self).has()
}
fn if_(&self) -> bool {
(&**self).if_()
fn is_truthy(&self) -> bool {
(**self).is_truthy()
}
fn for_(&self, index: usize) -> Option<&dyn Value> {
(&**self).for_(index)
fn index(&self, index: usize) -> Option<&dyn Value> {
(**self).index(index)
}
}
@ -121,18 +120,18 @@ impl Value for &str {
}
fn has(&self) -> Option<&dyn Value> {
if self.if_() {
if self.is_truthy() {
None
} else {
Some(self)
}
}
fn if_(&self) -> bool {
fn is_truthy(&self) -> bool {
!self.is_empty()
}
fn for_(&self, index: usize) -> Option<&dyn Value> {
fn index(&self, index: usize) -> Option<&dyn Value> {
if index == 0 {
Some(self)
} else {
@ -151,18 +150,18 @@ impl Value for String {
}
fn has(&self) -> Option<&dyn Value> {
if self.if_() {
if self.is_truthy() {
None
} else {
Some(self)
}
}
fn if_(&self) -> bool {
fn is_truthy(&self) -> bool {
!self.is_empty()
}
fn for_(&self, index: usize) -> Option<&dyn Value> {
fn index(&self, index: usize) -> Option<&dyn Value> {
if index == 0 {
Some(self)
} else {
@ -193,11 +192,11 @@ where
None
}
fn if_(&self) -> bool {
self.0.if_() && self.1.if_()
fn is_truthy(&self) -> bool {
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 {
0 => Some(&self.0),
1 => Some(&self.1),
@ -210,7 +209,7 @@ where
pub struct ValuesListMap<'a>(pub &'a [(&'a str, &'a dyn Value)]);
impl<'a> Value for ValuesListMap<'a> {
fn print(&self, w: &mut String) {
for (name, v) in self.0.iter() {
for (name, v) in self.0 {
let _ = write!(w, "{name}");
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()
}
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)
}
}
@ -242,8 +241,8 @@ where
T: Value,
{
fn print(&self, w: &mut String) {
for v in self.iter() {
v.print(w)
for v in self {
v.print(w);
}
}
@ -260,11 +259,11 @@ where
}
}
fn if_(&self) -> bool {
fn is_truthy(&self) -> bool {
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)
}
}
@ -275,7 +274,7 @@ where
{
fn print(&self, out: &mut String) {
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)
}
fn if_(&self) -> bool {
fn is_truthy(&self) -> bool {
self.is_some()
}
fn for_(&self, index: usize) -> Option<&dyn Value> {
fn index(&self, index: usize) -> Option<&dyn Value> {
if index == 0 {
self.has()
} else {
@ -305,8 +304,8 @@ where
T: Value,
{
fn print(&self, w: &mut String) {
for v in self.iter() {
v.print(w)
for v in self {
v.print(w);
}
}
@ -323,11 +322,11 @@ where
}
}
fn if_(&self) -> bool {
fn is_truthy(&self) -> bool {
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)
}
}
@ -344,18 +343,18 @@ impl Value for () {
None
}
fn if_(&self) -> bool {
fn is_truthy(&self) -> bool {
true
}
fn for_(&self, _: usize) -> Option<&dyn Value> {
fn index(&self, _: usize) -> Option<&dyn Value> {
None
}
}
impl Value for bool {
fn print(&self, out: &mut String) {
let _ = write!(out, "{}", self);
let _ = write!(out, "{self}");
}
fn lookup(&self, _name: &str) -> Option<&dyn Value> {
@ -366,11 +365,11 @@ impl Value for bool {
Some(self)
}
fn if_(&self) -> bool {
fn is_truthy(&self) -> bool {
*self
}
fn for_(&self, _index: usize) -> Option<&dyn Value> {
fn index(&self, _index: usize) -> Option<&dyn Value> {
None
}
}
@ -379,6 +378,7 @@ pub struct Newt {
ops: Ops,
}
impl Newt {
#[must_use]
pub fn build(tmpl: &str) -> Self {
let ast = parse(tmpl);
let ops = lower_ast(&ast);