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

Subversion Repositories tcp_socket

[/] [tcp_socket/] [trunk/] [chips2/] [chips/] [compiler/] [parser.py] - Blame information for rev 4

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 4 jondawson
import struct
6
from copy import copy
7
 
8 2 jondawson
from parse_tree import *
9
from tokens import Tokens
10
from allocator import Allocator
11
 
12 4 jondawson
types = ["float", "signed", "unsigned", "short", "long", "char", "int", "void"]
13
numeric_types = ["float", "signed", "unsigned", "short", "long", "char", "int"]
14
storage_specifiers = ["const"]
15
 
16 2 jondawson
class Parser:
17
 
18
    """Turn the C input file into a tree of expressions and statements."""
19
 
20
    def __init__(self, input_file, reuse, initialize_memory):
21
        self.scope = {}
22
        self.function = None
23
        self.loop = None
24
        self.tokens = Tokens(input_file)
25
        self.allocator = Allocator(reuse)
26
        self.structs = []
27
        self.initialize_memory = initialize_memory
28
 
29
    def parse_process(self):
30
        process = Process()
31
        process.allocator = self.allocator
32
        process.inputs = []
33
        process.outputs = []
34
        process.functions = []
35
        while not self.tokens.end():
36
            if self.tokens.peek() == "struct":
37
                self.parse_define_struct()
38
            elif self.tokens.peek() == "typedef":
39
                self.parse_typedef_struct()
40
            else:
41
                process.functions.append(self.parse_function())
42
        process.main = self.main
43
        return process
44
 
45
    def parse_type_specifier(self):
46
        type_specifiers = []
47
 
48 4 jondawson
        while self.tokens.peek() in types + self.structs + storage_specifiers:
49 2 jondawson
            type_specifiers.append(self.tokens.get())
50
 
51
        signed = True
52
        if "unsigned" in type_specifiers:
53
            signed = False
54
            if "signed" in type_specifiers:
55
                self.tokens.error("Cannot be signed and unsigned")
56
 
57
        size = 2
58
        if "long" in type_specifiers:
59
            if "short" in type_specifiers:
60
                self.tokens.error("Cannot be long and short")
61
            size = 4
62
 
63
        type_ = "int"
64
        for i in type_specifiers:
65
            if i in self.structs:
66
                type_ = i
67
                size = 2
68
                signed = False
69
 
70 4 jondawson
        if "float" in type_specifiers:
71
            if "short" in type_specifiers:
72
                self.tokens.error("Float cannot be short")
73
            if "long" in type_specifiers:
74
                self.tokens.error("Float cannot be long (but double can)")
75
            if "unsigned" in type_specifiers:
76
                self.tokens.error("Float cannot be unsigned")
77
            type_ = "float"
78
            size = 4
79
            signed = True
80
 
81
        const = False
82
        if "const" in type_specifiers:
83
            const = True
84
 
85 2 jondawson
        if "void" in type_specifiers:
86
            type_ = "void"
87
            size = 2
88
            signed = False
89
 
90
 
91 4 jondawson
        return type_, size, signed, const
92 2 jondawson
 
93 4 jondawson
    def parse_argument(self):
94
        type_, size, signed, const = self.parse_type_specifier()
95
 
96
        if type_ in ["void"]:
97
            self.tokens.error("argument cannot be void")
98
        else:
99
            argument = self.tokens.get()
100
            if type_ in self.structs:
101
                declaration = self.scope[type_]
102
            else:
103
                if self.tokens.peek() == "[":
104
                    self.tokens.expect("[")
105
                    self.tokens.expect("]")
106
                    declaration = ArrayDeclaration(
107
                        self.allocator,
108
                        2,
109
                        type_+"[]",
110
                        type_,
111
                        size,
112
                        signed,
113
                        None,
114
                        self.initialize_memory)
115
                else:
116
                    declaration = VariableDeclaration(
117
                        self.allocator,
118
                        None,
119
                        argument,
120
                        type_,
121
                        size,
122
                        signed,
123
                        const)
124
        instance = declaration.instance()
125
        self.scope[argument] = instance
126
        return instance.reference()
127
 
128 2 jondawson
    def parse_function(self):
129
        function = Function()
130
        function.allocator = self.allocator
131 4 jondawson
        stored_scope = copy(self.scope)
132
        type_, size, signed, const = self.parse_type_specifier()
133 2 jondawson
        name = self.tokens.get()
134 4 jondawson
 
135 2 jondawson
        #check if it is a global declaration
136
        if self.tokens.peek() != "(":
