aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/control/function/contract.lux
blob: b36aa75c66354908789c910bfb6a866e6c301347 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
(.using
 [library
  [lux "*"
   [control
    ["[0]" exception {"+" exception:}]
    [parser
     ["<[0]>" code]]]
   [data
    [text
     ["%" format {"+" format}]]]
   [macro {"+" with_symbols}
    [syntax {"+" syntax:}]
    ["[0]" code]]
   [math
    [number
     ["i" int]]]]])

(template [<name>]
  [(exception: .public (<name> [condition Code])
     (exception.report
      "Condition" (%.code condition)))]

  [pre_condition_failed]
  [post_condition_failed]
  )

(def: (assert! message test)
  (-> Text Bit [])
  (if test
    []
    (panic! message)))

(syntax: .public (pre [test <code>.any
                       expr <code>.any])
  (in (list (` (exec
                 ((~! ..assert!) (~ (code.text (exception.error ..pre_condition_failed test)))
                  (~ test))
                 (~ expr))))))

(syntax: .public (post [test <code>.any
                        expr <code>.any])
  (with_symbols [g!output]
    (in (list (` (let [(~ g!output) (~ expr)]
                   (exec
                     ((~! ..assert!) (~ (code.text (exception.error ..post_condition_failed test)))
                      ((~ test) (~ g!output)))
                     (~ g!output))))))))