OpenCores
URL https://opencores.org/ocsvn/tcp_socket/tcp_socket/trunk

Subversion Repositories tcp_socket

[/] [tcp_socket/] [trunk/] [chips2/] [chips/] [compiler/] [parse_tree.py] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jondawson
__author__ = "Jon Dawson"
2
__copyright__ = "Copyright (C) 2012, Jonathan P Dawson"
3
__version__ = "0.1"
4
 
5
class NotConstant(Exception):
6
  pass
7
 
8
def value(expression):
9
 
10
  """If an expression can be evaluated at compile time, return the value"""
11
 
12
  if hasattr(expression, "value"):
13
    return truncate(expression.value())
14
  else:
15
    raise NotConstant
16
 
17
def constant_fold(expression):
18
 
19
  """Replace an expression with a constant if possible"""
20
 
21
  try:
22
    return Constant(value(expression))
23
  except NotConstant:
24
    return expression
25
 
26
def truncate(number):
27
 
28
  """Truncate arithmetic results to the target number of bits"""
29
 
30
  #sign = number & 0x10000
31
  #number = number & 0xffff
32
  #if sign:
33
    #number =  ~0xffff | number
34
  return int(number)
35
 
36
class Process:
37
  def generate(self):
38
    instructions = []
39
    for function in self.functions:
40
      if hasattr(function, "declarations"):
41
          instructions.extend(function.generate())
42
    instructions.append({"op"   :"jmp_and_link",
43
                         "dest" :self.main.return_address,
44
                         "label":"function_%s"%id(self.main)})
45
    instructions.append({"op":"stop"})
46
    for function in self.functions:
47
      if not hasattr(function, "declarations"):
48
          instructions.extend(function.generate())
49
    return instructions
50
 
51
class Function:
52
  def generate(self):
53
    instructions = []
54
    instructions.append({"op":"label", "label":"function_%s"%id(self)})
55
    instructions.extend(self.statement.generate())
56
    if not hasattr(self, "return_value"):
57
        instructions.append({"op":"jmp_to_reg", "src":self.return_address})
58
    return instructions
59
 
60
class Break:
61
  def generate(self): return [{"op":"goto", "label":"break_%s"%id(self.loop)}]
62
 
63
class Continue:
64
  def generate(self): return [{"op":"goto", "label":"continue_%s"%id(self.loop)}]
65
 
66
class Assert:
67
  def generate(self):
68
    result = self.allocator.new(self.expression.size)
69
    instructions = self.expression.generate(result)
70
    self.allocator.free(result)
71
    instructions.append({"op":"assert", "src":result, "line":self.line, "file":self.filename})
72
    return instructions
73
 
74
class Return:
75
  def generate(self):
76
    if hasattr(self, "expression"):
77
        instructions = self.expression.generate(self.function.return_value)
78
    else:
79
        instructions = []
80
    instructions.append({"op":"jmp_to_reg", "src":self.function.return_address})
81
    return instructions
82
 
83
class Report:
84
  def generate(self):
85
    result = self.allocator.new(self.expression.size)
86
    instructions = self.expression.generate(result)
87
    self.allocator.free(result)
88
    instructions.append({"op":"report",
89
                         "src":result,
90
                         "line":self.line,
91
                         "file":self.filename,
92
                         "signed":self.expression.signed})
93
    return instructions
94
 
95
class WaitClocks:
96
  def generate(self):
97
    result = self.allocator.new(self.expression.size)
98
    instructions = self.expression.generate(result)
99
    self.allocator.free(result)
100
    instructions.append({"op":"wait_clocks", "src":result})
101
    return instructions
102
 
103
class If:
104
  def generate(self):
105
    try:
106
      if value(self.expression):
107
        return self.true_statement.generate()
108
      else:
109
        if self.false_statement:
110
          return self.false_statement.generate()
111
        else:
112
          return []
113
    except NotConstant:
114
      result = self.allocator.new(self.expression.size)
115
      instructions = []
116
      instructions.extend(self.expression.generate(result))
117
      instructions.append({"op"   :"jmp_if_false",
118
                           "src" :result,
119
                           "label":"else_%s"%id(self)})
120
      self.allocator.free(result)
121
      instructions.extend(self.true_statement.generate())
122
      instructions.append({"op":"goto", "label":"end_%s"%id(self)})
123
      instructions.append({"op":"label", "label":"else_%s"%id(self)})
124
      if self.false_statement:
125
        instructions.extend(self.false_statement.generate())
126
      instructions.append({"op":"label", "label":"end_%s"%id(self)})
127
      return instructions
128
 
