Allow variadic arguments in trace

Although, doesn't do anything with them yet. The idea is to simplify
  the use of trace to make it a lot more useful than it currently is.
This commit is contained in:
KtorZ 2024-07-18 08:32:26 +02:00
parent 976262c2e6
commit f9719af23e
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
25 changed files with 248 additions and 39 deletions

View File

@ -548,7 +548,8 @@ pub enum UntypedExpr {
kind: TraceKind, kind: TraceKind,
location: Span, location: Span,
then: Box<Self>, then: Box<Self>,
text: Box<Self>, label: Box<Self>,
arguments: Vec<Self>,
}, },
TraceIfFalse { TraceIfFalse {
@ -1134,10 +1135,11 @@ impl UntypedExpr {
location, location,
kind: TraceKind::Todo, kind: TraceKind::Todo,
then: Box::new(UntypedExpr::ErrorTerm { location }), then: Box::new(UntypedExpr::ErrorTerm { location }),
text: Box::new(reason.unwrap_or_else(|| UntypedExpr::String { label: Box::new(reason.unwrap_or_else(|| UntypedExpr::String {
location, location,
value: DEFAULT_TODO_STR.to_string(), value: DEFAULT_TODO_STR.to_string(),
})), })),
arguments: Vec::new(),
} }
} }
@ -1147,7 +1149,8 @@ impl UntypedExpr {
location, location,
kind: TraceKind::Error, kind: TraceKind::Error,
then: Box::new(UntypedExpr::ErrorTerm { location }), then: Box::new(UntypedExpr::ErrorTerm { location }),
text: Box::new(reason), label: Box::new(reason),
arguments: Vec::new(),
} }
} else { } else {
UntypedExpr::ErrorTerm { location } UntypedExpr::ErrorTerm { location }

View File

@ -969,8 +969,12 @@ impl<'comments> Formatter<'comments> {
} => self.assignment(patterns, value, *kind), } => self.assignment(patterns, value, *kind),
UntypedExpr::Trace { UntypedExpr::Trace {
kind, text, then, .. kind,
} => self.trace(kind, text, then), label,
then,
arguments,
..
} => self.trace(kind, label, arguments, then),
UntypedExpr::When { UntypedExpr::When {
subject, clauses, .. subject, clauses, ..
@ -1037,26 +1041,34 @@ impl<'comments> Formatter<'comments> {
pub fn trace<'a>( pub fn trace<'a>(
&mut self, &mut self,
kind: &'a TraceKind, kind: &'a TraceKind,
text: &'a UntypedExpr, label: &'a UntypedExpr,
arguments: &'a [UntypedExpr],
then: &'a UntypedExpr, then: &'a UntypedExpr,
) -> Document<'a> { ) -> Document<'a> {
let (keyword, default_text) = match kind { let (keyword, default_label) = match kind {
TraceKind::Trace => ("trace", None), TraceKind::Trace => ("trace", None),
TraceKind::Error => ("fail", Some(DEFAULT_ERROR_STR.to_string())), TraceKind::Error => ("fail", Some(DEFAULT_ERROR_STR.to_string())),
TraceKind::Todo => ("todo", Some(DEFAULT_TODO_STR.to_string())), TraceKind::Todo => ("todo", Some(DEFAULT_TODO_STR.to_string())),
}; };
let body = match text { let mut body = match label {
UntypedExpr::String { value, .. } if Some(value) == default_text.as_ref() => { UntypedExpr::String { value, .. } if Some(value) == default_label.as_ref() => {
keyword.to_doc() keyword.to_doc()
} }
_ => keyword _ => keyword
.to_doc() .to_doc()
.append(" ") .append(" ")
.append(self.wrap_expr(text)) .append(self.wrap_expr(label))
.group(), .group(),
}; };
for (ix, arg) in arguments.iter().enumerate() {
body = body
.append(if ix == 0 { ": " } else { ", " })
.append(self.wrap_expr(arg))
.group();
}
match kind { match kind {
TraceKind::Error | TraceKind::Todo => body, TraceKind::Error | TraceKind::Todo => body,
TraceKind::Trace => body TraceKind::Trace => body
@ -1095,7 +1107,6 @@ impl<'comments> Formatter<'comments> {
if args.is_empty() && spread_location.is_some() { if args.is_empty() && spread_location.is_some() {
if is_record { if is_record {
name.append(" { .. }") name.append(" { .. }")
// TODO: not possible
} else { } else {
name.append("(..)") name.append("(..)")
} }

View File

@ -11,10 +11,11 @@ Fn(
then: ErrorTerm { then: ErrorTerm {
location: 0..15, location: 0..15,
}, },
text: String { label: String {
location: 0..15, location: 0..15,
value: "aiken::todo", value: "aiken::todo",
}, },
arguments: [],
}, },
doc: None, doc: None,
location: 0..12, location: 0..12,

View File

@ -11,10 +11,11 @@ Fn(
then: ErrorTerm { then: ErrorTerm {
location: 0..11, location: 0..11,
}, },
text: String { label: String {
location: 0..11, location: 0..11,
value: "aiken::todo", value: "aiken::todo",
}, },
arguments: [],
}, },
doc: None, doc: None,
location: 0..8, location: 0..8,

View File

@ -28,13 +28,25 @@ pub fn parser<'a>(
.map_with_span(UntypedExpr::fail), .map_with_span(UntypedExpr::fail),
just(Token::Trace) just(Token::Trace)
.ignore_then(choice((string::hybrid(), expression.clone()))) .ignore_then(choice((string::hybrid(), expression.clone())))
.then(
just(Token::Colon)
.ignore_then(
choice((string::hybrid(), expression.clone()))
.separated_by(just(Token::Comma)),
)
.or_not()
.map(|opt| opt.unwrap_or_default()),
)
.then(sequence.clone().or_not()) .then(sequence.clone().or_not())
.map_with_span(|(text, then_), span| UntypedExpr::Trace { .map_with_span(
kind: TraceKind::Trace, |((label, arguments), continuation), span| UntypedExpr::Trace {
location: span, kind: TraceKind::Trace,
then: Box::new(then_.unwrap_or_else(|| UntypedExpr::todo(None, span))), location: span,
text: Box::new(text), then: Box::new(continuation.unwrap_or_else(|| UntypedExpr::todo(None, span))),
}), label: Box::new(label),
arguments,
},
),
)) ))
} }
@ -114,6 +126,26 @@ mod tests {
); );
} }
#[test]
fn trace_string() {
assert_expr!(
r#"
trace @"foo"
a
"#
);
}
#[test]
fn trace_bytearray() {
assert_expr!(
r#"
trace "foo"
a
"#
);
}
#[test] #[test]
fn trace_expr() { fn trace_expr() {
assert_expr!( assert_expr!(
@ -132,4 +164,22 @@ mod tests {
"# "#
); );
} }
#[test]
fn trace_labelled() {
assert_expr!(
r#"
trace foo: "bar"
"#
);
}
#[test]
fn trace_variadic() {
assert_expr!(
r#"
trace "foo": @"bar", baz
"#
);
}
} }

