crokus 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|