137 4 jondawson
            return self.parse_global_declaration(type_, size, signed, const, name)
138 2 jondawson
 
139
        #otherwise continue parsing a function
140
        self.tokens.expect("(")
141
        function.name = name
142
        function.type_ = type_
143
        function.size = size
144
        function.signed = signed
145 4 jondawson
 
146
        function.return_address = self.allocator.new(2,
147
            function.name+" return address")
148
 
149 2 jondawson
        if type_ != "void":
150 4 jondawson
 
151
            if type_ in self.structs:
152
                declaration = self.scope[type_]
153
            else:
154
                if self.tokens.peek() == "[":
155
                    self.tokens.error(
156
                        "Functions cannot return arrays")
157
                else:
158
                    declaration = VariableDeclaration(
159
                        self.allocator,
160
                        None,
161
                        function.name+" return value",
162
                        type_,
163
                        size,
164
                        signed,
165
                        const)
166
 
167
            function.return_value = declaration.instance().reference()
168
 
169 2 jondawson
        function.arguments = []
170
        while self.tokens.peek() != ")":
171 4 jondawson
            function.arguments.append(self.parse_argument())
172 2 jondawson
            if self.tokens.peek() == ",":
173
                self.tokens.expect(",")
174
            else:
175
                break
176 4 jondawson
 
177 2 jondawson
        self.tokens.expect(")")
178
        self.function = function
179
        function.statement = self.parse_statement()
180
        if type_ != "void" and not hasattr(function, "return_statement"):
181
            self.tokens.error("Function must have a return statement")
182
        self.function = None
183
        self.scope = stored_scope
184
        self.scope[function.name] = function
185
        #main thread is last function
186
        self.main = function
187
        return function
188
 
189
    def parse_break(self):
190
        break_ = Break()
191
        break_.loop = self.loop
192
        self.tokens.expect("break")
193
        self.tokens.expect(";")
194
        return break_
195
 
196
    def parse_continue(self):
197
        continue_ = Continue()
198
        continue_.loop = self.loop
199
        self.tokens.expect("continue")
200
        self.tokens.expect(";")
201
        return continue_
202
 
203
    def parse_return(self):
204
        return_ = Return()
205
        return_.function = self.function
206 4 jondawson
        return_.allocator = self.allocator
207 2 jondawson
        self.function.return_statement = return_
208
        self.tokens.expect("return")
209
        if hasattr(self.function, "return_value"):
210
            return_.expression = self.parse_expression()
211
        self.tokens.expect(";")
212
        return return_
213
 
214
    def parse_assert(self):
215
        assert_ = Assert()
216
        assert_.allocator = self.allocator
217
        self.tokens.expect("assert")
218
        self.tokens.expect("(")
219
        assert_.expression = self.parse_expression()
220
        self.tokens.expect(")")
221
        self.tokens.expect(";")
222
        assert_.line = self.tokens.lineno
223
        assert_.filename = self.tokens.filename
224
        return assert_
225
 
226
    def parse_report(self):
227
        report_ = Report()
228
        report_.allocator = self.allocator
229
        self.tokens.expect("report")
230
        self.tokens.expect("(")
231
        report_.expression = self.parse_expression()
232
        self.tokens.expect(")")
233
        self.tokens.expect(";")
234
        report_.line = self.tokens.lineno
235
        report_.filename = self.tokens.filename
236
        return report_
237
 
238
    def parse_wait_clocks(self):
239
        wait_clocks = WaitClocks()
240
        wait_clocks.allocator = self.allocator
241
        self.tokens.expect("wait_clocks")
242
        self.tokens.expect("(")
243
        wait_clocks.expression = self.parse_expression()
244
        self.tokens.expect(")")
245
        self.tokens.expect(";")
246
        wait_clocks.line = self.tokens.lineno
247
        return wait_clocks
248
 
249
    def parse_statement(self):
250 4 jondawson
        if self.tokens.peek() in numeric_types + self.structs + storage_specifiers:
251 2 jondawson
            return self.parse_compound_declaration()
252
        elif self.tokens.peek() == "struct":
253
            return self.parse_struct_declaration()
254
        elif self.tokens.peek() == "if":
255
            return self.parse_if()
256
        elif self.tokens.peek() == "while":
257
            return self.parse_while()
258
        elif self.tokens.peek() == "for":
259
            return self.parse_for()
260
        elif self.tokens.peek() == "return":
261
            return self.parse_return()
262
        elif self.tokens.peek() == "break":
263
            return self.parse_break()
264
        elif self.tokens.peek() == "continue":
265
            return self.parse_continue()
266
        elif self.tokens.peek() == "{":
267
            return self.parse_block()
268
        elif self.tokens.peek() == "assert":
269
            return self.parse_assert()
270
        elif self.tokens.peek() == "report":
271
            return self.parse_report()
272
        elif self.tokens.peek() == "switch":
273
            return self.parse_switch()
274
        elif self.tokens.peek() == "case":
275
            return self.parse_case()
276
        elif self.tokens.peek() == "default":
277
            return self.parse_default()
278
        elif self.tokens.peek() == "wait_clocks":
279
            return self.parse_wait_clocks()
280
        else:
281
            expression = self.parse_discard()
282
            self.tokens.expect(";")
283
            return expression
284
 
285
    def parse_discard(self):
286
        return DiscardExpression(self.parse_expression(), self.allocator)
287
 
288
    def parse_assignment(self):
289
        assignment_operators = [
290 4 jondawson
            "=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>="
291 2 jondawson
        ]
292
        lvalue = self.parse_ternary_expression()
293
        if self.tokens.peek() in assignment_operators:
294 4 jondawson
            if lvalue.const():
295
 
296 2 jondawson
                self.tokens.error(
297 4 jondawson
                    "left hand operand of assignment is not modifiable")
298
 
299 2 jondawson
            operator = self.tokens.get()
300
            if operator == "=":
301
                expression = self.parse_ternary_expression()
302
            else:
303 4 jondawson
 
304
                expression = self.parse_ternary_expression()
305
                left = lvalue
306
                left, expression = self.coerce_types(left, expression)
307
                expression = Binary(operator[:-1], left, expression)
308
 
309
            if expression.type_() != lvalue.type_():
310
                if expression.type_() == "int" and lvalue.type_() == "float":
311
                    expression = IntToFloat(expression)
312
                elif expression.type_() == "float" and lvalue.type_() == "int":
313
                    expression = FloatToInt(expression)
314
                else:
315
                    self.tokens.error(
316
                        "type mismatch in assignment expected: %s actual: %s"%(
317
                            lvalue.type_(),
318
                            expression.type_()))
319
 
320 2 jondawson
            return Assignment(lvalue, expression, self.allocator)
321
        else:
322
            return lvalue
323
 
324
    def parse_if(self):
325
        if_ = If()
326
        if_.allocator = self.allocator
327
        self.tokens.expect("if")
328
        self.tokens.expect("(")
329
        if_.expression = self.parse_expression()
330 4 jondawson
        if if_.expression.type_() not in ["unsigned", "int", "short", "long", "char"]:
331 2 jondawson
            self.tokens.error(
332 4 jondawson
                "if statement conditional must be an integer like expression")
333 2 jondawson
        self.tokens.expect(")")
334
        if_.true_statement = self.parse_statement()
335
        if self.tokens.peek() == "else":
336
            self.tokens.expect("else")
337
            if_.false_statement = self.parse_statement()
338
        else:
339
            if_.false_statement = None
340
        return if_
341
 
342
    def parse_switch(self):
343
        switch = Switch()
344
        switch.cases = {}
345
        self.tokens.expect("switch")
346
        self.tokens.expect("(")
347
        expression = self.parse_expression()
348 4 jondawson
        if expression.type_() not in ["unsigned", "int", "short", "long", "char"]:
349 2 jondawson
            self.tokens.error(
350 4 jondawson
                "switch statement expression must be an integer like expression")
351 2 jondawson
        self.tokens.expect(")")
352
        stored_loop = self.loop
353
        self.loop = switch
354
        statement = self.parse_statement()
355
        self.loop = stored_loop
356
        switch.expression = expression
357
        switch.allocator = self.allocator
358
        switch.statement = statement
359
        return switch
360
 
361
    def parse_case(self):
362
        self.tokens.expect("case")
363
        expression = self.parse_expression()
364 4 jondawson
        if expression.type_() not in ["int"]:
365 2 jondawson
            self.tokens.error(
366 4 jondawson
                "case expression must be an integer like expression")
367 2 jondawson
        self.tokens.expect(":")
368
        try:
369 4 jondawson
            expression = expression.value()
370 2 jondawson
            case = Case()
371 4 jondawson
            self.loop.cases[expression] = case
372 2 jondawson
        except NotConstant:
373
            self.tokens.error("case expression must be constant")
374
        except AttributeError:
375
            self.tokens.error(
376 4 jondawson
                "case statements may only be use inside a switch statment")
377 2 jondawson
        return case
378
 
379
    def parse_default(self):
380
        self.tokens.expect("default")
381
        self.tokens.expect(":")
382
        default = Default()
383
        if not hasattr(self.loop, "cases"):
384
            self.tokens.error(
385 4 jondawson
                "default statements may only be used inside a switch statment")
386 2 jondawson
        if hasattr(self.loop, "default"):
387
            self.tokens.error(
388 4 jondawson
                "A switch statement may only have one default statement")
389 2 jondawson
        self.loop.default=default
390
        return default
391
 
392
    def parse_while(self):
393
        loop = Loop()
394
        self.tokens.expect("while")
395
        self.tokens.expect("(")
396
        expression = self.parse_expression()
397
        self.tokens.expect(")")
398
        stored_loop = self.loop
399
        self.loop = loop
400
        statement = self.parse_statement()
401
        self.loop = stored_loop
402
 
403
        if_ = If()
404
        loop.statement = if_
405
        break_ = Break()
406
        break_.loop = loop
407
        if_.allocator = self.allocator
408 4 jondawson
        if expression.type_() not in ["int"]:
409 2 jondawson
            self.tokens.error(
410 4 jondawson
                "while statement conditional must be an integer like expression")
411 2 jondawson
        if_.expression = expression
412
        if_.false_statement = break_
413
        if_.true_statement = statement
414
 
415
        return loop
416
 
417
    def parse_for(self):
418
        for_ = For()
419
        for_.allocator = self.allocator
420
        self.tokens.expect("for")
421
        self.tokens.expect("(")
422
        if self.tokens.peek() != ";":
423
            for_.statement1 = self.parse_discard()
424
        self.tokens.expect(";")
425
        if self.tokens.peek() != ";":
426
            for_.expression = self.parse_expression()
427 4 jondawson
            if for_.expression.type_() not in [
428
                "unsigned",
429
                "int",
430
                "short",
431
                "long",
432
                "char"]:
433
 
434 2 jondawson
                self.tokens.error(
435 4 jondawson
            "For statement conditional must be an integer like expression")
436
 
437 2 jondawson
        self.tokens.expect(";")
438
        if self.tokens.peek() != ")":
439
            for_.statement2 = self.parse_discard()
440
        self.tokens.expect(")")
441
        stored_loop = self.loop
442
        self.loop = for_
443
        for_.statement3 = self.parse_statement()
444
        self.loop = stored_loop
445
        return for_
446
 
447
    def parse_block(self):
448
        block = Block()
449 4 jondawson
        stored_scope = copy(self.scope)
450 2 jondawson
        self.tokens.expect("{")
451
        block.statements = []
452
        while self.tokens.peek() != "}":
453
            block.statements.append(self.parse_statement())
454
        self.tokens.expect("}")
455
        self.scope = stored_scope
456
        return block
457
 
458
    def parse_struct_body(self):
459
        self.tokens.expect("{")
460
        members = {}
461
        while self.tokens.peek() != "}":
462 4 jondawson
            type_, size, signed, const = self.parse_type_specifier()
463 2 jondawson
            name = self.tokens.get()
464 4 jondawson
 
465
            members[name] = self.parse_declaration(
466
                type_,
467
                size,
468
                signed,
469
                const,
470
                name)
471
 
472 2 jondawson
            self.tokens.expect(";")
473
        self.tokens.expect("}")
474
        return members
475
 
476
    def parse_typedef_struct(self):
477
        self.tokens.expect("typedef")
478
        self.tokens.expect("struct")
479
        declaration = StructDeclaration(self.parse_struct_body())
480
        name = self.tokens.get()
481
        self.tokens.expect(";")
482
        self.scope[name] = declaration
483
        self.structs.append(name)
484
 
485
    def parse_define_struct(self):
486
        self.tokens.expect("struct")
487
        name = self.tokens.get()
488
        declaration = StructDeclaration(self.parse_struct_body())
489
        self.tokens.expect(";")
490
        self.scope[name] = declaration
491
 
492
    def parse_struct_declaration(self):
493
        self.tokens.expect("struct")
494
        struct_name = self.tokens.get()
495
        name = self.tokens.get()
496
        self.tokens.expect(";")
497
        instance = self.scope[struct_name].instance()
498
        self.scope[name] = instance
499
        return instance
500
 
501 4 jondawson
    def parse_global_declaration(self, type_, size, signed, const, name):
502 2 jondawson
        instances = []
503
        while True:
504 4 jondawson
 
505
            instance = self.parse_declaration(
506
                type_,
507
                size,
508
                signed,
509
                const,
510
                name).instance()
511
 
512 2 jondawson
            self.scope[name] = instance
513
            instances.append(instance)
514
            if self.tokens.peek() == ",":
515
                self.tokens.expect(",")
516
            else:
517
                break
518
            name = self.tokens.get()
519
        self.tokens.expect(";")
520
        return CompoundDeclaration(instances)
521
 
522
    def parse_compound_declaration(self):
523 4 jondawson
        type_, size, signed, const = self.parse_type_specifier()
524 2 jondawson
        instances = []
525
        while True:
526
            name = self.tokens.get()
527 4 jondawson
 
528
            instance = self.parse_declaration(
529
                type_,
530
                size,
531
                signed,
532
                const,
533
                name).instance()
534
 
535 2 jondawson
            self.scope[name] = instance
536
            instances.append(instance)
537
            if self.tokens.peek() == ",":
538
                self.tokens.expect(",")
539
            else:
540
                break
541
            name = None
542
        self.tokens.expect(";")
543
        return CompoundDeclaration(instances)
544
 
545 4 jondawson
    def parse_declaration(self, type_, size, signed, const, name):
546 2 jondawson
        #struct declaration
547
        if type_ in self.structs:
548
            declaration = self.scope[type_]
549 4 jondawson
        elif type_ in ["int", "float"]:
550
            #array declaration
551 2 jondawson
            if self.tokens.peek() == "[":
552
                array_size = None
553
                self.tokens.expect("[")
554
                if self.tokens.peek() != "]":
555 4 jondawson
                    size_expression = self.parse_ternary_expression()
556
                    if size_expression.type_() != "int":
557
                        self.tokens.error("Array size must be an integer like expression")
558
                    try:
559
                        array_size = size_expression.value()
560
                    except NotConstant:
561
                        self.tokens.error("Array size must be constant")
562
 
563 2 jondawson
                self.tokens.expect("]")
564
                initializer = None
565
                if self.tokens.peek() == "=":
566
                    self.tokens.expect("=")
567
                    initializer = self.tokens.get()
568
                    initializer = [ord(i) for i in initializer.strip('"').decode("string_escape")] + [0]
569
                    array_size = len(initializer)
570
                if array_size is None:
571 4 jondawson
 
572
                    self.tokens.error(
573
                        "array size must be specified if not initialized")
574
 
575 2 jondawson
                array_type=type_+"[]"
576
                initialize_memory = self.initialize_memory
577 4 jondawson
                declaration = ArrayDeclaration(
578
                    self.allocator,
579
                    array_size,
580
                    array_type,
581
                    type_,
582
                    size,
583
                    signed,
584
                    initializer,
585
                    self.initialize_memory)
586 2 jondawson
 
587 4 jondawson
            #simple variable declaration
588 2 jondawson
            else:
589
                if self.tokens.peek() == "=":
590
                    self.tokens.expect("=")
591
                    initializer = self.parse_ternary_expression()
592
                else:
593 4 jondawson
                    initializer = Constant(0, type_, size, signed)
594
 
595
                if type_ != initializer.type_():
596
 
597
                    if type_ == "int" and initializer.type_() == "float":
598
                        initializer = FloatToInt(initializer)
599
                    elif type_ == "float" and initializer.type_() == "int":
600
                        initializer = IntToFloat(initializer)
601
                    else:
602
                        self.tokens.error(
603
                            "type mismatch in intializer expected: %s actual: %s"%(
604
                                type_,
605
                                intitializer.type_()))
606 2 jondawson
                declaration = VariableDeclaration(
607 4 jondawson
                    self.allocator,
608
                    initializer,
609 2 jondawson
                    name,
610
                    type_,
611
                    size,
612 4 jondawson
                    signed,
613
                    const
614 2 jondawson
                )
615
 
616
        return declaration
617
 
618
    def parse_expression(self):
619
        expression = self.parse_assignment()
620
        return expression
621
 
622
    def parse_ternary_expression(self):
623
        expression = constant_fold(self.parse_or_expression())
624
        while self.tokens.peek() in ["?"]:
625
            self.tokens.expect("?")
626
            true_expression = constant_fold(self.parse_or_expression())
627
            self.tokens.expect(":")
628
            false_expression = constant_fold(self.parse_or_expression())
629
            expression = OR(AND(expression, true_expression), false_expression)
630
        return expression
631
 
632
    def parse_or_expression(self):
633
        expression = self.parse_and_expression()
634
        while self.tokens.peek() in ["||"]:
635
            self.tokens.expect("||")
636
            expression = OR(expression, self.parse_and_expression())
637
        return expression
638
 
639
    def parse_and_expression(self):
640
        expression = self.parse_binary_expression(["|"])
641
        while self.tokens.peek() in ["&&"]:
642
            self.tokens.expect("&&")
643
            expression = AND(expression, self.parse_binary_expression(["|"]))
644
        return expression
645
 
646 4 jondawson
    def substitute_function(self, binary_expression):
647
 
648
        """
649
        For some operations are more easily implemented in sofftware.
650
        This function substitutes a call to the builtin library function.
651
        """
652
 
653
        functions = {
654
           "False,int,int,4,/" : "long_unsigned_divide_xxxx",
655
           "True,int,int,4,/" : "long_divide_xxxx",
656
           "False,int,int,2,/" : "unsigned_divide_xxxx",
657
           "True,int,int,2,/" : "divide_xxxx",
658
           "False,int,int,4,%" : "long_unsigned_modulo_xxxx",
659
           "True,int,int,4,%" : "long_modulo_xxxx",
660
           "False,int,int,2,%" : "unsigned_modulo_xxxx",
661
           "True,int,int,2,%" : "modulo_xxxx",
662
           "True,float,float,4,==" : "float_equal_xxxx",
663
           "True,float,float,4,!=" : "float_ne_xxxx",
664
           "True,float,float,4,<" : "float_lt_xxxx",
665
           "True,float,float,4,>" : "float_gt_xxxx",
666
           "True,float,float,4,<=" : "float_le_xxxx",
667
           "True,float,float,4,>=" : "float_ge_xxxx",
668
        }
669
 
670
        #select a function that matches the template.
671
        signature = ",".join([
672
            str(binary_expression.signed()),
673
            binary_expression.left.type_(),
674
            binary_expression.right.type_(),
675
            str(binary_expression.size()),
676
            binary_expression.operator])
677
 
678 2 jondawson
        #Some things can't be implemented in verilog, substitute them with a function
679 4 jondawson
        if signature in functions:
680
            function = self.scope[functions[signature]]
681
            function_call = FunctionCall(function)
682
            function_call.arguments = [binary_expression.left, binary_expression.right]
683 2 jondawson
            return function_call
684
        else:
685 4 jondawson
            return binary_expression
686 2 jondawson
 
687 4 jondawson
    def coerce_types(self, left, right):
688
 
689
        """
690
        Convert numeric types in expressions.
691
        """
692
 
693
        if left.type_() != right.type_():
694
            if left.type_() == "float" and right.type_() == "int":
695
                return left, IntToFloat(right)
696
            elif left.type_() == "int" and right.type_() == "float":
697
                return IntToFloat(left), right
698
            else:
699
                self.tokens.error("Incompatible types : %s %s"%(
700
                    left.type_(),
701
                    right.type_()))
702
 
703
        return left, right
704
 
705 2 jondawson
    def parse_binary_expression(self, operators):
706
        operator_precedence = {
707
                "|": ["^"],
708
                "^": ["&"],
709
                "&": ["==", "!="],
710
                "==": ["<", ">", "<=", ">="],
711
                "<": ["<<", ">>"],
712
                "<<": ["+", "-"],
713
                "+": ["*", "/", "%"],
714
        }
715
        if operators[0] not in operator_precedence:
716 4 jondawson
            left = self.parse_unary_expression()
717 2 jondawson
            while self.tokens.peek() in operators:
718
                operator = self.tokens.get()
719
                right = self.parse_unary_expression()
720 4 jondawson
                left, right = self.coerce_types(left, right)
721
                left = Binary(operator, left, right)
722
                left = self.substitute_function(left)
723
            return left
724 2 jondawson
        else:
725
            next_operators = operator_precedence[operators[0]]
726 4 jondawson
            left = self.parse_binary_expression(next_operators)
727 2 jondawson
            while self.tokens.peek() in operators:
728 4 jondawson
                operator = self.tokens.get()
729
                right = self.parse_binary_expression(next_operators)
730
                left, right = self.coerce_types(left, right)
731
                left = Binary(operator, left, right)
732
                left = self.substitute_function(left)
733
            return left
734 2 jondawson
 
735
    def parse_unary_expression(self):
736
        if self.tokens.peek() == "!":
737
            operator = self.tokens.get()
738
            expression = self.parse_postfix_expression()
739 4 jondawson
            return Binary("==", expression, Constant(0))
740 2 jondawson
        elif self.tokens.peek() == "-":
741
            operator = self.tokens.get()
