Compare commits
No commits in common. "7f7bf5c98d9a8af0f1a21052c802f0297a752fe3" and "79a037b7493c877d48fe18da2cb8804bbfa8d0ba" have entirely different histories.
7f7bf5c98d
...
79a037b749
16 changed files with 22 additions and 320 deletions
|
|
@ -1,5 +1,3 @@
|
||||||
#![allow(missing_docs)]
|
|
||||||
|
|
||||||
use criterion::BenchmarkId;
|
use criterion::BenchmarkId;
|
||||||
use criterion::Criterion;
|
use criterion::Criterion;
|
||||||
use criterion::criterion_group;
|
use criterion::criterion_group;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#![allow(missing_docs)]
|
|
||||||
|
|
||||||
use criterion::BenchmarkId;
|
use criterion::BenchmarkId;
|
||||||
use criterion::Criterion;
|
use criterion::Criterion;
|
||||||
use criterion::criterion_group;
|
use criterion::criterion_group;
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ pub enum Instruction {
|
||||||
slot: VariableSlot,
|
slot: VariableSlot,
|
||||||
},
|
},
|
||||||
PushScope {
|
PushScope {
|
||||||
#[allow(unused)]
|
#[expect(unused)]
|
||||||
inherit_parent: bool,
|
inherit_parent: bool,
|
||||||
},
|
},
|
||||||
Abort,
|
Abort,
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,11 @@ use annotate_snippets::Level;
|
||||||
use annotate_snippets::Renderer;
|
use annotate_snippets::Renderer;
|
||||||
use annotate_snippets::Snippet;
|
use annotate_snippets::Snippet;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use winnow::stream::Offset;
|
|
||||||
|
|
||||||
use crate::input::NomoInput;
|
use crate::input::NomoInput;
|
||||||
use crate::lexer::ParseError;
|
use crate::lexer::ParseError;
|
||||||
use crate::parser::AstError;
|
use crate::parser::AstError;
|
||||||
|
|
||||||
/// An error occurred while producing an Ast
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub struct AstFailure {
|
pub struct AstFailure {
|
||||||
errors: Vec<AstError>,
|
errors: Vec<AstError>,
|
||||||
|
|
@ -28,7 +26,6 @@ impl AstFailure {
|
||||||
AstFailure { errors }
|
AstFailure { errors }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a CLI printable report
|
|
||||||
pub fn to_report(&self, source: &str) -> String {
|
pub fn to_report(&self, source: &str) -> String {
|
||||||
let reports = self
|
let reports = self
|
||||||
.errors
|
.errors
|
||||||
|
|
@ -41,14 +38,12 @@ impl AstFailure {
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.unwrap_or("An error occurred while producing an Ast"),
|
.unwrap_or("An error occurred while producing an Ast"),
|
||||||
)
|
)
|
||||||
.element(annotate_snippets::Snippet::source(source).annotation(
|
.element(
|
||||||
annotate_snippets::AnnotationKind::Primary.span(
|
annotate_snippets::Snippet::source(source).annotation(
|
||||||
constrain_without_whitespace(
|
annotate_snippets::AnnotationKind::Primary
|
||||||
source,
|
.span(error.span.clone().map(|s| s.range).unwrap_or_else(|| 0..0)),
|
||||||
error.span.clone().map(|s| s.range).unwrap_or_else(|| 0..0),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
))
|
)
|
||||||
.elements(
|
.elements(
|
||||||
error
|
error
|
||||||
.help
|
.help
|
||||||
|
|
@ -64,18 +59,6 @@ impl AstFailure {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn constrain_without_whitespace(
|
|
||||||
input: &str,
|
|
||||||
range: std::ops::Range<usize>,
|
|
||||||
) -> std::ops::Range<usize> {
|
|
||||||
let trimmed = input[range].trim();
|
|
||||||
let start = trimmed.offset_from(&input);
|
|
||||||
let end = start + trimmed.len();
|
|
||||||
|
|
||||||
start..end
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error occurred during lexing
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub struct ParseFailure {
|
pub struct ParseFailure {
|
||||||
input: Arc<str>,
|
input: Arc<str>,
|
||||||
|
|
@ -96,7 +79,6 @@ impl ParseFailure {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Produce a CLi printable report
|
|
||||||
pub fn to_report(&self) -> String {
|
pub fn to_report(&self) -> String {
|
||||||
let reports = self
|
let reports = self
|
||||||
.errors
|
.errors
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ pub trait NomoFunction<T>: 'static + Send + Sync {
|
||||||
|
|
||||||
#[cfg(feature = "unstable-pub")]
|
#[cfg(feature = "unstable-pub")]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
#[expect(missing_docs)]
|
|
||||||
pub struct FunctionMap {
|
pub struct FunctionMap {
|
||||||
funcs: HashMap<String, ErasedNomoFunction>,
|
funcs: HashMap<String, ErasedNomoFunction>,
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +45,6 @@ pub(crate) struct FunctionMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionMap {
|
impl FunctionMap {
|
||||||
#[expect(missing_docs)]
|
|
||||||
pub fn register<NF: NomoFunction<T>, T>(&mut self, name: impl Into<String>, func: NF) {
|
pub fn register<NF: NomoFunction<T>, T>(&mut self, name: impl Into<String>, func: NF) {
|
||||||
self.funcs
|
self.funcs
|
||||||
.insert(name.into(), ErasedNomoFunction::erase(func));
|
.insert(name.into(), ErasedNomoFunction::erase(func));
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use annotate_snippets::AnnotationKind;
|
||||||
|
use annotate_snippets::Level;
|
||||||
|
use annotate_snippets::Renderer;
|
||||||
|
use annotate_snippets::Snippet;
|
||||||
|
use thiserror::Error;
|
||||||
use winnow::LocatingSlice;
|
use winnow::LocatingSlice;
|
||||||
use winnow::Parser;
|
use winnow::Parser;
|
||||||
use winnow::RecoverableParser;
|
use winnow::RecoverableParser;
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,6 @@ macro_rules! unstable_pub {
|
||||||
($(#[$m:meta])* mod $name:ident) => {
|
($(#[$m:meta])* mod $name:ident) => {
|
||||||
$(#[$m])*
|
$(#[$m])*
|
||||||
#[cfg(feature = "unstable-pub")]
|
#[cfg(feature = "unstable-pub")]
|
||||||
#[allow(missing_docs)]
|
|
||||||
pub mod $name;
|
pub mod $name;
|
||||||
#[cfg(not(feature = "unstable-pub"))]
|
#[cfg(not(feature = "unstable-pub"))]
|
||||||
mod $name;
|
mod $name;
|
||||||
|
|
@ -137,7 +136,7 @@ unstable_pub!(
|
||||||
mod parser
|
mod parser
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Errors in this library
|
/// Nomo Functions
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
|
|
||||||
/// Nomo Functions
|
/// Nomo Functions
|
||||||
|
|
|
||||||
|
|
@ -104,14 +104,13 @@ impl FromRecoverableError<Input<'_>, AstError> for AstError {
|
||||||
.filter(|t| t.kind() != TokenKind::Whitespace);
|
.filter(|t| t.kind() != TokenKind::Whitespace);
|
||||||
let last = tokens.next();
|
let last = tokens.next();
|
||||||
let first = tokens.last();
|
let first = tokens.last();
|
||||||
|
|
||||||
match (last, first) {
|
match (last, first) {
|
||||||
(None, None) => None,
|
(None, None) => None,
|
||||||
(None, Some(single)) | (Some(single), None) => Some(SourceSpan {
|
(None, Some(single)) | (Some(single), None) => Some(SourceSpan {
|
||||||
range: single.source().get_range(),
|
range: single.source().get_range(),
|
||||||
}),
|
}),
|
||||||
(Some(last), Some(first)) => {
|
(Some(last), Some(first)) => {
|
||||||
let start = first.source().get_range().end;
|
let start = first.source().get_range().start;
|
||||||
let end = last.source().get_range().end;
|
let end = last.source().get_range().end;
|
||||||
|
|
||||||
Some(SourceSpan { range: start..end })
|
Some(SourceSpan { range: start..end })
|
||||||
|
|
@ -213,7 +212,7 @@ pub enum TemplateAstExpr<'input> {
|
||||||
ElseConditional {
|
ElseConditional {
|
||||||
expression: Option<Box<TemplateAstExpr<'input>>>,
|
expression: Option<Box<TemplateAstExpr<'input>>>,
|
||||||
},
|
},
|
||||||
#[allow(unused)]
|
#[expect(unused)]
|
||||||
Invalid(&'input [TemplateToken]),
|
Invalid(&'input [TemplateToken]),
|
||||||
MathOperation {
|
MathOperation {
|
||||||
op: TokenOperator,
|
op: TokenOperator,
|
||||||
|
|
@ -312,7 +311,7 @@ fn parse_action<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'in
|
||||||
(parse_block(
|
(parse_block(
|
||||||
cut_err(not(repeat_till(
|
cut_err(not(repeat_till(
|
||||||
0..,
|
0..,
|
||||||
parse_expression,
|
any,
|
||||||
peek((ws, TokenKind::RightDelim)),
|
peek((ws, TokenKind::RightDelim)),
|
||||||
)
|
)
|
||||||
.map(|((), _)| ())))
|
.map(|((), _)| ())))
|
||||||
|
|
@ -343,7 +342,7 @@ fn parse_for_chain<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<
|
||||||
|
|
||||||
let (content, taken) = resume_after_cut(
|
let (content, taken) = resume_after_cut(
|
||||||
repeat_till(0.., parse_ast, loop_end),
|
repeat_till(0.., parse_ast, loop_end),
|
||||||
repeat_till(0.., parse_ast, parse_end).map(|((), _)| ()),
|
repeat_till(0.., any, parse_end).map(|((), _)| ()),
|
||||||
)
|
)
|
||||||
.with_taken()
|
.with_taken()
|
||||||
.parse_next(input)?;
|
.parse_next(input)?;
|
||||||
|
|
@ -373,11 +372,9 @@ fn parse_for_loop<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'
|
||||||
ws,
|
ws,
|
||||||
TokenKind::For,
|
TokenKind::For,
|
||||||
ws,
|
ws,
|
||||||
cut_err(TokenKind::Ident.context(AstError::ctx().msg("Expected identifier here"))),
|
TokenKind::Ident,
|
||||||
ws,
|
ws,
|
||||||
cut_err(
|
TokenKind::In,
|
||||||
TokenKind::In.context(AstError::ctx().msg("Missing `in` in `for _ in <expr>`")),
|
|
||||||
),
|
|
||||||
ws,
|
ws,
|
||||||
parse_expression.map(Box::new),
|
parse_expression.map(Box::new),
|
||||||
)
|
)
|
||||||
|
|
@ -604,34 +601,11 @@ where
|
||||||
fn parse_operand<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
fn parse_operand<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
trace(
|
trace(
|
||||||
"operand",
|
"operand",
|
||||||
alt((
|
alt((parse_function, parse_variable_access, parse_literal)),
|
||||||
parse_keywords_fail,
|
|
||||||
parse_function,
|
|
||||||
parse_variable_access,
|
|
||||||
parse_literal,
|
|
||||||
)),
|
|
||||||
)
|
)
|
||||||
.parse_next(input)
|
.parse_next(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_keywords_fail<'input>(
|
|
||||||
input: &mut Input<'input>,
|
|
||||||
) -> Result<TemplateAstExpr<'input>, AstError> {
|
|
||||||
let value = alt((
|
|
||||||
TokenKind::ConditionalIf,
|
|
||||||
TokenKind::For,
|
|
||||||
TokenKind::End,
|
|
||||||
TokenKind::In,
|
|
||||||
))
|
|
||||||
.take()
|
|
||||||
.map(TemplateAstExpr::Invalid)
|
|
||||||
.parse_next(input)?;
|
|
||||||
|
|
||||||
cut_err(fail::<_, (), _>.context(AstError::ctx().msg("Found literal, expected expression")))
|
|
||||||
.value(value)
|
|
||||||
.parse_next(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_literal<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
fn parse_literal<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
trace(
|
trace(
|
||||||
"literal",
|
"literal",
|
||||||
|
|
@ -921,7 +895,7 @@ mod tests {
|
||||||
help: None,
|
help: None,
|
||||||
span: Some(
|
span: Some(
|
||||||
SourceSpan {
|
SourceSpan {
|
||||||
range: 2..6,
|
range: 0..6,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
is_fatal: false,
|
is_fatal: false,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#![allow(missing_docs)]
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_files() {
|
fn check_files() {
|
||||||
let files = std::fs::read_dir("tests/checks/").unwrap();
|
let files = std::fs::read_dir("tests/checks/").unwrap();
|
||||||
|
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
---
|
|
||||||
source: tests/file_tests.rs
|
|
||||||
expression: parsed
|
|
||||||
info:
|
|
||||||
input: "{{ if }} {{ end }}\n{{ if if }} {{ end }}\n{{ if if }} {{ for foo in bar }} {{ end }} {{ end }}\n{{ for in bar }} {{ end }}\n{{ for blah bar }} {{ end }}\n{{ else }}"
|
|
||||||
context: {}
|
|
||||||
---
|
|
||||||
ParsedTemplate {
|
|
||||||
tokens: [
|
|
||||||
[LeftDelim]"{{" (0..2),
|
|
||||||
[Whitespace]" " (2..3),
|
|
||||||
[ConditionalIf]"if" (3..5),
|
|
||||||
[Whitespace]" " (5..6),
|
|
||||||
[RightDelim]"}}" (6..8),
|
|
||||||
[Whitespace]" " (8..9),
|
|
||||||
[LeftDelim]"{{" (9..11),
|
|
||||||
[Whitespace]" " (11..12),
|
|
||||||
[End]"end" (12..15),
|
|
||||||
[Whitespace]" " (15..16),
|
|
||||||
[RightDelim]"}}" (16..18),
|
|
||||||
[Whitespace]"\n" (18..19),
|
|
||||||
[LeftDelim]"{{" (19..21),
|
|
||||||
[Whitespace]" " (21..22),
|
|
||||||
[ConditionalIf]"if" (22..24),
|
|
||||||
[Whitespace]" " (24..25),
|
|
||||||
[ConditionalIf]"if" (25..27),
|
|
||||||
[Whitespace]" " (27..28),
|
|
||||||
[RightDelim]"}}" (28..30),
|
|
||||||
[Whitespace]" " (30..31),
|
|
||||||
[LeftDelim]"{{" (31..33),
|
|
||||||
[Whitespace]" " (33..34),
|
|
||||||
[End]"end" (34..37),
|
|
||||||
[Whitespace]" " (37..38),
|
|
||||||
[RightDelim]"}}" (38..40),
|
|
||||||
[Whitespace]"\n" (40..41),
|
|
||||||
[LeftDelim]"{{" (41..43),
|
|
||||||
[Whitespace]" " (43..44),
|
|
||||||
[ConditionalIf]"if" (44..46),
|
|
||||||
[Whitespace]" " (46..47),
|
|
||||||
[ConditionalIf]"if" (47..49),
|
|
||||||
[Whitespace]" " (49..50),
|
|
||||||
[RightDelim]"}}" (50..52),
|
|
||||||
[Whitespace]" " (52..53),
|
|
||||||
[LeftDelim]"{{" (53..55),
|
|
||||||
[Whitespace]" " (55..56),
|
|
||||||
[For]"for" (56..59),
|
|
||||||
[Whitespace]" " (59..60),
|
|
||||||
[Ident]"foo" (60..63),
|
|
||||||
[Whitespace]" " (63..64),
|
|
||||||
[In]"in" (64..66),
|
|
||||||
[Whitespace]" " (66..67),
|
|
||||||
[Ident]"bar" (67..70),
|
|
||||||
[Whitespace]" " (70..71),
|
|
||||||
[RightDelim]"}}" (71..73),
|
|
||||||
[Whitespace]" " (73..74),
|
|
||||||
[LeftDelim]"{{" (74..76),
|
|
||||||
[Whitespace]" " (76..77),
|
|
||||||
[End]"end" (77..80),
|
|
||||||
[Whitespace]" " (80..81),
|
|
||||||
[RightDelim]"}}" (81..83),
|
|
||||||
[Whitespace]" " (83..84),
|
|
||||||
[LeftDelim]"{{" (84..86),
|
|
||||||
[Whitespace]" " (86..87),
|
|
||||||
[End]"end" (87..90),
|
|
||||||
[Whitespace]" " (90..91),
|
|
||||||
[RightDelim]"}}" (91..93),
|
|
||||||
[Whitespace]"\n" (93..94),
|
|
||||||
[LeftDelim]"{{" (94..96),
|
|
||||||
[Whitespace]" " (96..97),
|
|
||||||
[For]"for" (97..100),
|
|
||||||
[Whitespace]" " (100..101),
|
|
||||||
[In]"in" (101..103),
|
|
||||||
[Whitespace]" " (103..104),
|
|
||||||
[Ident]"bar" (104..107),
|
|
||||||
[Whitespace]" " (107..108),
|
|
||||||
[RightDelim]"}}" (108..110),
|
|
||||||
[Whitespace]" " (110..111),
|
|
||||||
[LeftDelim]"{{" (111..113),
|
|
||||||
[Whitespace]" " (113..114),
|
|
||||||
[End]"end" (114..117),
|
|
||||||
[Whitespace]" " (117..118),
|
|
||||||
[RightDelim]"}}" (118..120),
|
|
||||||
[Whitespace]"\n" (120..121),
|
|
||||||
[LeftDelim]"{{" (121..123),
|
|
||||||
[Whitespace]" " (123..124),
|
|
||||||
[For]"for" (124..127),
|
|
||||||
[Whitespace]" " (127..128),
|
|
||||||
[Ident]"blah" (128..132),
|
|
||||||
[Whitespace]" " (132..133),
|
|
||||||
[Ident]"bar" (133..136),
|
|
||||||
[Whitespace]" " (136..137),
|
|
||||||
[RightDelim]"}}" (137..139),
|
|
||||||
[Whitespace]" " (139..140),
|
|
||||||
[LeftDelim]"{{" (140..142),
|
|
||||||
[Whitespace]" " (142..143),
|
|
||||||
[End]"end" (143..146),
|
|
||||||
[Whitespace]" " (146..147),
|
|
||||||
[RightDelim]"}}" (147..149),
|
|
||||||
[Whitespace]"\n" (149..150),
|
|
||||||
[LeftDelim]"{{" (150..152),
|
|
||||||
[Whitespace]" " (152..153),
|
|
||||||
[ConditionalElse]"else" (153..157),
|
|
||||||
[Whitespace]" " (157..158),
|
|
||||||
[RightDelim]"}}" (158..160),
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
---
|
|
||||||
source: tests/file_tests.rs
|
|
||||||
expression: ast
|
|
||||||
info:
|
|
||||||
input: "{{ if }} {{ end }}\n{{ if if }} {{ end }}\n{{ if if }} {{ for foo in bar }} {{ end }} {{ end }}\n{{ for in bar }} {{ end }}\n{{ for blah bar }} {{ end }}\n{{ else }}"
|
|
||||||
context: {}
|
|
||||||
---
|
|
||||||
[1m[91merror[0m[1m: Expected an expression after 'if'[0m
|
|
||||||
[1m[94m ╭▸ [0m
|
|
||||||
[1m[94m1[0m [1m[94m│[0m {{ if }} {{ end }}
|
|
||||||
[1m[94m│[0m [1m[91m━━[0m
|
|
||||||
[1m[94m╰╴[0m
|
|
||||||
[1m[91merror[0m[1m: Expected an expression after 'if'[0m
|
|
||||||
[1m[94m ╭▸ [0m
|
|
||||||
[1m[94m2[0m [1m[94m│[0m {{ if if }} {{ end }}
|
|
||||||
[1m[94m╰╴[0m [1m[91m━━[0m
|
|
||||||
[1m[91merror[0m[1m: Expected an expression after 'if'[0m
|
|
||||||
[1m[94m ╭▸ [0m
|
|
||||||
[1m[94m3[0m [1m[94m│[0m {{ if if }} {{ for foo in bar }} {{ end }} {{ end }}
|
|
||||||
[1m[94m╰╴[0m [1m[91m━━[0m
|
|
||||||
[1m[91merror[0m[1m: Expected identifier here[0m
|
|
||||||
[1m[94m ╭▸ [0m
|
|
||||||
[1m[94m4[0m [1m[94m│[0m {{ for in bar }} {{ end }}
|
|
||||||
[1m[94m╰╴[0m [1m[91m━━━━━━[0m
|
|
||||||
[1m[91merror[0m[1m: Missing `in` in `for _ in <expr>`[0m
|
|
||||||
[1m[94m ╭▸ [0m
|
|
||||||
[1m[94m5[0m [1m[94m│[0m {{ for blah bar }} {{ end }}
|
|
||||||
[1m[94m╰╴[0m [1m[91m━━━━━━━━[0m
|
|
||||||
[1m[91merror[0m[1m: An error occurred while producing an Ast[0m
|
|
||||||
[1m[94m ╭▸ [0m
|
|
||||||
[1m[94m6[0m [1m[94m│[0m {{ else }}
|
|
||||||
[1m[94m╰╴[0m [1m[91m━━━━━━━[0m
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
{}
|
|
||||||
---
|
|
||||||
{{ if }} {{ end }}
|
|
||||||
{{ if if }} {{ end }}
|
|
||||||
{{ if if }} {{ for foo in bar }} {{ end }} {{ end }}
|
|
||||||
{{ for in bar }} {{ end }}
|
|
||||||
{{ for blah bar }} {{ end }}
|
|
||||||
{{ else }}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
---
|
|
||||||
source: tests/file_tests.rs
|
|
||||||
expression: parsed
|
|
||||||
info:
|
|
||||||
input: "{{ if if }} {{ end }}"
|
|
||||||
context: {}
|
|
||||||
---
|
|
||||||
ParsedTemplate {
|
|
||||||
tokens: [
|
|
||||||
[LeftDelim]"{{" (0..2),
|
|
||||||
[Whitespace]" " (2..3),
|
|
||||||
[ConditionalIf]"if" (3..5),
|
|
||||||
[Whitespace]" " (5..6),
|
|
||||||
[ConditionalIf]"if" (6..8),
|
|
||||||
[Whitespace]" " (8..9),
|
|
||||||
[RightDelim]"}}" (9..11),
|
|
||||||
[Whitespace]" " (11..12),
|
|
||||||
[LeftDelim]"{{" (12..14),
|
|
||||||
[Whitespace]" " (14..15),
|
|
||||||
[End]"end" (15..18),
|
|
||||||
[Whitespace]" " (18..19),
|
|
||||||
[RightDelim]"}}" (19..21),
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
---
|
|
||||||
source: tests/file_tests.rs
|
|
||||||
expression: ast
|
|
||||||
info:
|
|
||||||
input: "{{ if if }} {{ end }}"
|
|
||||||
context: {}
|
|
||||||
---
|
|
||||||
[1m[91merror[0m[1m: Expected an expression after 'if'[0m
|
|
||||||
[1m[94m ╭▸ [0m
|
|
||||||
[1m[94m1[0m [1m[94m│[0m {{ if if }} {{ end }}
|
|
||||||
[1m[94m╰╴[0m [1m[91m━━[0m
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
{}
|
|
||||||
---
|
|
||||||
{{ if if }} {{ end }}
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#![allow(missing_docs)]
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
|
@ -8,8 +6,6 @@ use nomo::functions::FunctionMap;
|
||||||
|
|
||||||
test_each_file::test_each_path! { for ["nomo"] in "./tests/cases/" as cases => check_for_input }
|
test_each_file::test_each_path! { for ["nomo"] in "./tests/cases/" as cases => check_for_input }
|
||||||
|
|
||||||
test_each_file::test_each_path! { for ["nomo"] in "./tests/errors/" as error_cases => check_errors }
|
|
||||||
|
|
||||||
#[derive(serde::Serialize)]
|
#[derive(serde::Serialize)]
|
||||||
struct Info {
|
struct Info {
|
||||||
input: String,
|
input: String,
|
||||||
|
|
@ -67,67 +63,3 @@ fn check_for_input([path]: [&Path; 1]) {
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(format!("{basename}.4-output"), output);
|
insta::assert_debug_snapshot!(format!("{basename}.4-output"), output);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_errors([path]: [&Path; 1]) {
|
|
||||||
let mut settings = insta::Settings::clone_current();
|
|
||||||
settings.set_snapshot_path("errors");
|
|
||||||
settings.set_prepend_module_to_snapshot(false);
|
|
||||||
|
|
||||||
let basename = path.file_stem().unwrap().to_string_lossy();
|
|
||||||
let input = std::fs::read_to_string(path).unwrap();
|
|
||||||
|
|
||||||
let (context, input) = input.split_once("\n---\n").unwrap_or_else(|| ("", &input));
|
|
||||||
|
|
||||||
let map = if !context.is_empty() {
|
|
||||||
serde_json::from_str::<HashMap<String, serde_json::Value>>(context).unwrap()
|
|
||||||
} else {
|
|
||||||
HashMap::new()
|
|
||||||
};
|
|
||||||
|
|
||||||
settings.set_info(&Info {
|
|
||||||
input: input.to_string(),
|
|
||||||
context: map.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut context = Context::new();
|
|
||||||
|
|
||||||
for (k, v) in map {
|
|
||||||
context.try_insert(k, v).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let _guard = settings.bind_to_scope();
|
|
||||||
|
|
||||||
let parsed = nomo::lexer::parse(input.into()).map_err(|err| err.to_report());
|
|
||||||
|
|
||||||
match &parsed {
|
|
||||||
Ok(parsed) => insta::assert_debug_snapshot!(format!("{basename}.1-parsed"), parsed),
|
|
||||||
Err(parsed) => insta::assert_snapshot!(format!("{basename}.1-parsed"), parsed),
|
|
||||||
}
|
|
||||||
|
|
||||||
let Ok(parsed) = parsed else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let ast = nomo::parser::parse(parsed.tokens()).map_err(|err| err.to_report(input));
|
|
||||||
|
|
||||||
match &ast {
|
|
||||||
Ok(ast) => insta::assert_debug_snapshot!(format!("{basename}.2-ast"), ast),
|
|
||||||
Err(ast) => insta::assert_snapshot!(format!("{basename}.2-ast"), ast),
|
|
||||||
}
|
|
||||||
|
|
||||||
let Ok(ast) = ast else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let emit = nomo::compiler::emit_machine(ast);
|
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(format!("{basename}.3-instructions"), emit);
|
|
||||||
|
|
||||||
let output = nomo::eval::execute(&FunctionMap::default(), &emit, &context)
|
|
||||||
.map_err(|err| err.to_string());
|
|
||||||
|
|
||||||
match &output {
|
|
||||||
Ok(output) => insta::assert_debug_snapshot!(format!("{basename}.4-output"), output),
|
|
||||||
Err(output) => insta::assert_snapshot!(format!("{basename}.4-output"), output),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue