forked from alex-eg/sex
fix (. (* p) x) expanding to *(p).x
Was an fmt-c-writer bug: unary-op must parenthize itself, and not it's arg
This commit is contained in:
@@ -325,4 +325,24 @@ compiles."
|
||||
(test-assert "a closure passed as an argument stays a value"
|
||||
(emits? "(fn g ((c (closure ((int)) int))) int (return 0))
|
||||
(fn f ((c (closure ((int)) int))) int (return (g c)))"
|
||||
"g(c)"))))
|
||||
"g(c)")))
|
||||
|
||||
;; A unary expression parenthesised its operand rather than itself, so
|
||||
;; the parens landed inside: `*(p).x', which C reads as `*(p.x)'.
|
||||
(test-group "unary operand precedence"
|
||||
(test-assert "member access through a dereference"
|
||||
(emits? "(struct pt ((x int))) (fn f ((p (* (struct pt)))) int (return (. (* p) x)))"
|
||||
"(*p).x"))
|
||||
(test-assert "and not with the parens inside"
|
||||
(not (emits? "(struct pt ((x int))) (fn f ((p (* (struct pt)))) int (return (. (* p) x)))"
|
||||
"*(p).x")))
|
||||
(test-assert "member access through a cast"
|
||||
(emits? (in-fn "(var n int (. (* (cast a (* (struct s)))) f))")
|
||||
"(*(struct s*)a).f"))
|
||||
;; ...without gaining parens where none are due
|
||||
(test-assert "a bare dereference is left alone"
|
||||
(emits? (in-fn "(var p (* int) 0) (= a (* p))") "a = *p"))
|
||||
(test-assert "so is address-of in an argument"
|
||||
(emits? (in-fn "(g (& a))") "g(&a)"))
|
||||
(test-assert "and negation beside a binary operator"
|
||||
(emits? (in-fn "(var n int (+ (- a) b))") "-a + b"))))
|
||||
|
||||
Reference in New Issue
Block a user