crokus 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/crokus/cfg_printer_c.rb +199 -0
- data/lib/crokus/cfg_random_gen.rb +312 -0
- data/lib/crokus/version.rb +1 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 852a2b5bdf274b42fa37edba80142da8b481cad7203637a5b86ab7a5b83f7b10
|
4
|
+
data.tar.gz: f199ddb9ac49df0c8bb5a456c332677ccb2cbd21baa469d0cee514d400b4ae78
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec54d76cffdfeeb764fcc06463fd67b01b88dd642246496f6d6de07d5462113e3fda0e34af0bf60750552397e14be4d6cd1d36eec0a6fd8d27ed88cdd27ea1f3
|
7
|
+
data.tar.gz: 602f8152c74bda51fde3c991fa969192d3a2c542688650b822158fdcfab654d7ac62cb869b9243d3d512b880c168938d8e9848388cb2f5c097f0c46a853b7502
|
@@ -0,0 +1,199 @@
|
|
1
|
+
module Crokus
|
2
|
+
|
3
|
+
class PrinterC
|
4
|
+
|
5
|
+
attr_accessor :cfg
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@visited=[]
|
9
|
+
@prp=PrettyPrinter.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def print cfg
|
13
|
+
puts " |-->[+] generating C code from cfg '#{cfg.name}'"
|
14
|
+
@cfg=cfg
|
15
|
+
code=Code.new
|
16
|
+
code << "//"+"-"*60
|
17
|
+
code << "// automatically generated by Crokus compiler"
|
18
|
+
code << "// date : #{Time.now.strftime("%a %d,%B %Y - %H:%M:%S")}"
|
19
|
+
code << "//"+"-"*60
|
20
|
+
code.newline
|
21
|
+
code << "#include <stdio.h>"
|
22
|
+
code << "#include <stdlib.h>"
|
23
|
+
code.newline
|
24
|
+
io=[decl_inputs,decl_outputs].join(',')
|
25
|
+
code << "int #{cfg.name}(#{io}){"
|
26
|
+
code.indent=2
|
27
|
+
code << decl_vars()
|
28
|
+
code << decl_loop_indexes()
|
29
|
+
code << decl_arrays()
|
30
|
+
code << visit_rec(cfg.starter)
|
31
|
+
code << output_assigns()
|
32
|
+
code << "return 0;"
|
33
|
+
code.indent=0
|
34
|
+
code << "}"
|
35
|
+
code.newline
|
36
|
+
code << main(cfg)
|
37
|
+
puts code.finalize
|
38
|
+
code.save_as "#{cfg.name}.c"
|
39
|
+
end
|
40
|
+
|
41
|
+
def main cfg
|
42
|
+
code=Code.new
|
43
|
+
code << "int main(void){"
|
44
|
+
code.indent=2
|
45
|
+
inputs,outputs=[],[]
|
46
|
+
cfg.infos["inputs"].each do |input|
|
47
|
+
code << "int #{input} = #{rand 0..255};"
|
48
|
+
inputs << input
|
49
|
+
end
|
50
|
+
cfg.infos["outputs"].each do |output|
|
51
|
+
code << "int #{output};"
|
52
|
+
outputs << "&#{output}"
|
53
|
+
end
|
54
|
+
params=[inputs,outputs].flatten.join(',')
|
55
|
+
code << "#{cfg.name}(#{params});"
|
56
|
+
cfg.infos["outputs"].each do |output|
|
57
|
+
code << "printf(\"#{output} = %d\\n\",#{output});"
|
58
|
+
end
|
59
|
+
code << "return 0;"
|
60
|
+
code.indent=0
|
61
|
+
code << "}"
|
62
|
+
code
|
63
|
+
end
|
64
|
+
|
65
|
+
def decl_inputs
|
66
|
+
if h=cfg.infos["inputs"]
|
67
|
+
return h.map{|ident| "int #{ident}"}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def decl_outputs
|
72
|
+
if h=cfg.infos["outputs"]
|
73
|
+
return h.map{|ident| "int *#{ident}"}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def decl_vars
|
78
|
+
code=Code.new
|
79
|
+
if h=cfg.infos["int_vars"]
|
80
|
+
h.each{|ident| code << "int #{ident} = #{rand(0..255)};"}
|
81
|
+
end
|
82
|
+
code.newline
|
83
|
+
code
|
84
|
+
end
|
85
|
+
|
86
|
+
def decl_loop_indexes
|
87
|
+
code=Code.new
|
88
|
+
if cfg.infos["loop_indexes"]
|
89
|
+
code << "// loop indexes"
|
90
|
+
cfg.infos["loop_indexes"].each do |index|
|
91
|
+
code << "int #{index};"
|
92
|
+
end
|
93
|
+
code.newline
|
94
|
+
end
|
95
|
+
code
|
96
|
+
end
|
97
|
+
|
98
|
+
def decl_arrays
|
99
|
+
code=Code.new
|
100
|
+
cfg.infos["internal_arrays"].each do |h|
|
101
|
+
name,size_lit=h.first
|
102
|
+
size_int=size_lit.to_s.to_i
|
103
|
+
init=Array.new(size_int){rand(255)}.join(",")
|
104
|
+
size=size_lit.accept(@prp)
|
105
|
+
code << "int #{name}[#{size}] ={#{init}};"
|
106
|
+
end
|
107
|
+
code.newline
|
108
|
+
code
|
109
|
+
end
|
110
|
+
|
111
|
+
def output_assigns
|
112
|
+
code=Code.new
|
113
|
+
code.newline
|
114
|
+
code << "//------- output assignments ------"
|
115
|
+
if ary=cfg.infos["output_assigns"]
|
116
|
+
ary.each{|h|
|
117
|
+
out,expr=h.first
|
118
|
+
rhs=expr.accept(@prp)
|
119
|
+
code << "*#{out} = #{rhs};"
|
120
|
+
}
|
121
|
+
end
|
122
|
+
code
|
123
|
+
end
|
124
|
+
|
125
|
+
def visit_rec bb
|
126
|
+
unless bb.nil? or @visited.include?(bb)
|
127
|
+
if bb.infos[:start_if]
|
128
|
+
gen_if(bb)
|
129
|
+
elsif bb.infos[:start_while]
|
130
|
+
gen_while(bb)
|
131
|
+
elsif bb.infos[:start_for]
|
132
|
+
gen_for(bb)
|
133
|
+
else
|
134
|
+
gen_plain(bb)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def gen_plain bb
|
140
|
+
code=Code.new
|
141
|
+
@visited << bb
|
142
|
+
#code << "// bb #{bb.label}"
|
143
|
+
bb.stmts.each{|assign|
|
144
|
+
code << assign.accept(@prp)
|
145
|
+
}
|
146
|
+
code << visit_rec(bb.nextBranch)
|
147
|
+
code
|
148
|
+
end
|
149
|
+
|
150
|
+
def gen_if bb
|
151
|
+
code=Code.new
|
152
|
+
@visited << bb
|
153
|
+
#code << "// bb 'if' #{bb.label}"
|
154
|
+
bb.stmts.each{|stmt| code << stmt.accept(@prp)}
|
155
|
+
cond=bb.infos[:cond].accept(@prp)
|
156
|
+
code << "if (#{cond}){"
|
157
|
+
code.indent=2
|
158
|
+
code << visit_rec(bb.trueBranch)
|
159
|
+
code.indent=0
|
160
|
+
code << "}"
|
161
|
+
code << "else {"
|
162
|
+
code.indent=2
|
163
|
+
code << visit_rec(bb.falseBranch)
|
164
|
+
code.indent=0
|
165
|
+
code << "}"
|
166
|
+
code
|
167
|
+
end
|
168
|
+
|
169
|
+
def gen_while bb
|
170
|
+
code=Code.new
|
171
|
+
@visited << bb
|
172
|
+
bb.stmts.each{|stmt| code << stmt.accept(@prp)}
|
173
|
+
cond=bb.infos[:cond].accept(@prp)
|
174
|
+
code << "while (#{cond}){"
|
175
|
+
code.indent=2
|
176
|
+
code << visit_rec(bb.trueBranch)
|
177
|
+
code.indent=0
|
178
|
+
code << "}"
|
179
|
+
code << visit_rec(bb.falseBranch)
|
180
|
+
code
|
181
|
+
end
|
182
|
+
|
183
|
+
def gen_for bb
|
184
|
+
code=Code.new
|
185
|
+
@visited << bb
|
186
|
+
#code << "// bb 'for' #{bb.label}"
|
187
|
+
bb.stmts.each{|stmt| code << stmt.accept(@prp)}
|
188
|
+
index=bb.infos["loop_index"]
|
189
|
+
index_bound=bb.infos["loop_index_bound"]
|
190
|
+
code << "for(#{index}=0;#{index} < #{index_bound};#{index}++){"
|
191
|
+
code.indent=2
|
192
|
+
code << visit_rec(bb.trueBranch)
|
193
|
+
code.indent=0
|
194
|
+
code << "}"
|
195
|
+
code << visit_rec(bb.falseBranch)
|
196
|
+
code
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,312 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'distribution'
|
3
|
+
|
4
|
+
require_relative 'cfg_printer_c'
|
5
|
+
|
6
|
+
class Hash
|
7
|
+
def sample
|
8
|
+
k=keys.sample
|
9
|
+
[k,self[k]]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module Crokus
|
14
|
+
|
15
|
+
class RandomGen
|
16
|
+
attr_accessor :cfg
|
17
|
+
|
18
|
+
def run params
|
19
|
+
puts "[+] running random C generation"
|
20
|
+
puts " |-->[+] reading parameters file '#{params}'"
|
21
|
+
@params=YAML.load(File.read(params))
|
22
|
+
init_cfg
|
23
|
+
init_random_generators
|
24
|
+
create_inputs
|
25
|
+
create_outputs
|
26
|
+
create_variables
|
27
|
+
create_internal_arrays
|
28
|
+
create_output_assigns
|
29
|
+
create_cfg
|
30
|
+
gen_dot # to see the structure, before hacking the content
|
31
|
+
populate_all
|
32
|
+
generate_c
|
33
|
+
#print_infos
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def print_infos
|
38
|
+
puts " |-->[+] infos about CFG :"
|
39
|
+
puts " |-->[+] #basic blocks : #{@cfg.size}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def gen_dot
|
43
|
+
@cfg.print verbose=false
|
44
|
+
end
|
45
|
+
|
46
|
+
def init_cfg
|
47
|
+
@cfg=CFG.new(@params["name"])
|
48
|
+
@current=@cfg.starter
|
49
|
+
end
|
50
|
+
|
51
|
+
def init_random_generators
|
52
|
+
puts " |-->[+] init parameterized random generators"
|
53
|
+
@rng={}
|
54
|
+
@params.each do |key,val|
|
55
|
+
if key.start_with? "avg_"
|
56
|
+
name=key[4..-1]
|
57
|
+
@rng[name]=Distribution::Normal.rng(mean=val,sigma=0.5) #sigma=1 ?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def register_readables ary
|
63
|
+
@readables||=[]
|
64
|
+
@readables << ary
|
65
|
+
@readables.flatten!
|
66
|
+
end
|
67
|
+
|
68
|
+
def create_inputs
|
69
|
+
name="in_0"
|
70
|
+
@inputs=(1..@params["nb_inputs"]).map{|idx| Ident.new(Token.create name=name.succ)}
|
71
|
+
register_readables @inputs
|
72
|
+
@cfg.infos["inputs"]=@inputs
|
73
|
+
end
|
74
|
+
|
75
|
+
def create_outputs
|
76
|
+
name="out_0"
|
77
|
+
@outputs=(1..@params["nb_outputs"]).map{|idx| Ident.new(Token.create name=name.succ)}
|
78
|
+
@cfg.infos["outputs"]=@outputs
|
79
|
+
end
|
80
|
+
|
81
|
+
def create_variables
|
82
|
+
name="`" # succ is 'a'
|
83
|
+
@vars=(1..@params["nb_int_vars"]).map{|idx| Ident.new(Token.create name=name.succ)}
|
84
|
+
register_readables @vars
|
85
|
+
@cfg.infos["int_vars"]=@vars
|
86
|
+
end
|
87
|
+
|
88
|
+
def create_output_assigns
|
89
|
+
@cfg.infos["output_assigns"]||=[]
|
90
|
+
@outputs.each do |ident|
|
91
|
+
@cfg.infos["output_assigns"] << {ident => create_expression}
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def create_internal_arrays
|
96
|
+
@cfg.infos["internal_arrays"]||=[]
|
97
|
+
(1..@params["nb_int_arrays"]).each do |idx|
|
98
|
+
size=@rng["size_int_arrays"].call.to_i
|
99
|
+
size=IntLit.new(Token.create(size.to_s))
|
100
|
+
@cfg.infos["internal_arrays"] << {Ident.new(Token.create("t#{idx}")) => size}
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def create_cfg
|
105
|
+
puts " |-->[+] building cfg"
|
106
|
+
while @cfg.size < @params["nb_basic_blocks"]
|
107
|
+
rec_create_bbs
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def rec_create_bbs level=0
|
112
|
+
if @cfg.size < @params["nb_basic_blocks"]
|
113
|
+
type = [:plain,:if,:while,:for].sample
|
114
|
+
case type
|
115
|
+
when :plain
|
116
|
+
gen_plain_block(level)
|
117
|
+
when :if
|
118
|
+
gen_if_block(level)
|
119
|
+
when :while
|
120
|
+
gen_while_block(level) if @params["accept_while_loops"]
|
121
|
+
when :for
|
122
|
+
gen_for_block(level)
|
123
|
+
else
|
124
|
+
raise "unknown cfg type : #{type}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def gen_plain_block level
|
130
|
+
@cfg << bb=BasicBlock.new
|
131
|
+
@current.to bb
|
132
|
+
@current=bb
|
133
|
+
end
|
134
|
+
|
135
|
+
def gen_if_block level
|
136
|
+
@current.infos[:cond]=create_condition
|
137
|
+
@current.infos[:start_if]=true
|
138
|
+
@cfg << trueBranch =BasicBlock.new
|
139
|
+
@cfg << falseBranch=BasicBlock.new
|
140
|
+
@cfg << mergeBranch=BasicBlock.new
|
141
|
+
@current.to trueBranch
|
142
|
+
@current.to falseBranch
|
143
|
+
|
144
|
+
@current=trueBranch
|
145
|
+
rec_create_bbs(level+1)
|
146
|
+
@current.to mergeBranch
|
147
|
+
|
148
|
+
@current=falseBranch
|
149
|
+
rec_create_bbs(level+1)
|
150
|
+
@current.to mergeBranch
|
151
|
+
|
152
|
+
@current=mergeBranch
|
153
|
+
end
|
154
|
+
|
155
|
+
def gen_while_block level
|
156
|
+
@cfg << cond_bb = BasicBlock.new(:start_while => true)
|
157
|
+
cond_bb.infos[:cond]=create_condition
|
158
|
+
@cfg << trueBranch = BasicBlock.new
|
159
|
+
@cfg << falseBranch = BasicBlock.new
|
160
|
+
@current.to cond_bb
|
161
|
+
cond_bb.to trueBranch
|
162
|
+
cond_bb.to falseBranch
|
163
|
+
@current = trueBranch
|
164
|
+
rec_create_bbs(level+1)
|
165
|
+
@current.to cond_bb
|
166
|
+
@current=falseBranch
|
167
|
+
end
|
168
|
+
|
169
|
+
def gen_for_block level
|
170
|
+
@cfg << cond_bb = BasicBlock.new(:start_for => true)
|
171
|
+
@index||="idx_0"
|
172
|
+
@index=@index.succ
|
173
|
+
loop_index=Ident.new Token.create @index
|
174
|
+
cond_bb.infos["loop_index"]=loop_index
|
175
|
+
@cfg.infos["loop_indexes"]||=[]
|
176
|
+
@cfg.infos["loop_indexes"] << loop_index
|
177
|
+
cond_bb.infos["loop_index_bound"]=@rng["forloop_iterations"].call.to_i
|
178
|
+
@cfg << trueBranch = BasicBlock.new
|
179
|
+
@cfg << falseBranch = BasicBlock.new
|
180
|
+
@cfg << postBranch = BasicBlock.new(:loop_body_end => true)
|
181
|
+
@current.to cond_bb
|
182
|
+
cond_bb.to trueBranch
|
183
|
+
cond_bb.to falseBranch
|
184
|
+
@current= trueBranch
|
185
|
+
rec_create_bbs(level+1)
|
186
|
+
@current.to postBranch
|
187
|
+
@current=postBranch
|
188
|
+
@current.to cond_bb
|
189
|
+
@current=falseBranch
|
190
|
+
end
|
191
|
+
|
192
|
+
def populate_all
|
193
|
+
puts " |-->[+] populate cfg"
|
194
|
+
@cfg.each{|bb| populate bb}
|
195
|
+
end
|
196
|
+
|
197
|
+
def populate bb
|
198
|
+
@rng["assigns_per_bbs"].call.to_i.times do
|
199
|
+
bb << create_assign
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def create_assign
|
204
|
+
lhs=create_assignee
|
205
|
+
rhs=create_expression()
|
206
|
+
Assign.new(lhs,ASSIGN,rhs)
|
207
|
+
end
|
208
|
+
|
209
|
+
def create_assignee
|
210
|
+
if @params["nb_int_arrays"]>0
|
211
|
+
case r=rand(0..10)
|
212
|
+
when 0..3
|
213
|
+
name,size=@cfg.infos["internal_arrays"].sample.first
|
214
|
+
var=@readables.sample
|
215
|
+
@readables.rotate!
|
216
|
+
abs_func=Ident.new(Token.create "abs")
|
217
|
+
return Indexed.new(name,FunCall.new(abs_func,[Binary.new(var,MOD,size)]))
|
218
|
+
end
|
219
|
+
end
|
220
|
+
assignee=@vars.first
|
221
|
+
@vars.rotate!
|
222
|
+
return assignee
|
223
|
+
end
|
224
|
+
|
225
|
+
def create_condition
|
226
|
+
lhs=create_expression()
|
227
|
+
op =create_cond_op()
|
228
|
+
rhs=create_expression()
|
229
|
+
Binary.new(lhs,op,rhs)
|
230
|
+
end
|
231
|
+
|
232
|
+
def create_expression
|
233
|
+
depth=@rng["assigns_expression_depth"].call.to_i
|
234
|
+
return create_binary_expression(depth)
|
235
|
+
end
|
236
|
+
|
237
|
+
def create_binary_expression depth
|
238
|
+
if depth <= 1
|
239
|
+
lhs=create_unary_expression
|
240
|
+
rhs=create_unary_expression
|
241
|
+
else
|
242
|
+
lhs=create_binary_expression(depth-1)
|
243
|
+
rhs=create_binary_expression(depth-1)
|
244
|
+
end
|
245
|
+
op=create_binary_op
|
246
|
+
if op.val=="/" and lhs.to_s=="0"
|
247
|
+
return create_binary_expression(depth)
|
248
|
+
else
|
249
|
+
return Parenth.new(Binary.new(lhs,op,rhs))
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
ARITH={
|
254
|
+
:add => "+",
|
255
|
+
:sub => "-",
|
256
|
+
:mul => "*",
|
257
|
+
:div => "/",
|
258
|
+
#:shift_r => ">>",
|
259
|
+
#:shift_l => "<<",
|
260
|
+
}
|
261
|
+
|
262
|
+
COMP={
|
263
|
+
:gt => ">",
|
264
|
+
:gte => ">=",
|
265
|
+
:lt => "<",
|
266
|
+
:lte => "<=",
|
267
|
+
:eq => "==",
|
268
|
+
:neq => "!="
|
269
|
+
|
270
|
+
}
|
271
|
+
|
272
|
+
COMPA=[:gt,:lt,:eq,:neq,:gte,:lte]
|
273
|
+
ACCUM=[:add_assign,:sub_assign,:mul_assign,:div_assign]
|
274
|
+
LOGIC=[:or,:and,:xor]
|
275
|
+
MINUS=Token.new [:sub,"-",[0,0]]
|
276
|
+
|
277
|
+
def create_binary_op
|
278
|
+
kind,val=ARITH.sample
|
279
|
+
if @params["accept_integer_division"]==false and kind==:div
|
280
|
+
return create_binary_op # retry
|
281
|
+
end
|
282
|
+
Token.new([kind,val,[0,0]])
|
283
|
+
end
|
284
|
+
|
285
|
+
def create_cond_op
|
286
|
+
kind,val=COMP.sample
|
287
|
+
Token.new([kind,val,[0,0]])
|
288
|
+
end
|
289
|
+
|
290
|
+
def create_unary_expression
|
291
|
+
r=rand(0..10)
|
292
|
+
case r
|
293
|
+
when 1
|
294
|
+
return IntLit.new Token.create rand(0..255).to_s
|
295
|
+
when 2
|
296
|
+
return Parenth.new(Unary.new(MINUS,@readables.sample))
|
297
|
+
when 3
|
298
|
+
name,size=@cfg.infos["internal_arrays"].sample.first
|
299
|
+
var=@readables.sample
|
300
|
+
abs_func=Ident.new(Token.create "abs")
|
301
|
+
index=FunCall.new(abs_func,[Binary.new(var,MOD,size)])
|
302
|
+
return Indexed.new(name,index) #eg : t[abs(a % 4)]
|
303
|
+
else
|
304
|
+
return @readables.sample
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
def generate_c
|
309
|
+
PrinterC.new.print(cfg)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
data/lib/crokus/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crokus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean-Christophe Le Lann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-10-
|
11
|
+
date: 2019-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: distribution
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.7.3
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: colorize
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.8.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.8.1
|
27
41
|
description: Crokus is developped in Ruby and aims at providing simple basis for C
|
28
42
|
transformations. It has been use for teaching purposes and applied to Electronic
|
29
43
|
System Level experiments.
|
@@ -41,6 +55,8 @@ files:
|
|
41
55
|
- lib/crokus/cfg_builder.rb
|
42
56
|
- lib/crokus/cfg_cleaner.rb
|
43
57
|
- lib/crokus/cfg_printer.rb
|
58
|
+
- lib/crokus/cfg_printer_c.rb
|
59
|
+
- lib/crokus/cfg_random_gen.rb
|
44
60
|
- lib/crokus/cleaner.rb
|
45
61
|
- lib/crokus/code.rb
|
46
62
|
- lib/crokus/compiler.rb
|