implement compound and designated literals support
This commit was merged in pull request #38.
This commit is contained in:
@@ -101,6 +101,39 @@
|
||||
'(%var (struct suc *) s (hoge piyo))
|
||||
(walk-var '(var s (* struct suc) (hoge piyo))))
|
||||
|
||||
;;; Initializers and compound literals
|
||||
(test "a bare initializer is unchanged"
|
||||
'#(1 2)
|
||||
(walk-expr '#(1 2)))
|
||||
|
||||
(test "`:' ends the type and makes it a compound literal"
|
||||
'(%compound (struct point) 3 4)
|
||||
(walk-expr '#(struct point : 3 4)))
|
||||
|
||||
(test "the type is bare words, as everywhere else"
|
||||
'(%compound (const char *) 65)
|
||||
(walk-expr '#(* const char : 65)))
|
||||
|
||||
(test "and may be an array type"
|
||||
'(%compound (%array int 3) 10 20 30)
|
||||
(walk-expr '#(¤ int 3 : 10 20 30)))
|
||||
|
||||
(test "a grouped type is unwrapped the way a declaration's is"
|
||||
'(%compound (%array int 3) 10)
|
||||
(walk-expr '#((¤ int 3) : 10)))
|
||||
|
||||
(test "`.field value' is a designated initializer, kebab and all"
|
||||
'(%compound (struct named) (%designate n 7) (%designate first_name "zoe"))
|
||||
(walk-expr '#(struct named : .n 7 .first-name "zoe")))
|
||||
|
||||
(test "positional and designated may be mixed"
|
||||
'(%compound (struct point) 1 (%designate y 5))
|
||||
(walk-expr '#(struct point : 1 .y 5)))
|
||||
|
||||
(test "designators work in an untyped initializer too"
|
||||
'#((%designate y 5))
|
||||
(walk-expr '#(.y 5)))
|
||||
|
||||
;;; Fn defs
|
||||
(test
|
||||
'(%fun void puk ((int) (%array float 8)))
|
||||
|
||||
49
tests/sex-programs/compound-literals.sex
Normal file
49
tests/sex-programs/compound-literals.sex
Normal file
@@ -0,0 +1,49 @@
|
||||
(input)
|
||||
(output "plain 1 2"
|
||||
"literal 3 4"
|
||||
"designated zoe 7"
|
||||
"through a pointer 9"
|
||||
"array 10 20 30"
|
||||
"argument 6"
|
||||
"mixed 1 5")
|
||||
(return 0)
|
||||
|
||||
;;; `:' inside #(...) ends a type and makes the rest a C99 compound
|
||||
;;; literal. Without one, #(...) is the brace initializer it always was.
|
||||
|
||||
(include stdio.h)
|
||||
|
||||
(struct point ((x int) (y int)))
|
||||
(struct named ((first-name (* const char)) (n int)))
|
||||
|
||||
(fn sum ((p (struct point))) int
|
||||
(return (+ (. p x) (. p y))))
|
||||
|
||||
(pub fn main () int
|
||||
;; unchanged: a bare initializer has no type of its own
|
||||
(var p (struct point) #(1 2))
|
||||
(printf "plain %d %d\n" (. p x) (. p y))
|
||||
|
||||
(var q (struct point) #(struct point : 3 4))
|
||||
(printf "literal %d %d\n" (. q x) (. q y))
|
||||
|
||||
;; designated, out of declaration order, and kebab-cased
|
||||
(var r (struct named) #(struct named : .n 7 .first-name "zoe"))
|
||||
(printf "designated %s %d\n" (. r first-name) (. r n))
|
||||
|
||||
;; a compound literal is an lvalue, so its address can be taken --
|
||||
;; until the end of the enclosing block, and no longer
|
||||
(var pp (* struct point) (& #(struct point : 9 9)))
|
||||
(printf "through a pointer %d\n" (-> pp x))
|
||||
|
||||
;; an array literal decays the way an array does
|
||||
(var a (* int) #([int 3] : 10 20 30))
|
||||
(printf "array %d %d %d\n" (¤ a 0) (¤ a 1) (¤ a 2))
|
||||
|
||||
(printf "argument %d\n" (sum #(struct point : 2 4)))
|
||||
|
||||
;; positional and designated may be mixed, as in C
|
||||
(var m (struct point) #(struct point : 1 .y 5))
|
||||
(printf "mixed %d %d\n" (. m x) (. m y))
|
||||
|
||||
(return 0))
|
||||
Reference in New Issue
Block a user