Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds initial TDL test cases #148

Merged
merged 3 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions conformance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ declarative domain-specific language.
* `ion_encoding/` – test cases for encoding directives
* `module/`
* `system_macros/` – test cases for each of the system macros
* `tdl/` – test cases for the template definition language and special forms
* `demos/` – contains demonstrations of interesting and/or useful strategies

> [!WARNING]
Expand Down
4 changes: 4 additions & 0 deletions conformance/tdl/data_model_values.ion
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

// Test each type of data model value in a template body.
54 changes: 54 additions & 0 deletions conformance/tdl/expression_groups.ion
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

(ion_1_1 "expression groups may not"
(each "have an annotation on the s-expression"
(mactab (macro foo () (.values foo::(.. 1 2))))
"have an annotation on the '..' operator"
(mactab (macro foo () (.values (foo::'..' 1 2))))
"contain another expression group"
(mactab (macro foo () (.values (.. (..)))))
(mactab (macro foo () (.values (.. 1 (..) 2))))
(mactab (macro foo () (.values (.. (.. 1) 2))))
(mactab (macro foo () (.values (.. 1 (.. 2)))))
(mactab (macro foo () (.values (.. (.. 1 2)))))
"be used as rest arguments"
// ...you can have rest arguments or an expression group, but not both.
(mactab (macro foo () (.values (.. 1) (.. 2))))
"be the template body expression"
(mactab (macro foo () (..)))
(mactab (macro foo () (.. 1)))
"occur in a list"
(mactab (macro foo () [(..)]))
(mactab (macro foo () [(.. 1)]))
(mactab (macro foo () [0, (..), 2]))
(mactab (macro foo () [0, (.. 1), 2]))
"occur in a sexp"
(mactab (macro foo () ( (..) ) ))
(mactab (macro foo () (0 (..) 2) ))
(mactab (macro foo () ( (.. 1) ) ))
(mactab (macro foo () (0 (.. 1) 1) ))
"occur in a struct"
(mactab (macro foo () { a: (..) } ))
(mactab (macro foo () { a: 1, b: (..), c: 2 } ))
(mactab (macro foo () { a: (.. 1) } ))
(mactab (macro foo () { a: 0, b: (.. 1), c:2 } ))
(signals "invalid macro definition")))

(ion_1_1 "expression groups"
(then "may be empty"
(mactab (macro foo () (.values (..))))
(toplevel 0 ('#$:foo') 1)
(produces 0 1))
(then "may contain one value"
(mactab (macro foo () (.values (.. 2))))
(toplevel 0 ('#$:foo') 1)
(produces 0 2 1))
(then "may contain many values"
(mactab (macro foo () (.values (.. 2 3))))
(toplevel 0 ('#$:foo') 1)
(produces 0 2 3 1))
(then "may contain macro invocations"
(mactab (macro foo () (.values (.. (.values 2)))))
(toplevel 0 ('#$:foo') 1)
(produces 0 2 1)))
19 changes: 19 additions & 0 deletions conformance/tdl/for.ion
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

// * Test cases for `for`
// * binding names, keywords, etc. cannot be annotated
// * Can iterate one stream
// * Can iterate more than one stream
// * Can iterate empty stream
// * Can iterate non-empty stream
// * Can use grouping syntax for avoiding ambiguity
// * Creates a new binding for the stream iteration
// * Bindings can shadow the macro variables
// * Bindings can shadow an outer `for`
// * Iteration ends when the shorter stream is complete
// * When there's one stream
// * When there's multiple streams, and the first stream is shortest
// * When there's multiple streams, and the second (or later) is the shortest
// * When two streams have the same length
// * `for` should have exactly one template body expression
132 changes: 132 additions & 0 deletions conformance/tdl/if_multi.ion
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

(ion_1_1 "if_multi special form cannot be"
(each "invoked as an unqualified e-expression"
(text "(:if_multi 1 2 3)")
"invoked as a qualified e-expression"
(text "(:$ion::if_multi 1 2 3)")
"exported"
(mactab (export if_multi))
(mactab (export $ion::if_multi))
(signals "no such macro")))

(ion_1_1 "when invoked in TDL,"
// TODO: Can be invoked qualified and unqualified
// Can be shadowed
(each "each argument can be elided because they are optional trailing parameters"
(mactab (macro foo () (.$ion::if_multi)))
(mactab (macro foo () (.$ion::if_multi (..))))
(mactab (macro foo () (.$ion::if_multi (..) 3)))
(then (toplevel 0 ('#$:foo') 1)
(produces 0 1))))