742
            expression = self.parse_postfix_expression()
743 4 jondawson
            return Binary("-", Constant(0,
744
                expression.type_(),
745
                expression.size(),
746
                expression.signed()),
747
                expression)
748 2 jondawson
        elif self.tokens.peek() == "~":
749
            operator = self.tokens.get()
750
            expression = self.parse_postfix_expression()
751 4 jondawson
            return Unary("~", expression)
752 2 jondawson
        elif self.tokens.peek() == "sizeof":
753
            operator = self.tokens.get()
754
            expression = self.parse_unary_expression()
755
            return SizeOf(expression)
756
        else:
757
            return self.parse_postfix_expression()
758
 
759
    def parse_postfix_expression(self):
760
        expression = self.parse_paren_expression()
761
        while self.tokens.peek() in ["++", "--"]:
762
            operator = self.tokens.get()
763
            expression = PostIncrement(
764
                operator[:-1],
765 4 jondawson
                expression,
766 2 jondawson
                self.allocator
767
            )
768
        return expression
769
 
770
    def parse_paren_expression(self):
771
        if self.tokens.peek() == "(":
772
            self.tokens.expect("(")
773
            expression = self.parse_expression()
774
            self.tokens.expect(")")
775
        else:
776
            expression = self.parse_number_or_variable()
777
        return expression
778
 
779
    def parse_number_or_variable(self):
780
        if self.tokens.peek()[0].isalpha():
781
            name = self.tokens.get()
782
            if self.tokens.peek() == "(":
783
                return self.parse_function_call(name)
784
            else:
785
                return self.parse_variable(name)
786
        else:
787
            return self.parse_number()
788
 
789
    def parse_file_read(self):
790
        self.tokens.expect("(")
791
        file_name = self.tokens.get()
792
        file_name = file_name.strip('"').decode("string_escape")
793
        self.tokens.expect(")")
794
        return FileRead(file_name)
795
 
796
    def parse_file_write(self):
797
        self.tokens.expect("(")
798
        expression = self.parse_expression()
799
        self.tokens.expect(",")
800
        file_name = self.tokens.get()
801
        file_name = file_name.strip('"').decode("string_escape")
802
        self.tokens.expect(")")
803
        return FileWrite(file_name, expression)
804
 
805
    def parse_input(self, name):
806
        input_name = name.replace("input_", "")
807
        self.tokens.expect("(")
808
        self.tokens.expect(")")
809
        return Input(input_name)
810
 
811
    def parse_ready(self, name):
812
        input_name = name.replace("ready_", "")
813
        self.tokens.expect("(")
814
        self.tokens.expect(")")
815
        return Ready(input_name)
816
 
817
    def parse_output(self, name):
818
        output_name = name.replace("output_", "")
819
        self.tokens.expect("(")
820
        expression = self.parse_expression()
821
        self.tokens.expect(")")
822
        return Output(output_name, expression)
823
 
824
    def parse_function_call(self, name):
825
        if name.startswith("input_"):
826
            return self.parse_input(name)
827
        if name.startswith("ready_"):
828
            return self.parse_ready(name)
829
        if name.startswith("output_"):
830
            return self.parse_output(name)
831
        if name == "file_read":
832
            return self.parse_file_read()
833
        if name == "file_write":
834
            return self.parse_file_write()
835 4 jondawson
        if name not in self.scope:
836
            self.tokens.error("Unknown function: %s"%name)
837
        function = self.scope[name]
838
        function_call = FunctionCall(function)
839 2 jondawson
        function_call.arguments = []
840
        self.tokens.expect("(")
841
        while self.tokens.peek() != ")":
842
            function_call.arguments.append(self.parse_expression())
843
            if self.tokens.peek() == ",":
844
                self.tokens.expect(",")
845
            else:
846
                break
847
        self.tokens.expect(")")
848
 
849
 
850
        required_arguments = len(function_call.function.arguments)
851
        actual_arguments = len(function_call.arguments)
852
        if required_arguments != actual_arguments:
853
            self.tokens.error("Function %s takes %s arguments %s given."%(
854
                name,
855
                len(function_call.function.arguments),
856 4 jondawson
                len(function_call.arguments)))
857 2 jondawson
        required_arguments = function_call.function.arguments
858
        actual_arguments = function_call.arguments
859 4 jondawson
        corrected_arguments = []
860 2 jondawson
        for required, actual in zip(required_arguments, actual_arguments):
861 4 jondawson
            if not compatible(required, actual):
862
                if actual.type_() == "int" and required.type_() == "float":