129
class Switch:
130
  def generate(self):
131
    result = self.allocator.new(self.expression.size)
132
    test = self.allocator.new(self.expression.size)
133
    instructions = self.expression.generate(result)
134
    for value, case in self.cases.iteritems():
135
      instructions.append({"op":"==", "dest":test, "src":result, "right":value, "signed":True})
136
      instructions.append({"op":"jmp_if_true", "src":test, "label":"case_%s"%id(case)})
137
    if hasattr(self, "default"):
138
      instructions.append({"op":"goto", "label":"case_%s"%id(self.default)})
139
    self.allocator.free(result)
140
    self.allocator.free(test)
141
    instructions.extend(self.statement.generate())
142
    instructions.append({"op":"label", "label":"break_%s"%id(self)})
143
    return instructions
144
 
145
class Case:
146
  def generate(self):
147
    return [{"op":"label", "label":"case_%s"%id(self)}]
148
 
149
class Default:
150
  def generate(self):
151
    return [{"op":"label", "label":"case_%s"%id(self)}]
152
 
153
class Loop:
154
  def generate(self):
155
      instructions = [{"op":"label", "label":"begin_%s"%id(self)}]
156
      instructions.append({"op":"label", "label":"continue_%s"%id(self)})
157
      instructions.extend(self.statement.generate())
158
      instructions.append({"op":"goto", "label":"begin_%s"%id(self)})
159
      instructions.append({"op":"label", "label":"break_%s"%id(self)})
160
      return instructions
161
 
162
class For:
163
  def generate(self):
164
    instructions = []
165
    if hasattr(self, "statement1"):
166
      instructions.extend(self.statement1.generate())
167
    instructions.append({"op":"label", "label":"begin_%s"%id(self)})
168
    if hasattr(self, "expression"):
169
      result = self.allocator.new(self.expression.size)
170
      instructions.extend(self.expression.generate(result))
171
      instructions.append({"op":"jmp_if_false", "src":result, "label":"end_%s"%id(self)})
172
      self.allocator.free(result)
173
    instructions.extend(self.statement3.generate())
174
    instructions.append({"op":"label", "label":"continue_%s"%id(self)})
175
    if hasattr(self, "statement2"):
176
      instructions.extend(self.statement2.generate())
177
    instructions.append({"op":"goto", "label":"begin_%s"%id(self)})
178
    instructions.append({"op":"label", "label":"end_%s"%id(self)})
179
    instructions.append({"op":"label", "label":"break_%s"%id(self)})
180
    return instructions
181
 
182
class Block:
183
  def generate(self):
184
    instructions = []
185
    for statement in self.statements:
186
      instructions.extend(statement.generate())
187
    return instructions
188
 
189
class CompoundDeclaration:
190
  def __init__(self, declarations):
191
    self.declarations = declarations
192
 
193
  def generate(self):
194
    instructions = []
195
    for declaration in self.declarations:
196
      instructions.extend(declaration.generate());
197
    return instructions
198
 
199
class VariableDeclaration:
200
  def __init__(self, allocator, initializer, name, type_, size, signed):
201
    self.initializer = initializer
202
    self.allocator = allocator
203
    self.type_ = type_
204
    self.size = size
205
    self.signed = signed
206
    self.name = name
207
  def instance(self):
208
    register = self.allocator.new(self.size, "variable "+self.name)
209
    return VariableInstance(register, self.initializer, self.type_, self.size, self.signed)
210
 
211
class VariableInstance:
212
  def __init__(self, register, initializer, type_, size, signed):
213
    self.register = register
214
    self.type_ = type_
215
    self.initializer = initializer
216
    self.size = size
217
    self.signed = signed
218
  def generate(self):
219
    return self.initializer.generate(self.register)
220
 
221
class ArrayDeclaration:
222
  def __init__(self,
223
               allocator,
224
               size,
225
               type_,
226
               element_type,
227
               element_size,
228
               element_signed,
229
               initializer = None,
230
               initialize_memory = False):
231
 
232
    self.allocator = allocator
233
    self.type_ = type_
234
    self.size = size
235
    self.signed = False
236
    self.element_type = element_type
237
    self.element_size = element_size
238
    self.element_signed = element_signed
239
    self.initializer = initializer
240
    self.initialize_memory = initialize_memory
241
 
242
  def instance(self):
243
    location = self.allocator.new_array(self.size, self.initializer, self.element_size)
244
    register = self.allocator.new(2, "array")
245
    return ArrayInstance(location,
246
                         register,
247
                         self.size,
248
                         self.type_,
249
                         self.initializer,
250
                         self.initialize_memory,
251
                         self.element_type,
252
                         self.element_size,
253
                         self.element_signed)
254
 
255
class ArrayInstance:
256
  def __init__(self,
257
               location,
258
               register,
259
               size,
260
               type_,
261
               initializer,
262
               initialize_memory,
263
               element_type,
264
               element_size,
265
               element_signed):
266
 
267
    self.register = register
268
    self.location = location
269
    self.type_ = type_
270
    self.size = size
271
    self.signed = False
272
    self.element_type = element_type
273
    self.element_size = element_size
274
    self.element_signed = element_signed
275
    self.initializer = initializer
276
    self.initialize_memory = initialize_memory
277
 
278
  def generate(self, result=None):
279
      instructions = []
280
      #If initialize memory is true, the memory content will initialised (as at configuration time)
281
      #If initialize memory is false, then the memory will need to be filled by the program.
282
      if not self.initialize_memory and self.initializer is not None:
283
          location = 0
284
          for value in self.initializer:
285
              instructions.append({
286
                  "op":"memory_write_literal",
287
                  "address":location,
288
                  "value":value,
289
                  "element_size":self.element_size
290
              })
291
              location += 1
292
      instructions.append({
293
          "op":"literal",
294
          "literal":self.location,
295
          "dest":self.register
296
      })
297
      #this bit here is to make string literals work, 
298
      #in this case an array instance is created implicitly, 
299
      #but the value of the expression is the array register.
300
      if result is not None and result != self.register:
301
          instructions.append({
302
              "op"  :"move",
303
              "dest":result,
304
              "src" :self.register
305
          })
306
      return instructions
307
 
308
class StructDeclaration:
309
  def __init__(self, members):
310
    self.members = members
311
 
312
  def instance(self):
313
    instances = {}
314
    for name, declaration in self.members.iteritems():
315
      instances[name] = declaration.instance()
316
    return StructInstance(instances)
317
 
318
class StructInstance:
319
  def __init__(self, members):
320
    self.members = members
321
    self.type_ = "struct"
322
 
323
  def generate(self):
324
    instructions = []
325
    for member in self.members.values():
326
      instructions.extend(member.generate())
327
    return instructions
328
 
329
class Argument:
330
  def __init__(self,
331
        name,
332
        type_,
333
        size,
334
        signed,
335
        parser,
336
        element_type,
337
        element_size,
338
        element_signed):
339
    self.type_=type_
340
    self.size=size
341
    self.signed=signed
342
    self.element_type = element_type
343
    self.element_size = element_size
344
    self.element_signed = element_signed
345
    parser.scope[name] = self
346
    self.register = parser.allocator.new(size, "function argument "+name)
347
  def generate(self): return []
348
 
349
class DiscardExpression:
350
  def __init__(self, expression, allocator):
351
    self.expression = expression
352
    self.allocator = allocator
353
 
354
  def generate(self):
355
    result = self.allocator.new(self.expression.size)
356
    instructions = self.expression.generate(result)
357
    self.allocator.free(result)
358
    return instructions
359
 
360
#...then Expressions...
361
 
362
#Expressions generate methods accept a result argument.
363
#This indicates which register to put the result in.
364
 
365
#Expressions may also provide a value method which returns the value of an xpression
366
#if it can be calculated at compile time.
367
 
368
def AND(left, right):
369
  return ANDOR(left, right, "jmp_if_false")
370
 
371
def OR(left, right):
372
  return ANDOR(left, right, "jmp_if_true")
373
 
374
class ANDOR:
375
  def __init__(self, left, right, op):
376
    self.left = constant_fold(left)
377
    self.right = constant_fold(right)
378
    self.op = op
379
    self.type_ = "int"
380
    self.size = left.size
381
    self.signed = left.signed
382
 
383
  def generate(self, result):
384
    instructions = self.left.generate(result)
385
    instructions.append({"op":self.op, "src":result, "label":"end_%s"%id(self)})
386
    instructions.extend(self.right.generate(result))
387
    instructions.append({"op":"label", "label":"end_%s"%id(self)})
388
    return instructions
389
 
390
  def value(self):
391
    if self.op == "jmp_if_false":
392
      return value(self.left) and value(self.right)
393
    else:
394
      return value(self.left) or value(self.right)
395
 
396
class Binary:
397
  def __init__(self, operator, left, right, allocator):
398
    self.left = constant_fold(left)
399
    self.right = constant_fold(right)
400
    self.operator = operator
401
    self.allocator = allocator
402
    self.type_ = self.left.type_
403
    self.size = max(left.size, right.size)
404
    self.signed = left.signed and right.signed
405
 
406
  def generate(self, result):
407
    new_register = self.allocator.new(self.size)
408
    try:
409
      instructions = self.right.generate(new_register)
410
      instructions.append({"op"  :self.operator,
411
                           "dest":result,
412
                           "left":value(self.left),
413
                           "src":new_register,
414
                           "signed":self.signed})
415
    except NotConstant:
416
      try:
417
        instructions = self.left.generate(new_register)
418
        instructions.append({"op"   :self.operator,
419
                             "dest" :result,
420
                             "src"  :new_register,
421
                             "right":value(self.right),
422
                             "signed" :self.signed})
423
      except NotConstant:
424
        instructions = self.left.generate(new_register)
425
        right = self.allocator.new(self.right.size)
426
        instructions.extend(self.right.generate(right))
427
        instructions.append({"op"  :self.operator,
428
                             "dest":result,
429
                             "src" :new_register,
430
                             "srcb":right,
431
                             "signed":self.signed})
432
        self.allocator.free(right)
433
    self.allocator.free(new_register)
434
    return instructions
435
 
436
  def value(self):
437
    return eval("%s %s %s"%(value(self.left), self.operator, value(self.right)))
438
 
439
def SizeOf(expression):
440
    return Constant(expression.size)
441
 
442
class Unary:
443
  def __init__(self, operator, expression, allocator):
444
    self.expression = constant_fold(expression)
445
    self.operator = operator
446
    self.type_ = self.expression.type_
447
    self.size = expression.size
448
    self.signed = expression.signed
449
    self.allocator = allocator
450
 
451
  def generate(self, result):
452
    new_register = self.allocator.new(self.size)
453
    instructions = self.expression.generate(new_register)
454
    instructions.extend([{"op":self.operator, "dest":result, "src":new_register}])
455
    self.allocator.free(new_register)
456
    return instructions
457
 
458
  def value(self):
459
    return eval("%s%s"%(self.operator, value(self.expression)))
460
 
461
class FunctionCall:
462
  def generate(self, result):
463
    instructions = []
464
    for expression, argument in zip(self.arguments, self.function.arguments):
465
      instructions.extend(expression.generate(argument.register))
466
    instructions.append({"op"   :"jmp_and_link",
467
                         "dest" :self.function.return_address,
468
                         "label":"function_%s"%id(self.function)})
469
    if hasattr(self.function, "return_value"):
470
        instructions.append({"op"   :"move",
471
                             "dest" :result,
472
                             "src"  :self.function.return_value})
473
    return instructions
474
 
475
class Output:
476
  def __init__(self, name, expression):
477
    self.name = name
478
    self.expression = expression
479
    self.type_ = "int"
480
    self.size = expression.size
481
 
482
  def generate(self, result):
483
    instructions = self.expression.generate(result);
484
    instructions.append({"op"   :"write", "src"  :result, "output":self.name})
485
    return instructions
486
 
487
class FileWrite:
488
  def __init__(self, name, expression):
489
    self.name = name
490
    self.expression = expression
491
    self.type_ = "int"
492
    self.size = expression.size
493
 
494
  def generate(self, result):
495
    instructions = self.expression.generate(result);
496
    instructions.append({"op"   :"file_write", "src"  :result, "file_name":self.name})
497
    return instructions
498
 
499
class Input:
500
  def __init__(self, name):
501
    self.name = name
502
    self.type_ = "int"
503
    self.size = 2
504
    self.signed = True
505
 
506
  def generate(self, result):
507
      return [{"op"   :"read", "dest" :result, "input":self.name}]
508
 
509
class FileRead:
510
  def __init__(self, name):
511
    self.name = name
512
    self.type_ = "int"
513
    self.size = 2
514
    self.signed = True
515
 
516
  def generate(self, result):
517
      return [{"op"   :"file_read", "dest" :result, "file_name":self.name}]
518
 
519
class Ready:
520
  def __init__(self, name):
521
    self.name = name
522
    self.type_ = "int"
523
    self.size = 2
524
    self.signed = True
525
 
526
  def generate(self, result):
527
      return [{"op"   :"ready", "dest" :result, "input":self.name}]
528
 
529
class Array:
530
  def __init__(self, declaration, allocator):
531
    self.declaration = declaration
532
    self.allocator = allocator
533
    self.storage = "register"
534
    self.type_ = self.declaration.type_
535
    self.size = int(self.declaration.size) * 2
536
    self.signed = False
537
 
538
  def generate(self, result):
539
    instructions = []
540
    if result != self.declaration.register:
541
      instructions.append({"op"  :"move",
542
                           "dest":result,
543
                           "src" :self.declaration.register})
544
    return instructions
545
 
546
class ArrayIndex:
547
  def __init__(self, declaration, index_expression, allocator):
548
    self.declaration = declaration
549
    self.allocator = allocator
550
    self.index_expression = index_expression
551
    self.storage = "memory"
552
    self.type_  = self.declaration.element_type
553
    self.size   = self.declaration.element_size
554
    self.signed = self.declaration.element_signed
555
 
556
  def generate(self, result):
557
    instructions = []
558
    offset = self.allocator.new(2)
559
    address = self.allocator.new(2)
560
    instructions.extend(self.index_expression.generate(offset))
561
    instructions.append({"op"    :"+",
562
                         "dest"  :address,
563
                         "src"   :offset,
564
                         "srcb"  :self.declaration.register,
565
                         "signed":False})
566
    instructions.append({"op"    :"memory_read_request",
567
                         "src"   :address,
568
                         "sequence": id(self),
569
                         "element_size":self.size})
570
    instructions.append({"op"    :"memory_read_wait",
571
                         "src"   :address,
572
                         "sequence": id(self),
573
                         "element_size":self.size})
574
    instructions.append({"op"    :"memory_read",
575
                         "src"   :address,
576
                         "dest"  :result,
577
                         "sequence": id(self),
578
                         "element_size":self.size})
579
    self.allocator.free(address)
580
    self.allocator.free(offset)
581
    return instructions
582
 
583
class Variable:
584
  def __init__(self, declaration, allocator):
585
    self.declaration = declaration
586
    self.allocator = allocator
587
    self.storage = "register"
588
    self.type_ = self.declaration.type_
589
    self.size = self.declaration.size
590
    self.signed = self.declaration.signed
591
 
592
  def generate(self, result):
593
    instructions = []
594
    if result != self.declaration.register:
595
      instructions.append({"op"  :"move",
596
                           "dest":result,
597
                           "src" :self.declaration.register})
598
    return instructions
599
 
600
class PostIncrement:
601
  def  __init__(self, operator, lvalue, allocator):
602
    self.operator = operator
603
    self.lvalue = lvalue
604
    self.allocator = allocator
605
    self.type_ = self.lvalue.declaration.type_
606
    self.size = self.lvalue.declaration.size
607
    self.signed = self.lvalue.declaration.signed
608
 
609
  def generate(self, result):
610
 
611
    instructions = []
612
 
613
    instructions.append({"op"    :"move",
614
                         "src"   :self.lvalue.declaration.register,
615
                         "dest"  :result})
616
 
617
    instructions.append({"op"    :self.operator,
618
                         "dest"  :self.lvalue.declaration.register,
619
                         "right" :1,
620
                         "src"   :self.lvalue.declaration.register,
621
                         "signed":self.signed})
622
 
623
    return instructions
624
 
625
class Assignment:
626
  def __init__(self, lvalue, expression, allocator):
627
    self.lvalue = lvalue
628
    self.expression = expression
629
    self.allocator = allocator
630
    self.type_ = self.lvalue.type_
631
    self.size = self.lvalue.size
632
    self.signed = self.lvalue.signed
633
 
634
  def generate(self, result):
635
    instructions = self.expression.generate(result)
636
    if self.lvalue.storage == "register":
637
      if result != self.lvalue.declaration.register:
638
        instructions.append({"op"   : "move",
639
                             "dest" : self.lvalue.declaration.register,
640
                             "src"  : result})
641
 
642
    elif self.lvalue.storage == "memory":
643
      index = self.allocator.new(2)
644
      address = self.allocator.new(2)
645
      instructions.extend(self.lvalue.index_expression.generate(index))
646
      instructions.append({"op"     :"+",
647
                           "dest"   :address,
648
                           "src"    :index,
649
                           "srcb"   :self.lvalue.declaration.register,
650
                           "signed" :self.signed})
651
      instructions.append({"op"    :"memory_write",
652
                           "src"   :address,
653
                           "srcb"  :result,
654
                           "element_size" :self.lvalue.declaration.element_size})
655
      self.allocator.free(index)
656
      self.allocator.free(address)
657
 
658
    return instructions
659
 
660
class Constant:
661
  def __init__(self, value, size=2, signed=True):
662
    self._value = value
663
    self.type_ = "int"
664
    self.size = size
665
    self.signed = signed
666
 
667
  def generate(self, result):
668
    instructions = [{"op":"literal", "dest":result, "literal":self._value}]
669
    return instructions
670
 
671
  def value(self):
672
    return self._value

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.