-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathstack_template.f90.erb
165 lines (125 loc) · 4.21 KB
/
stack_template.f90.erb
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<%
def parse_line(l)
args = l.chomp.split("\t")
raise unless args.size == 5
use_stmt, suffix, data_in_decl, data_out_decl, scalar = args
{
use_stmt: use_stmt.gsub(';', "\n"),
suffix: suffix,
data_in_decl: data_in_decl,
data_out_decl: data_out_decl,
scalar: scalar == 'true',
}
end
module_name = $stdin.gets.chomp
params = $stdin.readlines.map{|l| parse_line(l)}
%>
module <%= module_name %>
use, intrinsic:: iso_fortran_env, only: int64
<% params.each{|param| %>
<%= param[:use_stmt] %>
<% } %>
implicit none
private
public:: add
public:: pop
public:: size
<% if params.map{|p| p[:scalar]}.any? %>
public:: array_of
<% end %>
<% params.each{|param| %>
<% suffix = param[:suffix] %>
type:: StackNode<%= suffix %>
type(StackNode<%= suffix %>), pointer:: prev => null()
<%= param[:data_out_decl] %>:: data
end type StackNode<%= suffix %>
type, public:: Stack<%= suffix %>
type(StackNode<%= suffix %>), pointer:: root => null()
contains
final:: finalize<%= suffix %>
end type Stack<%= suffix %>
interface add
module procedure add<%= suffix %>
end interface add
interface pop
module procedure pop1<%= suffix %>
module procedure pop2<%= suffix %>
end interface pop
interface size
module procedure size<%= suffix %>
end interface size
<% if param[:scalar] %>
interface array_of
module procedure array_of<%= suffix %>
end interface array_of
<% end %>
<% } %>
contains
<% params.each{|param| %>
<% suffix = param[:suffix] %>
<% data_in_decl = param[:data_in_decl] %>
<% data_out_decl = param[:data_out_decl] %>
pure subroutine add<%= suffix %>(self, data)
type(Stack<%= suffix %>), intent(inout):: self
<%= data_in_decl %>, intent(in):: data
type(StackNode<%= suffix %>), pointer:: node
allocate(node)
node%data = data
node%prev => self%root
self%root => node
end subroutine add<%= suffix %>
function pop1<%= suffix %>(self) result(data)
<%= data_out_decl %>:: data
type(Stack<%= suffix %>), intent(inout):: self
Logical:: found
found = pop(self, data)
end function pop1<%= suffix %>
function pop2<%= suffix %>(self, data) result(found)
Logical:: found
type(Stack<%= suffix %>), intent(inout):: self
<%= data_out_decl %>, intent(out):: data
type(StackNode<%= suffix %>), pointer:: tmp
found = associated(self%root)
if(found)then
data = self%root%data
tmp => self%root
self%root => self%root%prev
deallocate(tmp)
end if
end function pop2<%= suffix %>
impure elemental function size<%= suffix %>(self) result(ret)
Integer(kind=int64):: ret
type(Stack<%= suffix %>), intent(in):: self
type(StackNode<%= suffix %>), pointer:: tmp
ret = 0
tmp => self%root
do while(associated(tmp))
tmp => tmp%prev
ret = ret + 1
end do
end function size<%= suffix %>
<% if param[:scalar] %>
function array_of<%= suffix %>(self) result(ret)
type(Stack<%= suffix %>), intent(in):: self
<%= data_out_decl %>:: ret(size(self))
type(StackNode<%= suffix %>), pointer:: tmp
Integer(kind=int64):: i
tmp => self%root
do i = 1, size(ret, kind=kind(i))
ret(i) = tmp%data
tmp => tmp%prev
end do
end function array_of<%= suffix %>
<% end %>
impure elemental subroutine finalize<%= suffix %>(self)
type(Stack<%= suffix %>), intent(inout):: self
type(StackNode<%= suffix %>), pointer:: current, prev
current => self%root
do while(associated(current))
prev => current%prev
deallocate(current)
current => prev
end do
end subroutine finalize<%= suffix %>
<% } %>
end module <%= module_name %>