863
                    actual = IntToFloat(actual)
864
                elif actual.type_() == "float" and required.type_() == "int":
865
                    actual = FloatToInt(actual)
866
                else:
867
                    self.tokens.error(
868
                        "type mismatch in assignment expected: %s actual: %s"%(
869
                            required.type_(),
870
                            actual.type_()))
871
            corrected_arguments.append(actual)
872
        function_call.arguments = corrected_arguments
873 2 jondawson
 
874
        return function_call
875
 
876
    def parse_number(self):
877
        token = self.tokens.get()
878 4 jondawson
        type_ = "int"
879 2 jondawson
        size = 2
880
        signed = True
881
        if token.startswith("'"):
882
            try:
883
                token = eval(token)
884
                value = ord(token)
885
            except SyntaxError:
886
                self.tokens.error("%s is not a character literal"%token)
887
        elif token.startswith('"'):
888
            try:
889
                initializer = [ord(i) for i in token.strip('"').decode("string_escape")] + [0]
890
                size = len(initializer)
891
                initialize_memory = self.initialize_memory
892
                declaration = ArrayDeclaration(
893 4 jondawson
                    self.allocator,
894
                    size,
895
                    "int[]",
896
                    "int",
897
                    2,
898
                    False,
899
                    initializer,
900 2 jondawson
                    self.initialize_memory)
901 4 jondawson
                return ConstArray(declaration.instance())
902 2 jondawson
            except SyntaxError:
903
                self.tokens.error("%s is not a character literal"%token)
904 4 jondawson
        elif "." in token:
905
            #float literal
906
            try:
907
                type_ = "float"
908
                signed = True
909
                size = 4
910
                token = token.upper().replace("F", "")
911
                token = token.upper().replace("L", "")
912
                value = float(eval(token))
913
 
914
                try:
915
                    byte_value = struct.pack(">f", value)
916
                except OverflowError:
917
                    self.tokens.error("value too large")
918
 
919
            except SyntaxError:
920
                self.tokens.error("%s is not a floating point literal"%token)
921 2 jondawson
        else:
922 4 jondawson
            #integer literal
923 2 jondawson
            try:
924
                if "U" in token.upper():
925
                    signed = False
926
                if "L" in token.upper():
927
                    size = 4
928
                token = token.upper().replace("U", "")
929
                value = int(eval(token))
930
 
931
                if signed:
932
                    if value > 2**((size * 8)-1) - 1:
933
                        self.tokens.error("value too large")
934
                    if value < -(2**((size * 8)-1)):
935
                        self.tokens.error("value too small")
936
                else:
937
                    if value > 2**(size * 8) - 1:
938
                        self.tokens.error("value too large")
939
                    if value < 0:
940
                        self.tokens.error("value too small")
941
 
942
            except SyntaxError:
943
                self.tokens.error("%s is not an integer literal"%token)
944
 
945 4 jondawson
        return Constant(value, type_, size, signed)
946
 
947 2 jondawson
    def parse_variable(self, name):
948
        if name not in self.scope:
949
            self.tokens.error("Unknown variable: %s"%name)
950
        instance = self.scope[name]
951
        return self.parse_variable_array_struct(instance)
952 4 jondawson
 
953 2 jondawson
    def parse_variable_array_struct(self, instance):
954 4 jondawson
        if instance.type_() in numeric_types:
955
 
956
            if not hasattr(instance, "reference"):
957
 
958
                self.tokens.error(
959
                    "Not an expression")
960
 
961
            return Variable(instance)
962
        elif instance.type_().endswith("[]"):
963 2 jondawson
            if self.tokens.peek() == "[":
964
                self.tokens.expect("[")
965
                index_expression = self.parse_expression()
966
                self.tokens.expect("]")
967 4 jondawson
                if index_expression.type_() not in ["int"]:
968
 
969 2 jondawson
                    self.tokens.error(
970 4 jondawson
                        "Array indices must be an integer like expression")
971
 
972
                return ArrayIndex(instance, index_expression)
973 2 jondawson
            else:
974 4 jondawson
                return Array(instance)
975
        elif instance.type_().startswith("struct"):
976
            if self.tokens.peek() == ".":
977
                self.tokens.expect(".")
978
                member = self.tokens.get()
979
                instance = instance.members[member]
980
                return self.parse_variable_array_struct(instance)
981
            else:
982
                return Struct(instance)
983 2 jondawson
 
984
def compatible(left, right):
985 4 jondawson
    return left.type_() == right.type_()

powered by: WebSVN 2.1.0

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