Skip to content

Commit

Permalink
Merge branch 'main' into binary-eexp
Browse files Browse the repository at this point in the history
  • Loading branch information
popematt authored Nov 27, 2024
2 parents 805caac + 056cb4e commit 9fa7812
Show file tree
Hide file tree
Showing 13 changed files with 324 additions and 71 deletions.
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
* `demos/` – contains demonstrations of interesting and/or useful strategies

> [!WARNING]
> This test suite and its DSL are **Work In Progress**.
Expand Down
35 changes: 35 additions & 0 deletions conformance/demos/metaprogramming.ion
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

(ion_1_1 "a macro that can create a monomorphized variant of the values macro"
(mactab (macro tiny_decimal (int8::a int8::b) (.make_decimal a b))
(macro tagless_values (mod_or_type type?)
(macro
// Macro name
(.$ion::make_symbol (.. (%mod_or_type) (.$ion::if_some (%type) "_") (%type) "_values"))
// Signature
((.$ion::annotate (.. (%mod_or_type) (%type)) vals) *)
// Body
((.$ion::values %) vals))
))
(then "for a built-in encoding type"
(toplevel ('#$:$ion::add_macros' ('#$:tagless_values' uint8)))
(then "when invoked in Ion text"
(text "(:uint8_values 1 2 3 4 5)")
(produces 1 2 3 4 5))
(then "when invoked in Ion binary"
// Invoke our new "uint8_values" macro
(binary "02 02 0B 01 02 03 04 05")
(produces 1 2 3 4 5)))
(then "for a macro-shape"
(toplevel ('#$:$ion::add_macros' ('#$:tagless_values' tiny_decimal)))
// TODO: Add case demoing binary
(then "when invoked in Ion text"
(text "(:tiny_decimal_values (1 2) (3 4))")
(produces 1d2 3d4)))
(then "for a qualified type name"
(toplevel ('#$:$ion::add_macros' ('#$:tagless_values' $ion make_decimal)))
// TODO: Add case demoing binary
(then "when invoked in Ion text"
(text "(:$ion_make_decimal_values (1 2) (3 4))")
(produces 1d2 3d4))))
2 changes: 1 addition & 1 deletion conformance/grammar.isl
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ type::{
type::{
name: model_annot,
ordered_elements: [
{ valid_values: [Annot, "Annot"] },
{ valid_values: [annot, "annot"] },
model_content,
{ type: model_symtok, occurs: range::[0, max] }
]
Expand Down
2 changes: 1 addition & 1 deletion conformance/local_symtab_imports.ion
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
(signals "No exact-match for empty@2")))