View File

@ -8,8 +8,9 @@ Trace {
then: ErrorTerm { then: ErrorTerm {
location: 0..11, location: 0..11,
}, },
text: String { label: String {
location: 5..11, location: 5..11,
value: "foo", value: "foo",
}, },
arguments: [],
} }

View File

@ -8,8 +8,9 @@ Trace {
then: ErrorTerm { then: ErrorTerm {
location: 0..10, location: 0..10,
}, },
text: String { label: String {
location: 5..10, location: 5..10,
value: "foo", value: "foo",
}, },
arguments: [],
} }

View File

@ -8,7 +8,7 @@ Trace {
then: ErrorTerm { then: ErrorTerm {
location: 0..67, location: 0..67,
}, },
text: Call { label: Call {
arguments: [ arguments: [
CallArg { CallArg {
label: None, label: None,
@ -51,4 +51,5 @@ Trace {
}, },
location: 5..67, location: 5..67,
}, },
arguments: [],
} }

View File

@ -20,10 +20,11 @@ If {
then: ErrorTerm { then: ErrorTerm {
location: 20..24, location: 20..24,
}, },
text: String { label: String {
location: 20..24, location: 20..24,
value: "aiken::todo", value: "aiken::todo",
}, },
arguments: [],
}, },
is: Some( is: Some(
AssignmentPattern { AssignmentPattern {
@ -51,9 +52,10 @@ If {
then: ErrorTerm { then: ErrorTerm {
location: 36..40, location: 36..40,
}, },
text: String { label: String {
location: 36..40, location: 36..40,
value: "aiken::todo", value: "aiken::todo",
}, },
arguments: [],
}, },
} }

View File

@ -20,10 +20,11 @@ If {
then: ErrorTerm { then: ErrorTerm {
location: 31..35, location: 31..35,
}, },
text: String { label: String {
location: 31..35, location: 31..35,
value: "aiken::todo", value: "aiken::todo",
}, },
arguments: [],
}, },
is: Some( is: Some(
AssignmentPattern { AssignmentPattern {
@ -68,9 +69,10 @@ If {
then: ErrorTerm { then: ErrorTerm {
location: 47..51, location: 47..51,
}, },
text: String { label: String {
location: 47..51, location: 47..51,
value: "aiken::todo", value: "aiken::todo",
}, },
arguments: [],
}, },
} }

View File

@ -8,8 +8,9 @@ Trace {
then: ErrorTerm { then: ErrorTerm {
location: 0..11, location: 0..11,
}, },
text: String { label: String {
location: 5..11, location: 5..11,
value: "foo", value: "foo",
}, },
arguments: [],
} }

View File

@ -8,8 +8,9 @@ Trace {
then: ErrorTerm { then: ErrorTerm {
location: 0..4, location: 0..4,
}, },
text: String { label: String {
location: 0..4, location: 0..4,
value: "aiken::todo", value: "aiken::todo",
}, },
arguments: [],
} }