(ion_1_1 "when the first argument is"
(each "an empty expression group"
(mactab (macro is_multi () (.$ion::if_multi (..) true false)))
"a macro that produces nothing"
(mactab (macro is_multi () (.$ion::if_multi (.$ion::none) true false)))
"an expression group with one macro that produces nothing"
(mactab (macro is_multi () (.$ion::if_multi (..(.$ion::none)) true false)))
"an expression group with multiple macros that produce nothing"
(mactab (macro is_multi () (.$ion::if_multi (..(.$ion::none)(.$ion::none)) true false)))
"a single value"
(mactab (macro is_multi () (.$ion::if_multi 0 true false)))
"an expression group with a single value"
(mactab (macro is_multi () (.$ion::if_multi (..0) true false)))
"a macro that produces a single value"
(mactab (macro is_multi () (.$ion::if_multi (.values 0) true false)))
"an expression group with a single macro that produces a single value"
(mactab (macro is_multi () (.$ion::if_multi (.. (.values 0)) true false)))
"an expression group with a multiple macros that collectively produce a single value"
(mactab (macro is_multi () (.$ion::if_multi (.. (.values 0) (.none)) true false)))
(mactab (macro is_multi () (.$ion::if_multi (.. (.none) (.values 0)) true false)))
"an expression group with a single value and a macro produces nothing"
(mactab (macro is_multi () (.$ion::if_multi (.. 0 (.none)) true false)))
(mactab (macro is_multi () (.$ion::if_multi (.. (.none) 0) true false)))
(then "then if_multi should produce the false branch"
(toplevel ('#$:is_multi'))
(produces false)))
(each "an expression group with multiple values"
(mactab (macro is_multi () (.$ion::if_multi (.. 0 1 2) true false)))
"a macro that produces multiple values"
(mactab (macro is_multi () (.$ion::if_multi (.values (.. 0 1 2)) true false)))
"an expression group with a single macro that produces multiple values"
(mactab (macro is_multi () (.$ion::if_multi (..(.values (.. 0 1 2))) true false)))
"an expression group with multiple macros "
(mactab (macro is_multi () (.$ion::if_multi (..(.values 0) (.values 1)) true false)))
"an expression group with multiple values and some macros that produce nothing"
(mactab (macro is_multi () (.$ion::if_multi (.. 0 1 2 (.none)) true false)))
"an expression group with multiple values that starts with a macro that produces nothing"
(mactab (macro is_multi () (.$ion::if_multi (.. (.none) 0 1 2) true false)))
(then "then if_multi should produce the true branch"
(toplevel ('#$:is_multi'))
(produces true))))

(ion_1_1 "when the first argument is multiple values"
(then "the 'true_branch' argument can be"
(each "an empty expression group"
(mactab (macro is_multi () (.$ion::if_multi (.. "two" "things") (..) false)))
"a macro that produces no values"
(mactab (macro is_multi () (.$ion::if_multi (.. "two" "things") (.none) false)))
"an expression group with macros that produces no values"
(mactab (macro is_multi () (.$ion::if_multi (.. "two" "things") (.. (.none) (.none)) false)))
(then (toplevel 1 ('#$:is_multi') 2)
(produces 1 2)))
(each "one value"
(mactab (macro is_multi () (.$ion::if_multi (.. "two" "things") true false)))
"an expression group with one value"
(mactab (macro is_multi () (.$ion::if_multi (.. "two" "things") (.. true) false)))
"a macro that produces one value"
(mactab (macro is_multi () (.$ion::if_multi (.. "two" "things") (.$ion::values true) false)))
(then (toplevel 1 ('#$:is_multi') 2)
(produces 1 true 2)))
(each "an expression group with multiple values"
(mactab (macro is_multi () (.$ion::if_multi (.. "two" "things") (.. true true) false)))
"a macro that produces multiple values"
(mactab (macro is_multi () (.$ion::if_multi (.. "two" "things") (.$ion::values (.. true true)) false)))
(then (toplevel 1 ('#$:is_multi') 2)
(produces 1 true true 2))))
(then "the 'false_branch' argument is not evaluated"
// Note the false branch here must be something that is a RUNTIME evaluation error.
// We use `make_string`, assuming that it is a macro that will be implemented early on.
// We wrap the invalid argument in a `values` invocation so that the test won't cause
// a compilation error if implementations try to have compile time analysis of macro arguments.
(mactab (macro always_true () (.$ion::if_multi (.. "two" "things") true (.$ion::make_string (.$ion::values null)))))
(then (toplevel 1 ('#$:always_true') 2)
(produces 1 true 2))))

(ion_1_1 "when the first argument is none"
(then "the 'false_branch' argument can be"
(each "an empty expression group"
(mactab (macro is_multi () (.$ion::if_multi (..) true (..))))
"a macro that produces no values"
(mactab (macro is_multi () (.$ion::if_multi (..) true (.none))))
"an expression group with macros that produces no values"
(mactab (macro is_multi () (.$ion::if_multi (..) true (.. (.none) (.none)))))
(then (toplevel 1 ('#$:is_multi') 2)
(produces 1 2)))
(each "one value"
(mactab (macro is_multi () (.$ion::if_multi (..) true false)))
"an expression group with one value"
(mactab (macro is_multi () (.$ion::if_multi (..) true (.. false))))
"a macro that produces one value"
(mactab (macro is_multi () (.$ion::if_multi (..) true (.$ion::values false))))
(then (toplevel 1 ('#$:is_multi') 2)
(produces 1 false 2)))
(each "an expression group with multiple values"
(mactab (macro is_multi () (.$ion::if_multi (..) true (.. false false))))
"a macro that produces multiple values"
(mactab (macro is_multi () (.$ion::if_multi (..) true (.$ion::values (.. false false)))))
"multiple values as implicit rest args"
(mactab (macro is_multi () (.$ion::if_multi (..) true false false)))
(then (toplevel 1 ('#$:is_multi') 2)
(produces 1 false false 2))))
(then "the 'true_branch' argument is not evaluated"
// Note the true branch here must be something that is a RUNTIME evaluation error.
// We use `make_string`, assuming that it is a macro that will be implemented early on.
// We wrap the invalid argument in a `values` invocation so that the test won't cause
// a compilation error if implementations try to have compile time analysis of macro arguments.
(mactab (macro always_false () (.$ion::if_multi (..) (.$ion::make_string (.$ion::values null)) false)))
(then (toplevel 1 ('#$:always_false') 2)
(produces 1 false 2))))
Loading
Loading