2278363015
This is simply a translation of the C++ slicc into python with very minimal reorganization of the code. The output can be verified as nearly identical by doing a "diff -wBur". Slicc can easily be run manually by using util/slicc
162 lines
6.6 KiB
Python
162 lines
6.6 KiB
Python
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
|
# Copyright (c) 2009 The Hewlett-Packard Development Company
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are
|
|
# met: redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer;
|
|
# redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution;
|
|
# neither the name of the copyright holders nor the names of its
|
|
# contributors may be used to endorse or promote products derived from
|
|
# this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
import re
|
|
|
|
from slicc.ast.ExprAST import ExprAST
|
|
from slicc.symbols import Type
|
|
|
|
class ChipComponentAccessAST(ExprAST):
|
|
def __init__(self, slicc, machine, mach_version, component):
|
|
super(ChipComponentAccessAST, self).__init__(slicc)
|
|
self.mach_var = machine
|
|
self.comp_var = component
|
|
self.mach_ver_expr = mach_version
|
|
|
|
def __repr__(self):
|
|
return "[ChipAccessExpr: %r]" % self.expr_vec
|
|
|
|
def generate(self, code):
|
|
void_type = self.symtab.find("void", Type)
|
|
|
|
mname = self.mach_var.name
|
|
cname = self.comp_var.name
|
|
var = self.symtab.machine_components[mname][cname]
|
|
|
|
vcode = str(var.code)
|
|
|
|
if self.chip_ver_expr is not None:
|
|
# replace self.chip with specified chip
|
|
gcode = "g_system.getChip(%s)" % self.chip_ver_expr.inline()
|
|
vcode = re.sub("m_chip", gcode, vcode)
|
|
|
|
# replace default "m_version" with the version we really want
|
|
gcode = "(%s)" % self.mach_ver_expr.inline()
|
|
vcode = re.sub("m_version", gcode, vcode)
|
|
|
|
return_type, gcode = self.generate_access(var)
|
|
code("($vcode)$gcode")
|
|
return return_type
|
|
|
|
class ChipMethodAccessAST(ChipComponentAccessAST):
|
|
def __init__(self, slicc, chip_version, machine, mach_version, component,
|
|
proc_name, expr_vec):
|
|
s = super(ChipMethodAccessAST, self)
|
|
s.__init__(slicc, machine, mach_version, component)
|
|
|
|
self.chip_ver_expr = chip_version
|
|
self.expr_vec = expr_vec
|
|
self.proc_name = proc_name
|
|
|
|
def generate_access(self, var):
|
|
# generate code
|
|
paramTypes = []
|
|
gcode = []
|
|
for expr in self.expr_vec:
|
|
t,c = expr.generate()
|
|
paramTypes.append(t)
|
|
gcode.append(c)
|
|
|
|
methodId = var.type.methodId(self.proc_name, paramTypes)
|
|
|
|
# Verify that this is a method of the object
|
|
if not var.type.methodExist(methodId):
|
|
error("%s: Type '%s' does not have a method '%s'" % \
|
|
("Invalid method call", var.type, methodId))
|
|
|
|
expected_size = len(var.type.methodParamType(methodId))
|
|
if len(self.expr_vec) != expected_size:
|
|
# Right number of parameters
|
|
self.error("Wrong number of parameters for function name: " +\
|
|
"'%s', expected: %d, actual: %d",
|
|
self.proc_name, expected_size, len(self.expr_vec))
|
|
|
|
for expr,expected,actual in zip(self.expr_vec,
|
|
var.type.methodParamType(methodId),
|
|
paramTypes):
|
|
# Check the types of the parameter
|
|
if actual != expected:
|
|
expr.error("Type mismatch: expected: %s actual: %s",
|
|
expected, actual)
|
|
|
|
# method call
|
|
code = ".%s(%s)" % (self.proc_name, ', '.join(gcode))
|
|
|
|
# Return the return type of the method
|
|
return var.type.methodReturnType(methodId), code
|
|
|
|
class LocalChipMethodAST(ChipMethodAccessAST):
|
|
# method call from local chip
|
|
def __init__(self, slicc, machine, mach_version, component, proc_name,
|
|
expr_vec):
|
|
s = super(LocalChipMethodAST, self)
|
|
s.__init__(slicc, None, machine, mach_version, component, proc_name,
|
|
expr_vec)
|
|
|
|
class SpecifiedChipMethodAST(ChipMethodAccessAST):
|
|
# method call from specified chip
|
|
def __init__(self, slicc, chip_version, machine, mach_version, component,
|
|
proc_name, expr_vec):
|
|
s = super(SpecifiedChipMethodAST, self)
|
|
s.__init__(slicc, chip_version, machine, mach_version, component,
|
|
proc_name, expr_vec)
|
|
|
|
class ChipMemberAccessAST(ChipComponentAccessAST):
|
|
# member access from specified chip
|
|
def __init__(self, chip_version, machine, mach_version, component,
|
|
field_name):
|
|
s = super(ChipMemberAccessAST, self)
|
|
s.__init__(slicc, machine, mach_version, component)
|
|
|
|
self.chip_ver_expr = chip_version
|
|
self.field_name = field_name
|
|
|
|
def generate_access(self, var):
|
|
# Verify that this is a valid field name for this type
|
|
if not var.type.dataMemberExist(self.field_name):
|
|
self.error("Invalid object field: " +\
|
|
"Type '%s' does not have data member %s",
|
|
var.type, self.field_name)
|
|
|
|
code += ").m_%s" % self.field_name
|
|
|
|
return var.type.dataMemberType(self.field_name), code
|
|
|
|
class LocalChipMemberAST(ChipMemberAccessAST):
|
|
# member access from local chip
|
|
def __init__(self, slicc, machine, mach_version, component, field_name):
|
|
s = super(LocalChipMemberAST, self)
|
|
s.__init__(slicc, None, machine, mach_version, component, field_name)
|
|
|
|
class SpecifiedChipMemberAST(ChipMemberAccessAST):
|
|
# member access from specified chip
|
|
def __init__(self, chip_version, machine, mach_version, component,
|
|
field_name):
|
|
s = super(SpecifiedChipMemberAST, self)
|
|
s.__init__(slicc, chip_version, machine, mach_version, component,
|
|
field_name)
|