View File

@ -8,7 +8,7 @@ Trace {
then: ErrorTerm { then: ErrorTerm {
location: 0..32, location: 0..32,
}, },
text: Call { label: Call {
arguments: [ arguments: [
CallArg { CallArg {
label: None, label: None,
@ -49,4 +49,5 @@ Trace {
}, },
location: 5..32, location: 5..32,
}, },
arguments: [],
} }

View File

@ -8,8 +8,9 @@ Trace {
then: ErrorTerm { then: ErrorTerm {
location: 0..10, location: 0..10,
}, },
text: String { label: String {
location: 5..10, location: 5..10,
value: "foo", value: "foo",
}, },
arguments: [],
} }

View File

@ -0,0 +1,17 @@
---
source: crates/aiken-lang/src/parser/expr/fail_todo_trace.rs
description: "Code:\n\ntrace \"foo\"\na\n"
---
Trace {
kind: Trace,
location: 0..13,
then: Var {
location: 12..13,
name: "a",
},
label: String {
location: 6..11,
value: "foo",
},
arguments: [],
}

View File

@ -9,7 +9,7 @@ Trace {
location: 34..35, location: 34..35,
name: "a", name: "a",
}, },
text: Call { label: Call {
arguments: [ arguments: [
CallArg { CallArg {
label: None, label: None,
@ -50,4 +50,5 @@ Trace {
}, },
location: 6..33, location: 6..33,
}, },
arguments: [],
} }

View File

@ -1,6 +1,6 @@
--- ---
source: crates/aiken-lang/src/parser/expr/fail_todo_trace.rs source: crates/aiken-lang/src/parser/expr/fail_todo_trace.rs
description: "Code:\n\ntrace some_var \n" description: "Code:\n\ntrace some_var\n"
--- ---
Trace { Trace {
kind: Trace, kind: Trace,
@ -11,13 +11,15 @@ Trace {
then: ErrorTerm { then: ErrorTerm {
location: 0..14, location: 0..14,
}, },
text: String { label: String {
location: 0..14, location: 0..14,
value: "aiken::todo", value: "aiken::todo",
}, },
arguments: [],
}, },
text: Var { label: Var {
location: 6..14, location: 6..14,
name: "some_var", name: "some_var",
}, },
arguments: [],
} }

