1 # Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
2 # Copyright (c) 2009 The Hewlett-Packard Development Company
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met: redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer;
9 # redistributions in binary form must reproduce the above copyright
10 # notice, this list of conditions and the following disclaimer in the
11 # documentation and/or other materials provided with the distribution;
12 # neither the name of the copyright holders nor the names of its
13 # contributors may be used to endorse or promote products derived from
14 # this software without specific prior written permission.
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 from slicc
.ast
.ExprAST
import ExprAST
31 from slicc
.symbols
import Type
33 class ChipComponentAccessAST(ExprAST
):
34 def __init__(self
, slicc
, machine
, mach_version
, component
):
35 super(ChipComponentAccessAST
, self
).__init
__(slicc
)
36 self
.mach_var
= machine
37 self
.comp_var
= component
38 self
.mach_ver_expr
= mach_version
41 return "[ChipAccessExpr: %r]" % self
.expr_vec
43 def generate(self
, code
):
44 void_type
= self
.symtab
.find("void", Type
)
46 mname
= self
.mach_var
.name
47 cname
= self
.comp_var
.name
48 var
= self
.symtab
.machine_components
[mname
][cname
]
52 if self
.chip_ver_expr
is not None:
53 # replace self.chip with specified chip
54 gcode
= "g_system.getChip(%s)" % self
.chip_ver_expr
.inline()
55 vcode
= re
.sub("m_chip", gcode
, vcode
)
57 # replace default "m_version" with the version we really want
58 gcode
= "(%s)" % self
.mach_ver_expr
.inline()
59 vcode
= re
.sub("m_version", gcode
, vcode
)
61 return_type
, gcode
= self
.generate_access(var
)
62 code("($vcode)$gcode")
65 class ChipMethodAccessAST(ChipComponentAccessAST
):
66 def __init__(self
, slicc
, chip_version
, machine
, mach_version
, component
,
68 s
= super(ChipMethodAccessAST
, self
)
69 s
.__init
__(slicc
, machine
, mach_version
, component
)
71 self
.chip_ver_expr
= chip_version
72 self
.expr_vec
= expr_vec
73 self
.proc_name
= proc_name
75 def generate_access(self
, var
):
79 for expr
in self
.expr_vec
:
84 methodId
= var
.type.methodId(self
.proc_name
, paramTypes
)
86 # Verify that this is a method of the object
87 if not var
.type.methodExist(methodId
):
88 self
.error("%s: Type '%s' does not have a method '%s'" % \
89 ("Invalid method call", var
.type, methodId
))
91 expected_size
= len(var
.type.methodParamType(methodId
))
92 if len(self
.expr_vec
) != expected_size
:
93 # Right number of parameters
94 self
.error("Wrong number of parameters for function name: " +\
95 "'%s', expected: %d, actual: %d",
96 self
.proc_name
, expected_size
, len(self
.expr_vec
))
98 for expr
,expected
,actual
in zip(self
.expr_vec
,
99 var
.type.methodParamType(methodId
),
101 # Check the types of the parameter
102 if actual
!= expected
:
103 expr
.error("Type mismatch: expected: %s actual: %s",
107 code
= ".%s(%s)" % (self
.proc_name
, ', '.join(gcode
))
109 # Return the return type of the method
110 return var
.type.methodReturnType(methodId
), code
112 class LocalChipMethodAST(ChipMethodAccessAST
):
113 # method call from local chip
114 def __init__(self
, slicc
, machine
, mach_version
, component
, proc_name
,
116 s
= super(LocalChipMethodAST
, self
)
117 s
.__init
__(slicc
, None, machine
, mach_version
, component
, proc_name
,
120 class SpecifiedChipMethodAST(ChipMethodAccessAST
):
121 # method call from specified chip
122 def __init__(self
, slicc
, chip_version
, machine
, mach_version
, component
,
123 proc_name
, expr_vec
):
124 s
= super(SpecifiedChipMethodAST
, self
)
125 s
.__init
__(slicc
, chip_version
, machine
, mach_version
, component
,
128 class ChipMemberAccessAST(ChipComponentAccessAST
):
129 # member access from specified chip
130 def __init__(self
, chip_version
, machine
, mach_version
, component
,
132 s
= super(ChipMemberAccessAST
, self
)
133 s
.__init
__(slicc
, machine
, mach_version
, component
)
135 self
.chip_ver_expr
= chip_version
136 self
.field_name
= field_name
138 def generate_access(self
, var
):
139 # Verify that this is a valid field name for this type
140 if not var
.type.dataMemberExist(self
.field_name
):
141 self
.error("Invalid object field: " +\
142 "Type '%s' does not have data member %s",
143 var
.type, self
.field_name
)
145 code
+= ").m_%s" % self
.field_name
147 return var
.type.dataMemberType(self
.field_name
), code
149 class LocalChipMemberAST(ChipMemberAccessAST
):
150 # member access from local chip
151 def __init__(self
, slicc
, machine
, mach_version
, component
, field_name
):
152 s
= super(LocalChipMemberAST
, self
)
153 s
.__init
__(slicc
, None, machine
, mach_version
, component
, field_name
)
155 class SpecifiedChipMemberAST(ChipMemberAccessAST
):
156 # member access from specified chip
157 def __init__(self
, chip_version
, machine
, mach_version
, component
,
159 s
= super(SpecifiedChipMemberAST
, self
)
160 s
.__init
__(slicc
, chip_version
, machine
, mach_version
, component
,