(ion_1_0 "When max_id is valid, pad/truncade mismatched or absent SSTs"
(ion_1_0 "When max_id is valid, pad/truncate mismatched or absent SSTs"
(then (toplevel $ion_symbol_table::{imports:[{name:"absent", max_id:0}, {name:"abcs"}]}
'#$10')
(produces a))
Expand Down
98 changes: 92 additions & 6 deletions conformance/system_macros/annotate.ion
Original file line number Diff line number Diff line change
@@ -1,9 +1,95 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

// Test Cases:
// annotate can be invoked using any type of macro reference.
// annotate adds annotations to a value
// if the value has existing annotations, they are preserved and annotate prepends annotations to the existing annotations of the value
// the first argument must be zero or more non-null text values ($0 is allowed)
// the second argument must be a single expression that also expands to a single expression
(ion_1_1 "annotate can be invoked"
(each "in text with an unqualified macro name"
(text " (:annotate (::) 0) ")
"in text with an unqualified macro address"
(text " (:2 (::) 0) ")
"in text with a qualified macro name"
(text " (:$ion::annotate (::) 0) ")
"in text using qualified system macro address 2"
(text " (:$ion::2 (::) 0) ")
"in binary using system macro address 2"
(binary "EF 02 00 60")
"in binary with a user macro address"
(binary "02 00 60")
(produces 0)))

(ion_1_1 "annotate can add"
(each "0 annotations"
(text " (:annotate (::) a::b::c::d::e::0) ")
"1 annotations"
(text " (:annotate (:: a) b::c::d::e::0) ")
"2 annotations"
(text " (:annotate (:: a b) c::d::e::0) ")
"3 annotations"
(text " (:annotate (:: a b c) d::e::0) ")
"4 annotations"
(text " (:annotate (:: a b c d) e::0) ")
"5 annotations"
(text " (:annotate (:: a b c d e) 0) ")
(produces a::b::c::d::e::0)))

(ion_1_1 "annotate can add annotations to"
(then "null" (text "(:annotate (:: a) null )") (produces a::null))
(then "bool" (text "(:annotate (:: a) true )") (produces a::true))
(then "int" (text "(:annotate (:: a) 2 )") (produces a::2))
(then "float" (text "(:annotate (:: a) 3e0 )") (produces a::3e0))
(then "decimal" (text "(:annotate (:: a) 4d0 )") (produces a::4d0))
(then "timestamp" (text "(:annotate (:: a) 2024T )") (produces a::2024T))
(then "string" (text "(:annotate (:: a) '''abc''' )") (produces a::"abc"))
(then "symbol" (text "(:annotate (:: a) abc )") (produces a::abc))
(then "clob" (text "(:annotate (:: a) {{'''abc'''}} )") (produces a::{{"abc"}}))
(then "blob" (text "(:annotate (:: a) {{+AB/}} )") (produces a::{{ +AB/ }}))
(then "list" (text "(:annotate (:: a) [0, 1, 2] )") (produces a::[0, 1, 2]))
(then "sexp" (text "(:annotate (:: a) (0 1 2) )") (produces a::(0 1 2)))
(then "struct" (text "(:annotate (:: a) {a:1} )") (produces a::{a:1}))
(then "the result of an e-expression"
(text " (:annotate (:: a) (:values 123))")
(produces a::123))
(then "the result of a tdl macro invocation"
(mactab (macro foo () (.annotate (.. "a") (.values "b"))))
(text "(:foo)")
(produces a::"b"))
(then "the value of a tdl variable"
(mactab (macro foo (x) (.annotate (.. "a") (%x))))
(text "(:foo 10)")
(produces a::10)))

(ion_1_1 "the value to annotate cannot be"
(each "nothing"
(text "(:text (:: a) (:values))")
"more than one value"
(text "(:text (:: a) (:values 1 2))")
(signals "invalid argument")))

(ion_1_1 "the annotations argument"
(then "may be"
(then "an empty expression group"
(text "(:annotate (::) 0)")
(produces 0))
(then "a symbol with unknown text"
(text "(:annotate (:: $0) true)")
// Could be (produces $0::true), but some implementations don't support $0 nicely.
(denotes (annot true 0)))
(each "a string"
(text "(:annotate (:: '''a''') 0)")
"a symbol"
(text "(:annotate (:: 'a') 0)")
"an expression that produces a text value"
(text "(:annotate (:: (:values a)) 0)")
(produces a::0))
(each "an expression group with multiple text values"
(text "(:annotate (:: a b) 0)")
"an expression that produces multiple text values"
(text "(:annotate (:: (:values a b)) 0)")
(produces a::b::0)))
(then "may not be"
(each "any null"
(text "(:annotate (:: null) 0)")
(text "(:annotate (:: null.string) 0)")
(text "(:annotate (:: null.symbol) 0)")
"a non-text value"
(text "(:annotate (:: 1) 0)")
(signals "invalid argument"))))
8 changes: 4 additions & 4 deletions conformance/system_macros/delta.ion
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@
(text "(:delta (::))")
(produces))
(each "1 argument"
(binary "EF 12 01 03")
(binary "EF 12 01 61 01")
(text "(:delta 1)")
(produces 1))
(each "2 arguments"
(binary "EF 12 02 05 03 05 01")
(binary "EF 12 02 09 61 01 61 02")
(text "(:delta 1 2)")
(produces 1 3))
(each "3 arguments"
(binary "EF 12 02 07 FF FF FF 01")
(binary "EF 12 02 0D 61 FF 61 FF 61 FF")
(text "(:delta -1 -1 -1)")
(produces -1 -2 -3))
(each "4 arguments"
(binary "EF 12 02 09 03 03 03 03 01")
(binary "EF 12 02 11 61 01 61 01 61 01 61 01")
(text "(:delta 1 1 1 1)")
(text "(:delta (:repeat 4 1))")
(produces 1 2 3 4))
Expand Down
64 changes: 59 additions & 5 deletions conformance/system_macros/flatten.ion
Original file line number Diff line number Diff line change
@@ -1,8 +1,62 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

// Test Cases:
// flatten can be invoked using any type of macro reference.
// the argument values may be zero or more non-null lists and s-expressions
// flatten expands to a stream whose elements are the concatenated elements of all its arguments
// annotations on the argument (list and sexp) values are silently dropped
(ion_1_1 "flatten can be invoked"
(each "in text with an unqualified macro name"
(text " (:flatten (::)) ")
"in text with an unqualified macro address"
(text " (:19 (::)) ")
"in text with a qualified macro name"
(text " (:$ion::flatten (::)) ")
"in text using qualified system macro address 19"
(text " (:$ion::19 (::)) ")
"in binary using system macro address 19"
(binary "EF 13 00")
"in binary with a user macro address"
(binary "13 00")
(produces /*nothing*/)))

(ion_1_1 "flatten creates a flat sequence of values from"
(then "0 values"
(text "(:flatten)")
(produces /*nothing*/))
(each "one list"
(text "(:flatten [1, 2, 3])")
"multiple lists"
(text "(:flatten [1, 2] [3])")
(text "(:flatten [1] [2] [3])")
(text "(:flatten [] [1, 2, 3] [])")
(text "(:flatten [] [1] [] [2] [] [3] [])")
"one sexp"
(text "(:flatten (1 2 3))")
"multiple sexps"
(text "(:flatten (1 2) (3))")
(text "(:flatten (1) (2) (3))")
(text "(:flatten () (1 2 3) ())")
(text "(:flatten () (1) () (2) () (3) ())")
"a mix of lists and sexps"
(text "(:flatten () [1] (2) [3])")
(text "(:flatten (1) [2, 3] ())")
"annotated sequence values"
// Argument annotations are silently dropped.
(text "(:flatten a::() b::[1] c::(2) d::[3])")
(produces 1 2 3)))

(ion_1_1 "the argument cannot be"
(each "null"
(text "(:flatten null)")
(text "(:flatten (1) null (2))")
"null.list"
(text "(:flatten null.list)")
(text "(:flatten (1) null.list (2))")
"null.sexp"
(text "(:flatten null.sexp)")
(text "(:flatten (1) null.sexp (2))")
"a non-sequence value"
(text "(:flatten {{ '''abc''' }})")
(text "(:flatten (1) {{ '''abc''' }} (2))")
(text "(:flatten 123)")
(text "(:flatten (1) 123 (2))")
(text "(:flatten { a: 1 })")
(text "(:flatten (1) { a: 1 } (2))")
(signals "invalid argument")))
17 changes: 9 additions & 8 deletions conformance/system_macros/make_decimal.ion
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,12 @@
(text " (:make_decimal 0 (:: 1 2)) ")
(signals "invalid argument")))

