scrag 0.0.1

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.
@@ -0,0 +1,97 @@
1
+ require "optparse"
2
+
3
+ require_relative "compiler"
4
+
5
+ module <%=project_name.capitalize%>
6
+
7
+ class Runner
8
+
9
+ def self.run *arguments
10
+ new.run(arguments)
11
+ end
12
+
13
+ def run arguments
14
+ compiler=Compiler.new
15
+ compiler.options = args = parse_options(arguments)
16
+ begin
17
+ if filename=args[:file]
18
+ ok=compiler.compile(filename)
19
+ else
20
+ raise "need a <%=project_name%> file : <%=project_name%> [options] <file>"
21
+ end
22
+ return ok
23
+ rescue Exception => e
24
+ puts e unless compiler.options[:mute]
25
+ return false
26
+ end
27
+ end
28
+
29
+ def header
30
+ puts "<%=project_name%> (#{VERSION}) - (c) JC Le Lann 2020"
31
+ end
32
+
33
+ private
34
+ def parse_options(arguments)
35
+
36
+ parser = OptionParser.new
37
+
38
+ no_arguments=arguments.empty?
39
+
40
+ options = {}
41
+
42
+ parser.on("-h", "--help", "Show help message") do
43
+ puts parser
44
+ exit(true)
45
+ end
46
+
47
+ parser.on("-p", "--parse", "parse only") do
48
+ options[:parse_only]=true
49
+ end
50
+
51
+ parser.on("--pp", "pretty print back source code ") do
52
+ options[:pp] = true
53
+ end
54
+
55
+ parser.on("--ast", "abstract syntax tree (AST)") do
56
+ options[:ast] = true
57
+ end
58
+
59
+ parser.on("--check", "elaborate and check types") do
60
+ options[:check] = true
61
+ end
62
+
63
+ parser.on("--draw_ast", "draw abstract syntax tree (AST)") do
64
+ options[:draw_ast] = true
65
+ end
66
+
67
+ parser.on("--dummy_transform", "dummy ast transform") do
68
+ options[:dummy_transform] = true
69
+ end
70
+
71
+ parser.on("--vv", "verbose") do
72
+ options[:verbose] = true
73
+ end
74
+
75
+ parser.on("--mute","mute") do
76
+ options[:mute]=true
77
+ end
78
+
79
+ parser.on("-v", "--version", "Show version number") do
80
+ puts VERSION
81
+ exit(true)
82
+ end
83
+
84
+ parser.parse!(arguments)
85
+
86
+ header unless options[:mute]
87
+
88
+ options[:file]=arguments.shift #the remaining file
89
+
90
+ if no_arguments
91
+ puts parser
92
+ end
93
+
94
+ options
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,63 @@
1
+ class Token
2
+ attr_accessor :kind,:val,:pos
3
+ def initialize tab
4
+ @kind,@val,@pos=*tab
5
+ end
6
+
7
+ def is_a? kind
8
+ case kind
9
+ when Symbol
10
+ return @kind==kind
11
+ when Array
12
+ for sym in kind
13
+ return true if @kind==sym
14
+ end
15
+ return false
16
+ else
17
+ raise "wrong type during lookahead"
18
+ end
19
+ end
20
+
21
+ def not_a? kind
22
+ result=self.is_a? kind
23
+ !result
24
+ end
25
+
26
+ def is_not_a? kind
27
+ case kind
28
+ when Symbol
29
+ return @kind!=kind
30
+ when Array
31
+ ret=true
32
+ for sym in kind
33
+ ret=false if @kind==sym
34
+ end
35
+ return ret
36
+ else
37
+ raise "wrong type during lookahead"
38
+ end
39
+ end
40
+
41
+ # def accept visitor
42
+ # end
43
+
44
+ def self.create str
45
+ Token.new [:id,str,[0,0]]
46
+ end
47
+
48
+ # def inspect
49
+ # "(#{@kind.to_s.ljust(15,' ')},'#{@val}',#{@pos})"
50
+ # end
51
+
52
+ def to_s
53
+ val
54
+ end
55
+
56
+ def clone
57
+ Token.new([@kind,@val,@pos])
58
+ end
59
+ end
60
+
61
+ ONE = Token.new [:int_lit,'1',['na','na']]
62
+ ZERO = Token.new [:int_lit,'0',['na','na']]
63
+ DUMMY= Token.new [:id ,'' ,['na','na']]
@@ -0,0 +1,7 @@
1
+ require "colorize"
2
+ require_relative "./<%=project_name%>/version"
3
+ require_relative "./<%=project_name%>/runner"
4
+ require_relative "./<%=project_name%>/compiler"
5
+
6
+ module <%=project_name.capitalize%>
7
+ end
@@ -0,0 +1,487 @@
1
+ require_relative 'code'
2
+
3
+ module <%=project_name.capitalize%>
4
+
5
+ # here we transform an AST into another AST.
6
+ # we don't use Marshalling.
7
+
8
+ class Transformer
9
+
10
+ attr_accessor :code
11
+
12
+ def initialize
13
+ @ind=-2
14
+ @verbose=true
15
+ @verbose=false
16
+ end
17
+
18
+ def transform ast
19
+ ast.accept(self)
20
+ end
21
+
22
+ alias :visit :transform
23
+
24
+ def new_tmp
25
+ $tmp_id||=0
26
+ tok=Token.create_id "$"+$tmp_id.to_s
27
+ $tmp_id+=1
28
+ Ident.new(tok)
29
+ end
30
+
31
+ def new_ident
32
+ new_tmp
33
+ end
34
+
35
+ def reset_new_ident
36
+ @tmp_id=0
37
+ end
38
+
39
+ def visitToken tok, args=nil
40
+ Token.new [tok.kind,tok.val,tok.pos]
41
+ end
42
+
43
+ def visitRoot root,args=nil
44
+ stmts=root.stmts.map{|stmt| stmt.accept(self)}
45
+ ret=Root.new(stmts)
46
+ ret.pass="transformed"
47
+ ret
48
+ end
49
+
50
+ def visitRequire require_,args=nil
51
+ Require.new(require.filename)
52
+ end
53
+
54
+ def visitModule module_,args=nil
55
+ name=module_.name.accept(self)
56
+ elements=module_.elements.map{|e| e.accept(self)}
57
+ Module.new(name,elements)
58
+ end
59
+
60
+ def visitComment comment,args=nil
61
+ Comment.new(comment.str)
62
+ end
63
+
64
+ def visitSingleTokenLit stl,args=nil
65
+ end
66
+
67
+ def visitIdent ident,args=nil
68
+ token=ident.token.accept(self)
69
+ Ident.new(token)
70
+ end
71
+
72
+ def visitIntLit intlit,args=nil
73
+ IntLit.create intlit.token.val
74
+ end
75
+
76
+ def visitFloatLit floatlit,args=nil
77
+ FloatLit.create floatlit.token.val
78
+ end
79
+
80
+ def visitTrueLit true_,args=nil
81
+ TrueLit.create "true"
82
+ end
83
+
84
+ def visitFalseLit false_,args=nil
85
+ FalseLit.create "false"
86
+ end
87
+
88
+ def visitStringLit str,args=nil
89
+ StringLit.create str.token.val
90
+ end
91
+
92
+ def visitParam param,args=nil
93
+ name=param.name.accept(self)
94
+ type=param.parsed_type.accept(self)
95
+ expr=param.expr.accept(self)
96
+ Param.new(name,type,expr)
97
+ end
98
+
99
+ def visitIo io,args=nil
100
+ end
101
+
102
+ def visitInput input,args=nil
103
+ name=input.name.accept(self)
104
+ type=input.parsed_type.accept(self)
105
+ Input.new(name,type)
106
+ end
107
+
108
+ def visitOutput output,args=nil
109
+ name=output.name.accept(self)
110
+ type=output.parsed_type.accept(self)
111
+ Output.new(name,type)
112
+ end
113
+
114
+ def visitDeclaration declaration,args=nil
115
+ end
116
+
117
+ def visitVar var,args=nil
118
+ name=var.name.accept(self)
119
+ type=var.parsed_type.accept(self)
120
+ Var.new(name,type)
121
+ end
122
+
123
+ def visitTypeDef typedef,args=nil
124
+ name=typedef.name.accept(self)
125
+ type=typedef.type.accept(self)
126
+ TypeDef.new(name,type)
127
+ end
128
+
129
+ def visitType type,args=nil
130
+ tok=type.token.accept(self)
131
+ Type.new(tok)
132
+ end
133
+
134
+ def visitBasicType basic_type,args=nil
135
+ tok=basic_type.token.accept(self)
136
+ BasicType.new(tok)
137
+ end
138
+
139
+ def visitNil nil_,args=nil
140
+ Nil.new
141
+ end
142
+
143
+ def visitNamedType named_type,args=nil
144
+ name=named_type.name.accept(self)
145
+ NamedType.new(name)
146
+ end
147
+
148
+ def visitArrayType array_type,args=nil
149
+ size=array_type.size.accept(self)
150
+ ptype=array_type.parsed_type.accept(self)
151
+ ArrayType.new(size,ptype)
152
+ end
153
+
154
+ def visitRecordType record_type,args=nil
155
+ formal_parameters=record_type.formal_parameters.map{|fp| fp.accept(self)}
156
+ RecordType.new(formal_parameters)
157
+ end
158
+
159
+ def visitEnumDef enum_def,args=nil
160
+ list=enum_def.list.map{|e| e.accept(self)}
161
+ EnumDef.new(list)
162
+ end
163
+
164
+ def visitActor actor,args=nil
165
+ puts " "+"|--[+] transforming actor #{actor.name.str}"
166
+ ret=Actor.new
167
+ ret.name=actor.name.accept(self)
168
+ ret.includes=actor.includes.map{|inc| inc.accept(self)}
169
+ ret.inputs=actor.inputs.map{|i| i.accept(self,args)}
170
+ ret.outputs=actor.outputs.map{|o|o.accept(self,args)}
171
+ ret.typedefs=actor.typedefs.each {|o| o.accept(self,args)}
172
+ ret.vars=actor.vars.map{|v| v.accept(self,args)}
173
+ ret.body=actor.body.accept(self,args)
174
+ ret.funcs=actor.funcs.map{|func|func.accept(self,args)}
175
+ ret
176
+ end
177
+
178
+ def visitSystem system,args=nil
179
+ ret=System.new
180
+ ret.name=system.name.accept(self)
181
+ ret.includes=system.includes.map{|e| e.accept(self)}
182
+ ret.params=system.params.map{|e| e.accept(self)}
183
+ ret.inputs=system.inputs.map{|i| i.accept(self,args)}
184
+ ret.outputs=system.outputs.map{|o|o.accept(self,args)}
185
+ ret.instances=system.instances.map{|e| e.accept(self)}
186
+ ret.connects=system.connects.map{|e| e.accept(self)}
187
+ ret.generate_fors=system.generate_fors.map{|e| e.accept(self)}
188
+ ret
189
+ end
190
+
191
+ def visitInclude include,args=nil
192
+ name=include.name.accept(self)
193
+ Include.new(name)
194
+ end
195
+
196
+ def visitInstance instance,args=nil
197
+ name=instance.name.accept(self)
198
+ type=instance.parsed_type.accept(self)
199
+ Instance.new(name,type)
200
+ end
201
+
202
+ def visitConnect connect,args=nil
203
+ source=connect.source.accept(self)
204
+ sink=connect.sink.accept(self)
205
+ channel=connect.channel.accept(self) if connect.channel
206
+ Connect.new(source,sink,channel)
207
+ end
208
+
209
+ def visitCnxPort cnx_port,args=nil
210
+ instance_name=cnx_port.instance_name.accept(self) if cnx_port.instance_name
211
+ port_name=cnx_port.port_name.accept(self)
212
+ CnxPort.new(instance_name,port_name)
213
+ end
214
+ # FSM
215
+ def visitFsm fsm,args=nil
216
+ states=fsm.states.map{|state| state.accept(self)}
217
+ Fsm.new(states)
218
+ end
219
+
220
+ def visitState state,args=nil
221
+ name=state.name.accept(self)
222
+ body=state.body.accept(self)
223
+ State.new(name,body)
224
+ end
225
+
226
+ def visitNext next_,args=nil
227
+ state_name=next_.state_name.accept(self)
228
+ Next.new(state_name)
229
+ end
230
+
231
+ # IR
232
+ def visitIR ir,args=nil
233
+ name=ir.name.accept(self) #bug fix
234
+ bbs=ir.bbs.map{|bb| bb.accept(self)}
235
+ new_ir=IR.new(name,bbs)
236
+
237
+ IR_Builder.new.link(new_ir)
238
+ IR_Finalizer.new.clean(new_ir)
239
+ new_ir
240
+ end
241
+
242
+ def visitBasicBlock bb,args=nil
243
+ label=bb.label.accept(self)
244
+ stmts=bb.stmts.map{|stmt| stmt.accept(self)}
245
+ infos={:label=>label}
246
+ BasicBlock.new(infos,stmts)
247
+ end
248
+ #
249
+ def visitBody body,args=nil
250
+ stmts=body.stmts.map{|stmt| stmt.accept(self)}
251
+ Body.new(stmts)
252
+ end
253
+
254
+ def visitParallel parallel,args=nil
255
+ body=parallel.body.accept(self)
256
+ Parallel.new(body)
257
+ end
258
+
259
+ def visitLabel label,args=nil
260
+ ident=label.indent.accept(self)
261
+ Label.new(ident)
262
+ end
263
+
264
+ def visitAssign assign,args=nil
265
+ lhs=assign.lhs.accept(self)
266
+ rhs=assign.rhs.accept(self)
267
+ Assign.new(lhs,rhs)
268
+ end
269
+
270
+ def visitAccu accu,args=nil
271
+ lhs=accu.lhs.accept(self)
272
+ op=accu.op.accept(self)
273
+ rhs=accu.rhs.accept(self)
274
+ Accu.new(lhs,op,rhs)
275
+ end
276
+
277
+ def visitIf if_,args=nil
278
+ cond=if_.cond.accept(self)
279
+ then_=if_.then.accept(self)
280
+ elsifs_=if_.elsifs.map{|elsif_| elsif_.accept(self)}
281
+ else_=if_.else.accept(self)
282
+ If.new(cond,then_,elsifs_,else_)
283
+ end
284
+
285
+ def visitElsif elsif_,args=nil
286
+ cond=elsif_.cond.accept(self)
287
+ body=elsif_.body.accept(self)
288
+ Elsif.new(cond,body)
289
+ end
290
+
291
+ def visitPuts puts_,args=nil
292
+ expr=puts_.expr.accept(self)
293
+ Puts.new(expr)
294
+ end
295
+
296
+ def visitWhile while_,args=nil
297
+ cond=while_.cond.accept(self)
298
+ body=while_.body.accept(self)
299
+ While.new(cond,body)
300
+ end
301
+
302
+ def visitFor for_,args=nil
303
+ idx=for_.idx.accept(self)
304
+ range=for_.range.accept(self)
305
+ body=for_.body.accept(self)
306
+ For.new(idx,range,body)
307
+ end
308
+
309
+ def visitRange range_,args=nil
310
+ lhs=range_.lhs.accept(self)
311
+ rhs=range_.rhs.accept(self)
312
+ Range.new(lhs,rhs)
313
+ end
314
+
315
+ def visitFuncDef func_def,args=nil
316
+ puts " "*5+"|--[+] transforming def '#{func_def.name}'"
317
+ name=func_def.name.accept(self)
318
+ formal_parameters=func_def.formal_parameters.map{|fp| fp.accept(self)}
319
+ vars=func_def.vars.map{|v| v.accept(self)}
320
+ body=func_def.body.accept(self)
321
+ typedefs=func_def.typedefs.map{|td| td.accept(self)}
322
+ FuncDef.new(name,formal_parameters,vars,body,typedefs)
323
+ end
324
+
325
+ def visitFormalParameter fp,args=nil
326
+ name=fp.name.accept(self)
327
+ type=fp.parsed_type.accept(self)
328
+ FormalParameter.new(name,type)
329
+ end
330
+
331
+ def visitSend send,args=nil
332
+ expr=send.expr.accept(self)
333
+ port=send.port.accept(self)
334
+ Send.new(expr,port)
335
+ end
336
+
337
+ def visitWrite write,args=nil
338
+ expr=write.expr.accept(self)
339
+ port=write.port.accept(self)
340
+ Write.new(expr,port)
341
+ end
342
+
343
+ def visitReceive receive,args=nil
344
+ expr=receive.expr.accept(self)
345
+ port=receive.port.accept(self)
346
+ Receive.new(expr,port)
347
+ end
348
+
349
+ def visitRead read,args=nil
350
+ expr=read.expr.accept(self)
351
+ port=read.port.accept(self)
352
+ Read.new(expr,port)
353
+ end
354
+
355
+ def visitReturn return_,args=nil
356
+ expr=return_.expr.accept(self)
357
+ Return.new(expr)
358
+ end
359
+
360
+ def visitWait wait,args=nil
361
+ Wait.new
362
+ end
363
+
364
+ def visitBinary binary,args=nil
365
+ ret=Binary.new
366
+ ret.lhs=binary.lhs.accept(self)
367
+ ret.op=binary.op.accept(self)
368
+ ret.rhs=binary.rhs.accept(self)
369
+ ret.type=binary.type # <======= type also propagated ?
370
+ ret
371
+ end
372
+
373
+ def visitFuncCall func_call,args=nil
374
+ name=func_call.name.accept(self)
375
+ actual_parameters=func_call.actual_parameters.map{|ap| ap.accept(self)}
376
+ FuncCall.new(name,actual_parameters)
377
+ end
378
+
379
+ def visitIndexed indexed,args=nil
380
+ lhs=indexed.lhs.accept(self)
381
+ rhs=indexed.rhs.accept(self)
382
+ Indexed.new(lhs,rhs)
383
+ end
384
+
385
+ def visitPointed pointed,args=nil
386
+ lhs=pointed.lhs.accept(self)
387
+ rhs=pointed.rhs.accept(self)
388
+ Pointed.new(lhs,rhs)
389
+ end
390
+
391
+ def visitRecordLit reclit,args=nil
392
+ elements=reclit.elements.map{|e| e.accept(self)}
393
+ RecordLit.new(elements)
394
+ end
395
+
396
+ def visitArrayLit arylit,args=nil
397
+ elements=arylit.elements.map{|e| e.accept(self)}
398
+ ArrayLit.new(elements)
399
+ end
400
+
401
+ def visitUnary unary,args=nil
402
+ #:abtract
403
+ end
404
+
405
+ def visitMinus minus,args=nil
406
+ expr=minus.expr.accept(self)
407
+ Minus.new(expr)
408
+ end
409
+
410
+ def visitNot not_,args=nil
411
+ expr=not_.expr.accept(self)
412
+ Not.new(expr)
413
+ end
414
+
415
+ def visitParenth parenth,args=nil
416
+ expr=parenth.expr.accept(self)
417
+ Parenth.new(expr)
418
+ end
419
+
420
+ def visitPre pre,args=nil
421
+ expr=pre.expr.accept(self)
422
+ Pre.new(expr)
423
+ end
424
+
425
+ def visitValid valid,args=nil
426
+ port_name=valid.port_name.accept(self)
427
+ Valid.new(port_name)
428
+ end
429
+
430
+ def visitGoto goto,args=nil
431
+ label=goto.label.accept(self)
432
+ Goto.new(label)
433
+ end
434
+
435
+ def visitStop stop,args=nil
436
+ Stop.new
437
+ end
438
+
439
+ def visitITE ite,args=nil
440
+ cond=ite.cond.accept(self)
441
+ label_true=ite.label_true.accept(self)
442
+ label_false=ite.label_false.accept(self)
443
+ new_ite=ITE.new(cond)
444
+ new_ite.label_true=label_true
445
+ new_ite.label_false=label_false
446
+ new_ite
447
+ end
448
+
449
+ def visitReq req,args=nil
450
+ port=req.port.accept(self)
451
+ Req.new(port)
452
+ end
453
+
454
+ def visitUnreq unreq,args=nil
455
+ port=unreq.port.accept(self)
456
+ Unreq.new(port)
457
+ end
458
+
459
+ def visitAck ack,args=nil
460
+ port=ack.port.accept(self)
461
+ Ack.new(port)
462
+ end
463
+
464
+ def visitCallAck call_ack,args=nil
465
+ end
466
+
467
+ def visitCallReq call_req,args=nil
468
+ end
469
+
470
+ def visitCallUnreq call_unreq,args=nil
471
+ end
472
+
473
+ def visitCallRet call_ret,args=nil
474
+ end
475
+
476
+ def visitJTrue jtrue,args=nil
477
+ end
478
+
479
+ def visitJlt jlt,args=nil
480
+ end
481
+
482
+ def visitPhi phi,args=nil
483
+ end
484
+
485
+
486
+ end #def visitVisitor
487
+ end #module
@@ -0,0 +1,3 @@
1
+ module <%=project_name.capitalize%>
2
+ VERSION="0.0.1"
3
+ end
@@ -0,0 +1,39 @@
1
+ require_relative 'code'
2
+
3
+ module <%=project_name.capitalize%>
4
+
5
+ # here we transform an AST into another AST.
6
+ # we don't use Marshalling.
7
+
8
+ class Visitor
9
+
10
+ attr_accessor :code
11
+
12
+ def initialize
13
+ @verbose=true
14
+ @verbose=false
15
+ end
16
+
17
+ def visit ast
18
+ ast.accept(self)
19
+ end
20
+
21
+ def visitToken tok, args=nil
22
+ Token.new [tok.kind,tok.val,tok.pos]
23
+ end
24
+
25
+ def visitRoot root,args=nil
26
+ root.stmts.each{|stmt| stmt.accept(self)}
27
+ end
28
+
29
+ def visitComment comment,args=nil
30
+ comment
31
+ end
32
+
33
+ def visitIdent ident,args=nil
34
+ token=ident.token.accept(self)
35
+ Ident.new(token)
36
+ end
37
+
38
+ end #def visitVisitor
39
+ end #module