/
macros.jl
120 lines (104 loc) · 3.19 KB
/
macros.jl
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#
# This file is part of the DiscreteEvents.jl Julia package, MIT license
#
# Hector Perez, Paul Bayer, 2020
#
# This is a Julia package for discrete event simulation
#
"""
@process f(arg...) [cycles]
Create a process from a function `f(arg...)`.
Wrap a function and its arguments in a [`Prc`](@ref) and start it with
[`process!`](@ref).
# Arguments
- `f`: a function,
- `arg...`: arguments, the first argument must be an AbstractClock,
- `cycles::Int`: the number of cycles, `f` should run.
# Returns
- an `Int` process id.
"""
macro process(expr, args...)
expr.head != :call && error("Expression is not a function call.")
f = expr.args[1] #extract function passed
c = expr.args[2] #first function arg must be an AbstractClock
fargs = expr.args[3:end] #extract other function args
p = :(Prc($f, $(fargs...))) #create Prc struct
if isempty(args)
esc(:(process!($c,$p))) #execute process!
else
cycles = args[1] #extract cycle
esc(:(process!($c,$p,$cycles))) #execute process!
end
end
"""
@event f(arg...) T t [n]
Schedule a function `f(arg...)` as an event to a clock.
# Arguments
- `f`: function to be executed at event time,
- `arg...`: its arguments, the first argument must be a clock,
- `T`: a [`Timing`](@ref) (at, after, every),
- `n`: passed as keyword `n` to `event!`.
"""
macro event(expr, args...)
expr.head != :call && error("1st term is not a function call.")
f = expr.args[1] #extract function passed
c = expr.args[2] #first function arg must be an AbstractClock
fargs = expr.args[2:end] #extract other function args
ex = :(fun($f, $(fargs...))) #create Action
if length(args) == 3
esc(:(event!($c, $ex, $(args[1:2]...), n = $(args[3])))) #execute event!
else
esc(:(event!($c, $ex, $(args...)))) #execute event!
end
end
"""
@event f(farg...) c(carg...)
Schedule a function `f(farg...)` as a conditional event to a clock.
# Arguments
- `f`: function to be executed at event time,
- `farg...`: its arguments, the first argument must be a clock,
- `c`: function to be evaluated at the clock's sample rate, if it
returns true, the event is triggered,
- `carg...`: arguments to c.
"""
macro event(expr, cond)
expr.head != :call && error("1st term is not a function call.")
f1 = expr.args[1]
c = expr.args[2]
f1args = expr.args[2:end]
ex1 = :(fun($f1, $(f1args...)))
cond.head != :call && error("2nd term is not a function call.")
f2 = cond.args[1]
f2args = cond.args[2:end]
ex2 = :(fun($f2, $(f2args...)))
esc(:(event!($c, $ex1, $ex2)))
end
"""
```
@delay clk Δt
@delay clk until t
```
Delay a process on a clock `clk` for a time interval `Δt` or until
a time `t`.
"""
macro delay(clk, delay...)
esc(:(delay!($clk, $(delay...))))
end
"""
@wait clk f(arg...)
Conditionally wait on a clock `clk` until `f(arg...)` returns true.
"""
macro wait(clk, expr)
expr.head != :call && error("2nd term is not a function call.")
f = expr.args[1]
fargs = expr.args[2:end]
ex = :(fun($f, $(fargs...)))
esc(:(wait!($clk, $ex)))
end
"""
@run! clk t
Run a clock `clk` for a duration `t`.
"""
macro run!(clk, duration)
esc(:(run!($clk, $duration)))
end