diff --git a/crates/aiken-lang/src/expr.rs b/crates/aiken-lang/src/expr.rs index 3571a412..bc1505c4 100644 --- a/crates/aiken-lang/src/expr.rs +++ b/crates/aiken-lang/src/expr.rs @@ -548,7 +548,8 @@ pub enum UntypedExpr { kind: TraceKind, location: Span, then: Box, - text: Box, + label: Box, + arguments: Vec, }, TraceIfFalse { @@ -1134,10 +1135,11 @@ impl UntypedExpr { location, kind: TraceKind::Todo, 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, value: DEFAULT_TODO_STR.to_string(), })), + arguments: Vec::new(), } } @@ -1147,7 +1149,8 @@ impl UntypedExpr { location, kind: TraceKind::Error, then: Box::new(UntypedExpr::ErrorTerm { location }), - text: Box::new(reason), + label: Box::new(reason), + arguments: Vec::new(), } } else { UntypedExpr::ErrorTerm { location } diff --git a/crates/aiken-lang/src/format.rs b/crates/aiken-lang/src/format.rs index 4bcded89..debb1d5c 100644 --- a/crates/aiken-lang/src/format.rs +++ b/crates/aiken-lang/src/format.rs @@ -969,8 +969,12 @@ impl<'comments> Formatter<'comments> { } => self.assignment(patterns, value, *kind), UntypedExpr::Trace { - kind, text, then, .. - } => self.trace(kind, text, then), + kind, + label, + then, + arguments, + .. + } => self.trace(kind, label, arguments, then), UntypedExpr::When { subject, clauses, .. @@ -1037,26 +1041,34 @@ impl<'comments> Formatter<'comments> { pub fn trace<'a>( &mut self, kind: &'a TraceKind, - text: &'a UntypedExpr, + label: &'a UntypedExpr, + arguments: &'a [UntypedExpr], then: &'a UntypedExpr, ) -> Document<'a> { - let (keyword, default_text) = match kind { + let (keyword, default_label) = match kind { TraceKind::Trace => ("trace", None), TraceKind::Error => ("fail", Some(DEFAULT_ERROR_STR.to_string())), TraceKind::Todo => ("todo", Some(DEFAULT_TODO_STR.to_string())), }; - let body = match text { - UntypedExpr::String { value, .. } if Some(value) == default_text.as_ref() => { + let mut body = match label { + UntypedExpr::String { value, .. } if Some(value) == default_label.as_ref() => { keyword.to_doc() } _ => keyword .to_doc() .append(" ") - .append(self.wrap_expr(text)) + .append(self.wrap_expr(label)) .group(), }; + for (ix, arg) in arguments.iter().enumerate() { + body = body + .append(if ix == 0 { ": " } else { ", " }) + .append(self.wrap_expr(arg)) + .group(); + } + match kind { TraceKind::Error | TraceKind::Todo => body, TraceKind::Trace => body @@ -1095,7 +1107,6 @@ impl<'comments> Formatter<'comments> { if args.is_empty() && spread_location.is_some() { if is_record { name.append(" { .. }") - // TODO: not possible } else { name.append("(..)") } diff --git a/crates/aiken-lang/src/parser/definition/snapshots/function_empty.snap b/crates/aiken-lang/src/parser/definition/snapshots/function_empty.snap index 036ca2be..4f772cf6 100644 --- a/crates/aiken-lang/src/parser/definition/snapshots/function_empty.snap +++ b/crates/aiken-lang/src/parser/definition/snapshots/function_empty.snap @@ -11,10 +11,11 @@ Fn( then: ErrorTerm { location: 0..15, }, - text: String { + label: String { location: 0..15, value: "aiken::todo", }, + arguments: [], }, doc: None, location: 0..12, diff --git a/crates/aiken-lang/src/parser/definition/snapshots/function_non_public.snap b/crates/aiken-lang/src/parser/definition/snapshots/function_non_public.snap index 2e90a1ed..c46c2045 100644 --- a/crates/aiken-lang/src/parser/definition/snapshots/function_non_public.snap +++ b/crates/aiken-lang/src/parser/definition/snapshots/function_non_public.snap @@ -11,10 +11,11 @@ Fn( then: ErrorTerm { location: 0..11, }, - text: String { + label: String { location: 0..11, value: "aiken::todo", }, + arguments: [], }, doc: None, location: 0..8, diff --git a/crates/aiken-lang/src/parser/expr/fail_todo_trace.rs b/crates/aiken-lang/src/parser/expr/fail_todo_trace.rs index 618daaae..be7c7d34 100644 --- a/crates/aiken-lang/src/parser/expr/fail_todo_trace.rs +++ b/crates/aiken-lang/src/parser/expr/fail_todo_trace.rs @@ -28,13 +28,25 @@ pub fn parser<'a>( .map_with_span(UntypedExpr::fail), just(Token::Trace) .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()) - .map_with_span(|(text, then_), span| UntypedExpr::Trace { - kind: TraceKind::Trace, - location: span, - then: Box::new(then_.unwrap_or_else(|| UntypedExpr::todo(None, span))), - text: Box::new(text), - }), + .map_with_span( + |((label, arguments), continuation), span| UntypedExpr::Trace { + kind: TraceKind::Trace, + location: span, + 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] fn trace_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 + "# + ); + } } diff --git a/crates/aiken-lang/src/parser/expr/snapshots/error_basic.snap b/crates/aiken-lang/src/parser/expr/snapshots/error_basic.snap index 2a1d8c0d..75fca4bd 100644 --- a/crates/aiken-lang/src/parser/expr/snapshots/error_basic.snap +++ b/crates/aiken-lang/src/parser/expr/snapshots/error_basic.snap @@ -8,8 +8,9 @@ Trace { then: ErrorTerm { location: 0..11, }, - text: String { + label: String { location: 5..11, value: "foo", }, + arguments: [], } diff --git a/crates/aiken-lang/src/parser/expr/snapshots/error_sugar.snap b/crates/aiken-lang/src/parser/expr/snapshots/error_sugar.snap index 1cb7d47e..c106702a 100644 --- a/crates/aiken-lang/src/parser/expr/snapshots/error_sugar.snap +++ b/crates/aiken-lang/src/parser/expr/snapshots/error_sugar.snap @@ -8,8 +8,9 @@ Trace { then: ErrorTerm { location: 0..10, }, - text: String { + label: String { location: 5..10, value: "foo", }, + arguments: [], } diff --git a/crates/aiken-lang/src/parser/expr/snapshots/fail_expr.snap b/crates/aiken-lang/src/parser/expr/snapshots/fail_expr.snap index 2e7d8190..64277982 100644 --- a/crates/aiken-lang/src/parser/expr/snapshots/fail_expr.snap +++ b/crates/aiken-lang/src/parser/expr/snapshots/fail_expr.snap @@ -8,7 +8,7 @@ Trace { then: ErrorTerm { location: 0..67, }, - text: Call { + label: Call { arguments: [ CallArg { label: None, @@ -51,4 +51,5 @@ Trace { }, location: 5..67, }, + arguments: [], } diff --git a/crates/aiken-lang/src/parser/expr/snapshots/if_soft_cast_discard_assign.snap b/crates/aiken-lang/src/parser/expr/snapshots/if_soft_cast_discard_assign.snap index aab73ee8..a4f0bdad 100644 --- a/crates/aiken-lang/src/parser/expr/snapshots/if_soft_cast_discard_assign.snap +++ b/crates/aiken-lang/src/parser/expr/snapshots/if_soft_cast_discard_assign.snap @@ -20,10 +20,11 @@ If { then: ErrorTerm { location: 20..24, }, - text: String { + label: String { location: 20..24, value: "aiken::todo", }, + arguments: [], }, is: Some( AssignmentPattern { @@ -51,9 +52,10 @@ If { then: ErrorTerm { location: 36..40, }, - text: String { + label: String { location: 36..40, value: "aiken::todo", }, + arguments: [], }, } diff --git a/crates/aiken-lang/src/parser/expr/snapshots/if_soft_cast_not_var_condition.snap b/crates/aiken-lang/src/parser/expr/snapshots/if_soft_cast_not_var_condition.snap index e8fd4f35..0bd080ce 100644 --- a/crates/aiken-lang/src/parser/expr/snapshots/if_soft_cast_not_var_condition.snap +++ b/crates/aiken-lang/src/parser/expr/snapshots/if_soft_cast_not_var_condition.snap @@ -20,10 +20,11 @@ If { then: ErrorTerm { location: 31..35, }, - text: String { + label: String { location: 31..35, value: "aiken::todo", }, + arguments: [], }, is: Some( AssignmentPattern { @@ -68,9 +69,10 @@ If { then: ErrorTerm { location: 47..51, }, - text: String { + label: String { location: 47..51, value: "aiken::todo", }, + arguments: [], }, } diff --git a/crates/aiken-lang/src/parser/expr/snapshots/todo_basic.snap b/crates/aiken-lang/src/parser/expr/snapshots/todo_basic.snap index 9470a1a8..4b5a651e 100644 --- a/crates/aiken-lang/src/parser/expr/snapshots/todo_basic.snap +++ b/crates/aiken-lang/src/parser/expr/snapshots/todo_basic.snap @@ -8,8 +8,9 @@ Trace { then: ErrorTerm { location: 0..11, }, - text: String { + label: String { location: 5..11, value: "foo", }, + arguments: [], } diff --git a/crates/aiken-lang/src/parser/expr/snapshots/todo_empty.snap b/crates/aiken-lang/src/parser/expr/snapshots/todo_empty.snap index bc1fc0d1..16d45e79 100644 --- a/crates/aiken-lang/src/parser/expr/snapshots/todo_empty.snap +++ b/crates/aiken-lang/src/parser/expr/snapshots/todo_empty.snap @@ -8,8 +8,9 @@ Trace { then: ErrorTerm { location: 0..4, }, - text: String { + label: String { location: 0..4, value: "aiken::todo", }, + arguments: [], } diff --git a/crates/aiken-lang/src/parser/expr/snapshots/todo_expr.snap b/crates/aiken-lang/src/parser/expr/snapshots/todo_expr.snap index 9767c66a..3dd7a245 100644 --- a/crates/aiken-lang/src/parser/expr/snapshots/todo_expr.snap +++ b/crates/aiken-lang/src/parser/expr/snapshots/todo_expr.snap @@ -8,7 +8,7 @@ Trace { then: ErrorTerm { location: 0..32, }, - text: Call { + label: Call { arguments: [ CallArg { label: None, @@ -49,4 +49,5 @@ Trace { }, location: 5..32, }, + arguments: [], } diff --git a/crates/aiken-lang/src/parser/expr/snapshots/todo_sugar.snap b/crates/aiken-lang/src/parser/expr/snapshots/todo_sugar.snap index 6e9bf4c0..ff88606c 100644 --- a/crates/aiken-lang/src/parser/expr/snapshots/todo_sugar.snap +++ b/crates/aiken-lang/src/parser/expr/snapshots/todo_sugar.snap @@ -8,8 +8,9 @@ Trace { then: ErrorTerm { location: 0..10, }, - text: String { + label: String { location: 5..10, value: "foo", }, + arguments: [], } diff --git a/crates/aiken-lang/src/parser/expr/snapshots/trace_bytearray.snap b/crates/aiken-lang/src/parser/expr/snapshots/trace_bytearray.snap new file mode 100644 index 00000000..63c4af22 --- /dev/null +++ b/crates/aiken-lang/src/parser/expr/snapshots/trace_bytearray.snap @@ -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: [], +} diff --git a/crates/aiken-lang/src/parser/expr/snapshots/trace_expr.snap b/crates/aiken-lang/src/parser/expr/snapshots/trace_expr.snap index 783fa6e1..b64f649e 100644 --- a/crates/aiken-lang/src/parser/expr/snapshots/trace_expr.snap +++ b/crates/aiken-lang/src/parser/expr/snapshots/trace_expr.snap @@ -9,7 +9,7 @@ Trace { location: 34..35, name: "a", }, - text: Call { + label: Call { arguments: [ CallArg { label: None, @@ -50,4 +50,5 @@ Trace { }, location: 6..33, }, + arguments: [], } diff --git a/crates/aiken-lang/src/parser/expr/snapshots/trace_expr_todo.snap b/crates/aiken-lang/src/parser/expr/snapshots/trace_expr_todo.snap index c0ecd7ac..ae65d4df 100644 --- a/crates/aiken-lang/src/parser/expr/snapshots/trace_expr_todo.snap +++ b/crates/aiken-lang/src/parser/expr/snapshots/trace_expr_todo.snap @@ -1,6 +1,6 @@ --- 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 { kind: Trace, @@ -11,13 +11,15 @@ Trace { then: ErrorTerm { location: 0..14, }, - text: String { + label: String { location: 0..14, value: "aiken::todo", }, + arguments: [], }, - text: Var { + label: Var { location: 6..14, name: "some_var", }, + arguments: [], } diff --git a/crates/aiken-lang/src/parser/expr/snapshots/trace_labelled.snap b/crates/aiken-lang/src/parser/expr/snapshots/trace_labelled.snap new file mode 100644 index 00000000..3af8fa07 --- /dev/null +++ b/crates/aiken-lang/src/parser/expr/snapshots/trace_labelled.snap @@ -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", + }, + ], +} diff --git a/crates/aiken-lang/src/parser/expr/snapshots/trace_string.snap b/crates/aiken-lang/src/parser/expr/snapshots/trace_string.snap new file mode 100644 index 00000000..44459623 --- /dev/null +++ b/crates/aiken-lang/src/parser/expr/snapshots/trace_string.snap @@ -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: [], +} diff --git a/crates/aiken-lang/src/parser/expr/snapshots/trace_variadic.snap b/crates/aiken-lang/src/parser/expr/snapshots/trace_variadic.snap new file mode 100644 index 00000000..71ee7150 --- /dev/null +++ b/crates/aiken-lang/src/parser/expr/snapshots/trace_variadic.snap @@ -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", + }, + ], +} diff --git a/crates/aiken-lang/src/parser/expr/when/snapshots/when_clause_double_todo.snap b/crates/aiken-lang/src/parser/expr/when/snapshots/when_clause_double_todo.snap index 18642888..7fe8c880 100644 --- a/crates/aiken-lang/src/parser/expr/when/snapshots/when_clause_double_todo.snap +++ b/crates/aiken-lang/src/parser/expr/when/snapshots/when_clause_double_todo.snap @@ -32,10 +32,11 @@ When { then: ErrorTerm { location: 28..32, }, - text: String { + label: String { location: 28..32, value: "aiken::todo", }, + arguments: [], }, }, UntypedClause { @@ -61,10 +62,11 @@ When { then: ErrorTerm { location: 47..51, }, - text: String { + label: String { location: 47..51, value: "aiken::todo", }, + arguments: [], }, }, ], diff --git a/crates/aiken-lang/src/parser/expr/when/snapshots/when_clause_todo.snap b/crates/aiken-lang/src/parser/expr/when/snapshots/when_clause_todo.snap index bd0197bc..a437e880 100644 --- a/crates/aiken-lang/src/parser/expr/when/snapshots/when_clause_todo.snap +++ b/crates/aiken-lang/src/parser/expr/when/snapshots/when_clause_todo.snap @@ -54,10 +54,11 @@ When { then: ErrorTerm { location: 47..68, }, - text: String { + label: String { location: 52..68, value: "unimplemented", }, + arguments: [], }, }, ], diff --git a/crates/aiken-lang/src/tests/format.rs b/crates/aiken-lang/src/tests/format.rs index 5fed0458..ae567e67 100644 --- a/crates/aiken-lang/src/tests/format.rs +++ b/crates/aiken-lang/src/tests/format.rs @@ -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 + } + "# + ); +} diff --git a/crates/aiken-lang/src/tests/snapshots/format_variadic_trace.snap b/crates/aiken-lang/src/tests/snapshots/format_variadic_trace.snap new file mode 100644 index 00000000..6d902e24 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/format_variadic_trace.snap @@ -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 +} diff --git a/crates/aiken-lang/src/tipo/expr.rs b/crates/aiken-lang/src/tipo/expr.rs index 102afa14..1480974d 100644 --- a/crates/aiken-lang/src/tipo/expr.rs +++ b/crates/aiken-lang/src/tipo/expr.rs @@ -513,12 +513,14 @@ impl<'a, 'b> ExprTyper<'a, 'b> { self.infer_assignment(pattern, *value, kind, &annotation, location) } + // TODO: Trace.arguments UntypedExpr::Trace { location, then, - text, + label, kind, - } => self.infer_trace(kind, *then, location, *text), + .. + } => self.infer_trace(kind, *then, location, *label), UntypedExpr::When { location,