crokus 0.0.10 → 0.1.0
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/ast.rb +11 -3
- data/lib/crokus/cfg.rb +2 -2
- data/lib/crokus/cfg_builder.rb +6 -2
- data/lib/crokus/cfg_cleaner.rb +1 -1
- data/lib/crokus/cfg_printer.rb +2 -2
- data/lib/crokus/code.rb +4 -0
- data/lib/crokus/compiler.rb +10 -10
- data/lib/crokus/ir_dumper.rb +2 -2
- data/lib/crokus/lexer.rb +1 -1
- data/lib/crokus/parser.rb +75 -22
- data/lib/crokus/pretty_printer.rb +4 -5
- data/lib/crokus/runner.rb +6 -2
- data/lib/crokus/tac_builder.rb +3 -1
- data/lib/crokus/transformer.rb +8 -1
- data/lib/crokus/trojan_inserter.rb +45 -20
- data/lib/crokus/version.rb +1 -1
- data/lib/crokus/visitor.rb +9 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be5b5ebda83413fed630ed6069d00528c985cc2a29b7d977e5a3ce31b781e267
|
4
|
+
data.tar.gz: 2f450a1c765c7aed5f4707f50b83bdf6d3ec1f9b8e4e5bc2173a41f1c21be556
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b0788d72e8c057b4c2a01581a164e106b33c21c122e2de6a77751e264fdd173f11b5a43044dced72e389eceabf78c4d601912067c486b7a6fc794d94e1c17b7
|
7
|
+
data.tar.gz: 8ff0cc75ee7c2866f611e324439ac278b9c01d57e9df14bfc14cdd8d7c6047ffad0f6a1991caf03f126bce65e098946bb6ece4811e777d02a0fe4416169cdbab
|
data/lib/crokus/ast.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
module Crokus
|
2
3
|
|
3
4
|
class Ast
|
@@ -46,9 +47,9 @@ module Crokus
|
|
46
47
|
end
|
47
48
|
|
48
49
|
class Define < Ast
|
49
|
-
attr_accessor :name,:expr
|
50
|
-
def initialize n,e
|
51
|
-
@name,@expr=n,e
|
50
|
+
attr_accessor :name,:args,:expr
|
51
|
+
def initialize n,a,e
|
52
|
+
@name,@args,@expr=n,a,e
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
@@ -425,7 +426,14 @@ module Crokus
|
|
425
426
|
end
|
426
427
|
|
427
428
|
class IntLit < Literal
|
429
|
+
def to_i
|
430
|
+
tok.val.to_i
|
431
|
+
end
|
428
432
|
end
|
433
|
+
require_relative 'token'
|
434
|
+
|
435
|
+
ZERO_LIT=IntLit.new(ZERO)
|
436
|
+
ONE_LIT=IntLit.new(ONE)
|
429
437
|
|
430
438
|
class FloatLit < Literal
|
431
439
|
end
|
data/lib/crokus/cfg.rb
CHANGED
data/lib/crokus/cfg_builder.rb
CHANGED
@@ -18,7 +18,7 @@ module Crokus
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def visitFunction func,args=nil
|
21
|
-
puts "
|
21
|
+
puts " |--[+] visitFunction '#{func.name}'" unless $options[:mute]
|
22
22
|
@cfg=CFG.new(func.name)
|
23
23
|
@current=@cfg.starter
|
24
24
|
func.body.accept(self)
|
@@ -26,7 +26,7 @@ module Crokus
|
|
26
26
|
@cfg=CFGCleaner.new.clean(@cfg)
|
27
27
|
@cfg.name=Ident.new(Token.create "#{@cfg.name}_clean")
|
28
28
|
func.cfg=@cfg
|
29
|
-
puts "
|
29
|
+
puts " "*5+"|--[+] cfg size for '#{func.name}' : #{@cfg.size}" unless $options[:mute]
|
30
30
|
@cfg.print
|
31
31
|
end
|
32
32
|
|
@@ -38,6 +38,10 @@ module Crokus
|
|
38
38
|
@current << assign
|
39
39
|
end
|
40
40
|
|
41
|
+
def visitLabeledStmt assign,args=nil
|
42
|
+
@current << assign
|
43
|
+
end
|
44
|
+
|
41
45
|
def visitPreFixAccu accu,args=nil
|
42
46
|
@current << accu
|
43
47
|
end
|
data/lib/crokus/cfg_cleaner.rb
CHANGED
data/lib/crokus/cfg_printer.rb
CHANGED
@@ -6,7 +6,7 @@ module Crokus
|
|
6
6
|
|
7
7
|
attr_accessor :code
|
8
8
|
|
9
|
-
def print cfg,
|
9
|
+
def print cfg,pos=0
|
10
10
|
@code=Code.new
|
11
11
|
@code << header
|
12
12
|
@visited=[]
|
@@ -14,7 +14,7 @@ module Crokus
|
|
14
14
|
@code << footer
|
15
15
|
dot_name="cfg_#{cfg.name}.dot"
|
16
16
|
@code.save_as dot_name
|
17
|
-
puts "
|
17
|
+
puts " "*pos+"|--[+] graphviz file saved as '#{dot_name}'"
|
18
18
|
end
|
19
19
|
|
20
20
|
def header
|
data/lib/crokus/code.rb
CHANGED
data/lib/crokus/compiler.rb
CHANGED
@@ -47,7 +47,7 @@ module Crokus
|
|
47
47
|
def parse filename
|
48
48
|
@base_name=File.basename(filename, ".c")
|
49
49
|
code=IO.read(filename)
|
50
|
-
puts "
|
50
|
+
puts "[+] parsing #{filename}" unless options[:mute]
|
51
51
|
@ast=Parser.new.parse(code)
|
52
52
|
draw_ast if options[:draw_ast]
|
53
53
|
pretty_print if options[:pp]
|
@@ -55,46 +55,46 @@ module Crokus
|
|
55
55
|
|
56
56
|
def draw_ast tree=nil,filename=nil
|
57
57
|
dotname=filename || "#{base_name}.dot"
|
58
|
-
puts "
|
58
|
+
puts " |--[+] drawing AST '#{dotname}'" unless options[:mute]
|
59
59
|
ast_ = tree || @ast
|
60
60
|
dot=AstPrinter.new.print(ast_)
|
61
61
|
dot.save_as dotname
|
62
62
|
end
|
63
63
|
|
64
64
|
def transform
|
65
|
-
puts "
|
65
|
+
puts "[+] dummy transform" unless options[:mute]
|
66
66
|
ast_t= Transformer.new.transform(ast)
|
67
67
|
dotname="#{base_name}_trans.dot"
|
68
68
|
draw_ast ast_t,dotname
|
69
69
|
end
|
70
70
|
|
71
71
|
def visit
|
72
|
-
puts "
|
72
|
+
puts "[+] dummy visit" unless options[:mute]
|
73
73
|
Visitor.new.visit(ast)
|
74
74
|
end
|
75
75
|
|
76
76
|
def pretty_print
|
77
|
-
puts "
|
77
|
+
puts "[+] pretty_print" unless options[:mute]
|
78
78
|
code=PrettyPrinter.new.visit(ast)
|
79
79
|
pp_c=@base_name+"_pp.c"
|
80
80
|
File.open(pp_c,'w'){|f| f.puts code}
|
81
|
-
puts "
|
81
|
+
puts " "*1+"|--[+] saved as #{pp_c}" unless options[:mute]
|
82
82
|
end
|
83
83
|
|
84
84
|
def build_cfg
|
85
|
-
puts "
|
85
|
+
puts "[+] building CFGs" unless options[:mute]
|
86
86
|
builder=CFGBuilder.new
|
87
87
|
builder.build(ast)
|
88
88
|
end
|
89
89
|
|
90
90
|
def build_tac
|
91
|
-
puts "
|
91
|
+
puts "[+] building TAC" unless options[:mute]
|
92
92
|
builder=TACBuilder.new
|
93
93
|
builder.visit(ast)
|
94
94
|
end
|
95
95
|
|
96
96
|
def emit_ir
|
97
|
-
puts "
|
97
|
+
puts "[+] emit textual IR " unless options[:mute]
|
98
98
|
IRDumper.new.visit(ast)
|
99
99
|
end
|
100
100
|
|
@@ -103,7 +103,7 @@ module Crokus
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def insert_trojan
|
106
|
-
puts "
|
106
|
+
puts "[+] inserting trojan" unless options[:mute]
|
107
107
|
infected_ast=TrojanInserter.new.insert(ast)
|
108
108
|
if infected_ast
|
109
109
|
code=PrettyPrinter.new.visit(infected_ast)
|
data/lib/crokus/ir_dumper.rb
CHANGED
@@ -3,11 +3,11 @@ module Crokus
|
|
3
3
|
class IRDumper < Visitor
|
4
4
|
|
5
5
|
def visitFunction func,args=nil
|
6
|
-
puts "[+] IR for '#{func.name}'"
|
6
|
+
puts " "*1+"|--[+] IR for '#{func.name}'"
|
7
7
|
ir_code=dump(func.cfg)
|
8
8
|
filename=func.name.to_s+".ir"
|
9
9
|
ir_code.save_as filename
|
10
|
-
puts "
|
10
|
+
puts " "*5+"|--[+] generated #{filename}"
|
11
11
|
end
|
12
12
|
|
13
13
|
def dump cfg
|
data/lib/crokus/lexer.rb
CHANGED
@@ -91,7 +91,7 @@ module Crokus
|
|
91
91
|
|
92
92
|
token :ident => /\A[a-zA-Z]\w*/i
|
93
93
|
token :float_lit => /\A\d*(\.\d+)(E([+-]?)\d+)?/
|
94
|
-
token :integer_lit => /\A(0x[0-9a-fA-F]+)|\d
|
94
|
+
token :integer_lit => /\A((0x[0-9a-fA-F]+)|\d+)L?/
|
95
95
|
token :string_lit => /\A"[^"]*"/
|
96
96
|
token :char_lit => /\A'\\?.'/
|
97
97
|
token :lexer_warning => /./
|
data/lib/crokus/parser.rb
CHANGED
@@ -153,9 +153,20 @@ module Crokus
|
|
153
153
|
expect :sharp
|
154
154
|
expect :ident #define
|
155
155
|
name=expect :ident
|
156
|
+
args=[]
|
157
|
+
if showNext.is? :lparen
|
158
|
+
acceptIt
|
159
|
+
while !showNext.is?(:rparen)
|
160
|
+
args << acceptIt
|
161
|
+
if showNext.is?(:comma)
|
162
|
+
acceptIt
|
163
|
+
end
|
164
|
+
end
|
165
|
+
expect :rparen
|
166
|
+
end
|
156
167
|
e=expression()
|
157
168
|
dedent
|
158
|
-
return Define.new(name,e)
|
169
|
+
return Define.new(name,args,e)
|
159
170
|
end
|
160
171
|
|
161
172
|
def parse_struct
|
@@ -297,8 +308,9 @@ module Crokus
|
|
297
308
|
end
|
298
309
|
|
299
310
|
def parse_label
|
300
|
-
expect
|
301
|
-
expect
|
311
|
+
id=expect(:ident)
|
312
|
+
expect(:colon)
|
313
|
+
Ident.new(id)
|
302
314
|
end
|
303
315
|
|
304
316
|
def parse_goto
|
@@ -475,7 +487,7 @@ module Crokus
|
|
475
487
|
when :typedef
|
476
488
|
ret=typedef()
|
477
489
|
else
|
478
|
-
raise "Parsing ERROR in type declaration: '#{showNext}'"
|
490
|
+
raise "Parsing ERROR in type declaration: '#{showNext}' #{showNext.pos}"
|
479
491
|
end
|
480
492
|
|
481
493
|
while showNext.is? [:mul,:lparen]
|
@@ -541,7 +553,13 @@ module Crokus
|
|
541
553
|
indent "parse else"
|
542
554
|
expect :else
|
543
555
|
ret=Else.new
|
544
|
-
|
556
|
+
stmt=statement()
|
557
|
+
case stmt
|
558
|
+
when Body
|
559
|
+
ret.body=stmt
|
560
|
+
else
|
561
|
+
ret.body=Body.new([stmt])
|
562
|
+
end
|
545
563
|
dedent
|
546
564
|
return ret
|
547
565
|
end
|
@@ -550,8 +568,13 @@ module Crokus
|
|
550
568
|
indent "parse_while"
|
551
569
|
expect :while
|
552
570
|
cond=expression()
|
553
|
-
|
554
|
-
|
571
|
+
stmt=statement()
|
572
|
+
case stmt
|
573
|
+
when Body
|
574
|
+
body=stmt
|
575
|
+
else
|
576
|
+
body=Body.new([stmt])
|
577
|
+
end
|
555
578
|
dedent
|
556
579
|
return While.new(cond,body)
|
557
580
|
end
|
@@ -566,7 +589,13 @@ module Crokus
|
|
566
589
|
expect :semicolon
|
567
590
|
forloop.increment=expression()
|
568
591
|
expect :rparen
|
569
|
-
|
592
|
+
stmt=statement()
|
593
|
+
case stmt
|
594
|
+
when Body
|
595
|
+
forloop.body=stmt
|
596
|
+
else
|
597
|
+
forloop.body=Body.new([stmt])
|
598
|
+
end
|
570
599
|
dedent
|
571
600
|
forloop
|
572
601
|
end
|
@@ -667,7 +696,7 @@ module Crokus
|
|
667
696
|
while showNext.is? :oror
|
668
697
|
op=acceptIt
|
669
698
|
e2=logand
|
670
|
-
e1=
|
699
|
+
e1=Binary.new(e1,op,e2)
|
671
700
|
end
|
672
701
|
dedent
|
673
702
|
return e1
|
@@ -786,7 +815,6 @@ module Crokus
|
|
786
815
|
case showNext.kind
|
787
816
|
when :lparen # parenth expr OR casting !
|
788
817
|
res=is_casting?
|
789
|
-
puts "casting? : #{res}" if $options[:verbose]
|
790
818
|
if res
|
791
819
|
e=casting
|
792
820
|
else
|
@@ -799,23 +827,48 @@ module Crokus
|
|
799
827
|
return e
|
800
828
|
end
|
801
829
|
|
802
|
-
def
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
830
|
+
def castexp
|
831
|
+
#puts "castexpr : #{pp @tokens[0..3]}"
|
832
|
+
case showNext.kind
|
833
|
+
when :lparen # parenth expr OR casting !
|
834
|
+
res=is_casting?
|
835
|
+
#puts "casting=#{res}"
|
836
|
+
if res
|
837
|
+
e=casting
|
838
|
+
else
|
839
|
+
e=parenthesized
|
840
|
+
end
|
841
|
+
else
|
842
|
+
e=unary
|
808
843
|
end
|
809
|
-
|
810
|
-
return
|
811
|
-
return true if tok.is? STARTERS_UNARY-STARTERS_ARRAY_OR_STRUCT_INIT
|
812
|
-
return false
|
844
|
+
dedent
|
845
|
+
return e
|
813
846
|
end
|
814
847
|
|
848
|
+
def is_casting?
|
849
|
+
#puts "is_casting? : #{pp @tokens[0..1]}"
|
850
|
+
cond1= @tokens[0].is?(:lparen)
|
851
|
+
cond2= @tokens[1].is?([:int,:uint,:short,:byte,:float,:long])
|
852
|
+
cond1 and cond2
|
853
|
+
end
|
854
|
+
|
855
|
+
# def is_casting?
|
856
|
+
# i=0
|
857
|
+
# tok=DUMMY
|
858
|
+
# while tok.kind!=:rparen
|
859
|
+
# tok=@tokens[i]
|
860
|
+
# i+=1
|
861
|
+
# end
|
862
|
+
# pp tok=@tokens[i]
|
863
|
+
# return false if tok.is? [:mul,:add,:sub]
|
864
|
+
# pp cond=STARTERS_UNARY-STARTERS_ARRAY_OR_STRUCT_INIT
|
865
|
+
# return true if tok.is? cond
|
866
|
+
# return false
|
867
|
+
# end
|
868
|
+
|
815
869
|
def casting
|
816
870
|
puts "casting : #{showNext}" if $options[:verbose]
|
817
871
|
expect :lparen
|
818
|
-
#typename
|
819
872
|
t=parse_type
|
820
873
|
expect :rparen
|
821
874
|
u=unary
|
@@ -934,7 +987,7 @@ module Crokus
|
|
934
987
|
when :sizeof
|
935
988
|
u=sizeof()
|
936
989
|
else
|
937
|
-
raise "not an unary"
|
990
|
+
raise "not an unary. showNext : #{showNext}"
|
938
991
|
end
|
939
992
|
end
|
940
993
|
return u
|
@@ -329,11 +329,10 @@ module Crokus
|
|
329
329
|
return "continue;"
|
330
330
|
end
|
331
331
|
|
332
|
-
def visitLabeledStmt
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
return code
|
332
|
+
def visitLabeledStmt lstmt,args=nil
|
333
|
+
label=lstmt.label.accept(self)
|
334
|
+
stmt =lstmt.stmt.accept(self)
|
335
|
+
ret="#{label} : #{stmt.to_s}"
|
337
336
|
end
|
338
337
|
|
339
338
|
def visitGoto goto,args=nil
|
data/lib/crokus/runner.rb
CHANGED
@@ -69,8 +69,12 @@ module Crokus
|
|
69
69
|
options[:random] = params_filename
|
70
70
|
end
|
71
71
|
|
72
|
-
parser.on('--trojan PARAMS', "generates random c files, using parameters", String) do |params_filename|
|
73
|
-
|
72
|
+
# parser.on('--trojan PARAMS', "generates random c files, using parameters", String) do |params_filename|
|
73
|
+
# options[:trojan] = params_filename
|
74
|
+
# end
|
75
|
+
|
76
|
+
parser.on('--trojan', "generates random c files, using parameters") do
|
77
|
+
options[:trojan] = true
|
74
78
|
end
|
75
79
|
|
76
80
|
parser.on("--vv", "verbose") do
|
data/lib/crokus/tac_builder.rb
CHANGED
@@ -5,7 +5,7 @@ module Crokus
|
|
5
5
|
OP_ASSIGN=Token.new([:assign,"=",[0,0]])
|
6
6
|
|
7
7
|
def visitFunction func,args=nil
|
8
|
-
puts "
|
8
|
+
puts " "*1+"|--[+] tac builder for '#{func.name}'"
|
9
9
|
build func.cfg
|
10
10
|
end
|
11
11
|
|
@@ -19,6 +19,7 @@ module Crokus
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def new_tmp
|
22
|
+
@tmp_id||=0
|
22
23
|
tok=Token.create "$"+@tmp_id.to_s
|
23
24
|
@tmp_id+=1
|
24
25
|
tok
|
@@ -112,6 +113,7 @@ module Crokus
|
|
112
113
|
ret=Parenth.new(par.expr)
|
113
114
|
e=par.expr.accept(self)
|
114
115
|
tmp=new_tmp()
|
116
|
+
@new_stmts||=[]
|
115
117
|
@new_stmts << Assign.new(tmp,OP_ASSIGN,e)
|
116
118
|
ret.expr=tmp
|
117
119
|
return ret
|
data/lib/crokus/transformer.rb
CHANGED
@@ -42,8 +42,9 @@ module Crokus
|
|
42
42
|
|
43
43
|
def visitDefine define,args=nil
|
44
44
|
name=define.name.accept(self)
|
45
|
+
args=define.args.map{|arg| arg.accept(self)}
|
45
46
|
expr=define.expr.accept(self)
|
46
|
-
Define.new(name,expr)
|
47
|
+
Define.new(name,args,expr)
|
47
48
|
end
|
48
49
|
|
49
50
|
def visitTypedef typdef,args=nil
|
@@ -113,6 +114,12 @@ module Crokus
|
|
113
114
|
end
|
114
115
|
|
115
116
|
#...........stmts...............
|
117
|
+
def visitLabeledStmt lstmt,args=nil
|
118
|
+
label=lstmt.label.accept(self)
|
119
|
+
stmt=lstmt.stmt.accept(self)
|
120
|
+
LabeledStmt.new(label,stmt)
|
121
|
+
end
|
122
|
+
|
116
123
|
def visitCommaStmt comma,args=nil
|
117
124
|
lhs=comma.lhs.accept(self)
|
118
125
|
rhs=comma.rhs.accept(self)
|
@@ -9,10 +9,10 @@ module Crokus
|
|
9
9
|
@nb_trojans=0
|
10
10
|
new_ast=transform(ast)
|
11
11
|
if @nb_trojans>0
|
12
|
-
puts "insertion succeeded : #{@nb_trojans} trojan(s)"
|
12
|
+
puts " "*1+"|--[+] insertion succeeded : #{@nb_trojans} trojan(s)"
|
13
13
|
return new_ast
|
14
14
|
else
|
15
|
-
puts "insertion failed"
|
15
|
+
puts " "*1+"|--[?] insertion failed"
|
16
16
|
end
|
17
17
|
nil
|
18
18
|
end
|
@@ -25,13 +25,27 @@ module Crokus
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def visitFunction func,args=nil
|
28
|
-
puts "[+] func #{func.name}"
|
28
|
+
puts " "*1+"|--[+] func #{func.name}"
|
29
29
|
func_troj=super(func,args)
|
30
30
|
success=insert_trojan(func_troj)
|
31
31
|
@nb_trojans+=1 if success
|
32
32
|
func_troj
|
33
33
|
end
|
34
34
|
|
35
|
+
def insert_trojan func
|
36
|
+
if trojan=build_trojan(func)
|
37
|
+
bodies=bodies_collect(func)
|
38
|
+
puts "\t#bodies = #{bodies.size}"
|
39
|
+
target_body=bodies.sample
|
40
|
+
stmts=target_body.stmts
|
41
|
+
nb_decls=stmts.select{|stmt| stmt.is_a? Decl}.size
|
42
|
+
pos=rand(nb_decls-1..stmts.size-1)+1
|
43
|
+
target_body.stmts=stmts.insert(pos,trojan)
|
44
|
+
return success=true
|
45
|
+
end
|
46
|
+
success=false
|
47
|
+
end
|
48
|
+
|
35
49
|
def bodies_collect func
|
36
50
|
bodies=[]
|
37
51
|
bodies << func.body
|
@@ -55,6 +69,8 @@ module Crokus
|
|
55
69
|
bodies << stmt.body
|
56
70
|
when Switch
|
57
71
|
bodies << switch_.cases.collect{|case_| case_.body}
|
72
|
+
when Body
|
73
|
+
bodies << bodies_rec_collect(stmt)
|
58
74
|
end
|
59
75
|
end
|
60
76
|
result = []
|
@@ -63,20 +79,6 @@ module Crokus
|
|
63
79
|
result.flatten
|
64
80
|
end
|
65
81
|
|
66
|
-
def insert_trojan func
|
67
|
-
bodies=bodies_collect(func)
|
68
|
-
puts "#bodies = #{bodies.size}"
|
69
|
-
target_body=bodies.sample
|
70
|
-
stmts=target_body.stmts
|
71
|
-
nb_decls=stmts.select{|stmt| stmt.is_a? Decl}.size
|
72
|
-
pos=rand(nb_decls..stmts.size-1)
|
73
|
-
if trojan=build_trojan(func)
|
74
|
-
target_body.stmts=stmts.insert(pos,trojan)
|
75
|
-
return success=true
|
76
|
-
end
|
77
|
-
success=false
|
78
|
-
end
|
79
|
-
|
80
82
|
INT_TYPE=Type.new(INT)
|
81
83
|
|
82
84
|
def build_trojan func
|
@@ -119,16 +121,39 @@ module Crokus
|
|
119
121
|
|
120
122
|
def build_trigger func
|
121
123
|
args=find_int_arg(func)
|
122
|
-
|
123
|
-
|
124
|
+
arg_names=get_arg_names(args)
|
125
|
+
return unless arg_names.size>1
|
126
|
+
cond=Binary.new(Parenth.new(Binary.new(arg_names[0],AND,arg_names[1])),EQUAL,T42)
|
124
127
|
If.new(cond,nil)
|
125
128
|
end
|
126
129
|
|
127
130
|
def find_int_arg func
|
128
131
|
func.args.select do |arg|
|
129
|
-
(tok=arg.type.name).is_a?(Token) && tok.is?(:int)
|
132
|
+
cond1=(tok=arg.type.name).is_a?(Token) && tok.is?(:int)
|
133
|
+
cond2=(atype=arg.type).is_a?(ArrayOf) && (tok=atype.name.name).is_a?(Token) && tok.is?(:int)
|
134
|
+
cond1 or cond2
|
130
135
|
end
|
131
136
|
end
|
132
137
|
|
138
|
+
def get_arg_names args
|
139
|
+
ret=[]
|
140
|
+
ret << args.map{|formal_arg|
|
141
|
+
case (type=formal_arg.type)
|
142
|
+
when ArrayOf
|
143
|
+
if type.size.is_a?(IntLit)
|
144
|
+
array_size=type.size.to_i
|
145
|
+
if array_size>1
|
146
|
+
ret << Indexed.new(formal_arg.name,ZERO_LIT)
|
147
|
+
ret << Indexed.new(formal_arg.name,ONE_LIT)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
else
|
151
|
+
formal_arg.name
|
152
|
+
end
|
153
|
+
}
|
154
|
+
ret.flatten!
|
155
|
+
end
|
156
|
+
|
157
|
+
|
133
158
|
end
|
134
159
|
end
|
data/lib/crokus/version.rb
CHANGED
data/lib/crokus/visitor.rb
CHANGED
@@ -266,6 +266,15 @@ module Crokus
|
|
266
266
|
lit
|
267
267
|
end
|
268
268
|
|
269
|
+
def visitCondExpr cexpr,args=nil
|
270
|
+
indent "condexpr"
|
271
|
+
cexpr.cond.accept(self)
|
272
|
+
cexpr.lhs.accept(self,args)
|
273
|
+
cexpr.rhs.accept(self,args)
|
274
|
+
dedent
|
275
|
+
cexpr
|
276
|
+
end
|
277
|
+
|
269
278
|
def visitBinary expr,args=nil
|
270
279
|
indent "Binary"
|
271
280
|
expr.lhs.accept(self,args)
|
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.1.0
|
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: 2020-02-
|
11
|
+
date: 2020-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: distribution
|