View File

@ -0,0 +1,30 @@
---
source: crates/aiken-lang/src/parser/expr/fail_todo_trace.rs
description: "Code:\n\ntrace foo: \"bar\"\n"
---
Trace {
kind: Trace,
location: 0..16,
then: Trace {
kind: Todo,
location: 0..16,
then: ErrorTerm {
location: 0..16,
},
label: String {
location: 0..16,
value: "aiken::todo",
},
arguments: [],
},
label: Var {
location: 6..9,
name: "foo",
},
arguments: [
String {
location: 11..16,
value: "bar",
},
],
}

View File

@ -0,0 +1,17 @@
---
source: crates/aiken-lang/src/parser/expr/fail_todo_trace.rs
description: "Code:\n\ntrace @\"foo\"\na\n"
---
Trace {
kind: Trace,
location: 0..14,
then: Var {
location: 13..14,
name: "a",
},
label: String {
location: 6..12,
value: "foo",
},
arguments: [],
}

View File

@ -0,0 +1,34 @@
---
source: crates/aiken-lang/src/parser/expr/fail_todo_trace.rs
description: "Code:\n\ntrace \"foo\": @\"bar\", baz\n"
---
Trace {
kind: Trace,
location: 0..24,
then: Trace {
kind: Todo,
location: 0..24,
then: ErrorTerm {
location: 0..24,
},
label: String {
location: 0..24,
value: "aiken::todo",
},
arguments: [],
},
label: String {
location: 6..11,
value: "foo",
},
arguments: [
String {
location: 13..19,
value: "bar",
},
Var {
location: 21..24,
name: "baz",
},
],
}

View File

@ -32,10 +32,11 @@ When {
then: ErrorTerm { then: ErrorTerm {
location: 28..32, location: 28..32,
}, },
text: String { label: String {
location: 28..32, location: 28..32,
value: "aiken::todo", value: "aiken::todo",
}, },
arguments: [],
}, },
}, },
UntypedClause { UntypedClause {
@ -61,10 +62,11 @@ When {
then: ErrorTerm { then: ErrorTerm {
location: 47..51, location: 47..51,
}, },
text: String { label: String {
location: 47..51, location: 47..51,
value: "aiken::todo", value: "aiken::todo",
}, },
arguments: [],
}, },
}, },
], ],

View File

@ -54,10 +54,11 @@ When {
then: ErrorTerm { then: ErrorTerm {
location: 47..68, location: 47..68,
}, },
text: String { label: String {
location: 52..68, location: 52..68,
value: "unimplemented", value: "unimplemented",
}, },
arguments: [],
}, },
}, },
], ],

View File

@ -985,3 +985,18 @@ fn format_validator_pattern() {
"# "#
); );
} }
#[test]
fn format_variadic_trace() {
assert_format!(
r#"
fn foo() {
trace @"foo": @"bar"
trace "foo": "bar"
trace @"foo": "bar", @"baz"
trace bar: @"baz"
Void
}
"#
);
}

View File

@ -0,0 +1,11 @@
---
source: crates/aiken-lang/src/tests/format.rs
description: "Code:\n\nfn foo() {\n trace @\"foo\": @\"bar\"\n trace \"foo\": \"bar\"\n trace @\"foo\": \"bar\", @\"baz\"\n trace bar: @\"baz\"\n Void\n}\n"
---
fn foo() {
trace @"foo": @"bar"
trace @"foo": @"bar"
trace @"foo": @"bar", @"baz"
trace bar: @"baz"
Void
}

View File

@ -513,12 +513,14 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
self.infer_assignment(pattern, *value, kind, &annotation, location) self.infer_assignment(pattern, *value, kind, &annotation, location)
} }
// TODO: Trace.arguments
UntypedExpr::Trace { UntypedExpr::Trace {
location, location,
then, then,
text, label,
kind, kind,
} => self.infer_trace(kind, *then, location, *text), ..
} => self.infer_trace(kind, *then, location, *label),
UntypedExpr::When { UntypedExpr::When {
location, location,