(ion_1_1 "in binary both arguments are encoded as flex_int"
(then (binary "EF 06 01 01 ") (produces 0d0))
(then (binary "EF 06 03 03 ") (produces 1d1))
(then (binary "EF 06 06 00 06 00") (produces 1d1))
(then (binary "EF 06 9E F4 01 ") (produces -729d0))
(then (binary "EF 06 01 9E F4") (produces 0d-729))
(then (binary "EF 06 FF FF ") (produces -1d-1))
(then (binary "EF 06 FE FF FE FF") (produces -1d-1)))
(ion_1_1 "in binary both arguments are encoded as tagged values"
(then (binary "EF 06 60 60 ") (produces 0d0))
(then (binary "EF 06 61 01 61 01") (produces 1d1))
(then (binary "EF 06 61 FF 61 01") (produces -1d1))
(then (binary "EF 06 61 01 61 FF") (produces 1d-1))
(then (binary "EF 06 61 FF 61 FF") (produces -1d-1)))

(ion_1_1 "make_decimal creates a single unannotated decimal"
(then (text "(:make_decimal -3 1)") (produces -3d1))
Expand All @@ -60,5 +58,8 @@
(then (text "(:make_decimal 2 1)") (produces 2d1))
(then (text "(:make_decimal 2 2)") (produces 2d2))
(then (text "(:make_decimal 2 3)") (produces 2d3))
// Arguments can be e-expressions
(then (text "(:make_decimal (:values 2) 3)") (produces 2d3))
(then (text "(:make_decimal 2 (:values 3))") (produces 2d3))
// Argument annotations are silently dropped.
(then (text "(:make_decimal a::3 b::3)") (produces 3d3)))
4 changes: 2 additions & 2 deletions conformance/system_macros/make_field.ion
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"in text using qualified system macro address 22"
(text " (:$ion::22 foo 0) ")
"in binary using system macro address 22"
(binary "EF 16 FB 66 6F 6F 60")
(binary "EF 16 A3 66 6F 6F 60")
"in binary with a user macro address"
(binary "16 FB 66 6F 6F 60")
(binary "16 A3 66 6F 6F 60")
(produces {foo: 0} )))

(ion_1_1 "the first argument"
Expand Down
Loading

0 comments on commit 9fa7812

Please sign in to comment.