예제 #1
0
def c_CLASS_DEFINITION(child, file, tabs=""):
    # 0: identifier; 1: superclass; 2: suite

    global in_class
    global superclass
    global current_class
    global overloads
    in_class = True
    current_class = child[0]
    if current_class in overloads:
        print >> sys.stderr, "Error in 'cspy_translate.py':\n" + \
              "The class '" + current_class + "' has already been defined."
        remove_files()

    # new dictionary element
    overloads[current_class] = {}

    file.write(tabs + "class " + child[0])
    if child[1].label != "EMPTY":
        superclass = child[1][0]
        try:
            superclass = replace[superclass]
        except:
            pass
        file.write("(" + superclass + ")")
    file.write(":\n")
    advance(child)

    toPython(child[2], file, tabs+"\t")
    in_class = False
    current_class = ""
    superclass = None
예제 #2
0
def translate(parsetree, filename, orig_path,
              import_overloads = {'global' : {}}):

    global path
    global overloads
    global file_name
    path = orig_path

    overloads = import_overloads

    # RETRIEVE FILE NAME
    find_path = re.compile('(?P<p>[\S]+)/(?P<n>[\S]+).cspy')
    found_path = find_path.search(filename)
    if found_path:
        filename = found_path.group("n") + ".py"
    else:
        filename = filename[:len(filename)-5] + ".py"

    file_name = filename

    # TRANSLATE
    try:
        the_file = open(tmp_path + filename, "w+")
        toPython(parsetree, the_file)            # translate parse tree
        the_file.close()
        export_map(filename)                     # write line map file
    except IOError:
        print >> sys.stderr, "Can't translate " + tmp_path + str(filename) + \
            " due to IOError."
        remove_files()
        sys.exit(1)

    return overloads
예제 #3
0
def c_CONSTRUCTOR_CALL(child, file, tabs=""):
    # 0: identifier; 1: expression list

    if child[0].label == "MEMBER":
        # x = alpha.A() => x = alpha.A(alpha.A.A,)
        var = child[0][0][0] + "." + child[0][1]
    else:
        var = child[0][0]

    file.write(var + "(" + var + ".")           # calls hidden Python __init__
    
    # CALL USER-DEFINED CONSTRUCTOR
    node = child
    while(node.label != "FILE"):
        node = node.parent
    if child[0].label == "MEMBER":
        var_methods = child[0].type
        if type(var_methods) == list:         # overloaded constructor
            name = "_" + child[0][1]          # prepenhd _
            args = child[1].flatten("EXPRESSIONLIST_SINGLE")
            for arg in args:                  # append arg types
                name += "_" + arg[0].type.type_str
            file.write(name)
        else:
            file.write(child[0][1])
    else:
        var_methods = node.env[var].methods

        if var not in var_methods:
            result = "\nCSPy : Constructor Error\n"
            result += "File: " + file_name + "\n"
            column = child.column
            endColumn = child.endColumn
            line = child.line

            result += "Line " + str(child.lineNum) + ", Column " + \
                str(child.column) + ":\n"

            result += line + "\n"

            result += " " * (column - 1)
            result += "^" * (endColumn - column + 1)
            result += "\n"

            result += "The class '" + var + "' does not have a constructor.\n"

            print >> sys.stderr, result
            remove_files()

        if type(var_methods[var]) == list:     # overloaded constructor
            file.write(overload_name(child, "call"))
        else:
            toPython(child[0], file, tabs)
    file.write(",")
    toPython(child[1], file, tabs)
    file.write(")")
예제 #4
0
def c_PROCEDURE_DEFINITION(child, file, tabs=""):
    # 0: identifier; 1: arg list; 2: suite

    global overloads

    if (type(child.lookup_var(child[0])) == list and
        child[0] not in builtins):                    # overloaded function
        name = overload_name(child, "def")

        if in_class:
            if name in overloads[current_class]:
                print >> sys.stderr, "Error in 'cspy_translate.py':\n" + \
                      "Procedure '" + name + "' was already defined as an " + \
                      "overloaded Python procedure."
                remove_files()

            overloads[current_class][name] = child[0]

        else:
            if name in overloads['global']:
                print >> sys.stderr, "Error in 'cspy_translate.py':\n" + \
                      "Procedure '" + name + "' was already defined as an " + \
                      "overloaded Python procedure."
                remove_files()

            overloads['global'][name] = child[0]

    else:
        name = child[0]

    file.write(tabs + "def " + name + "(")

    if in_class:
        file.write("self, ")
    toPython(child[1], file, tabs)
    file.write("):\n")
    advance(child)

    toPython(child[2], file, tabs+"\t")
예제 #5
0
def pyimportgenerate(hfile, path):

    # LEX AND PARSE THE FILE
    filename = hfile
    if not os.path.isfile(path + hfile):
        script_path = os.path.realpath(__file__)
        if os.path.isfile(script_path + "/cspy_headers/" + hfile):
            # found header in cspy_headers folder
            try:
                hfile = open(script_path + "/cspy_headers/" + hfile,
                             'rU').read() + "\n"
            except:
                print >> sys.stderr, "Header file '" + script_path + \
                    "/cspy_headers/" + hfile + "' could not be read."
                exit()
        print >> sys.stderr, "Header file '" + path + hfile + \
            "' could not be found."
        exit()
    try:
        hfile = open(path + hfile, 'rU').read() + "\n"
    except:
        print >> sys.stderr, "Header file '" + path + hfile + \
            "' could not be read."
        exit()

    lexer = lex.lex()
    lexer.indentwith = None
    lexer.indentedline = None
    lexer.indentstack = [0]
    lexer.input(hfile)

    parser = yacc.yacc(tabmodule="header_parsetab")
    lexer.parser = parser
    parsetree = parser.parse(tracking=True)

    if parsetree:
        parsetree.set_column_num(hfile)
    else:
        remove_files()
        exit(1)

    # GET IMPORTED FILES
    imports = parsetree.flatten("IMPORTBLOCK_SINGLE")

    name = filename[:len(filename) - 5]

    tmp_path = "/tmp/" + getpass.getuser()

    # Make the folder in the tmp directory if it does not exist
    try:
        os.stat(tmp_path)
    except:
        os.mkdir(tmp_path)

    # SAVE FILE NAME
    # F = open(tmp_path + "/__import_names.txt", "a")
    # F.write(name + "\n")
    # F.close()

    if len(filename) <= 5:
        print >> sys.stderr, "Compiler error in cspy_pyimport.py:\nTried " + \
            "to import a non-cspyh file."
        exit(1)

    pyfilename = filename[:-6] + ".py"

    File = None

    # NO FILES IMPORTED
    if not imports:

        # PROCESS SELF
        generate_environments(parsetree)  # add environments
        det_type(parsetree)  # determine any remaining types

        return parsetree

    # FILES IMPORTED
    for statement in imports:

        # PROCESS IMPORTS
        statement = statement[0]
        importtype = statement.label

        # imports must be python files with cspyh headers
        importfile = statement[0] + ".cspyh"
        importtree = pyimportgenerate(importfile, path)

        # ADD IMPORTED CODE TO PARSE TREE

        # pyimport simple : pyimport module
        if importtype == "PYIMPORT_SIMPLE":
            importmodule = type_obj("import module",
                                    builtins["ImportModule"],
                                    methods=importtree.env)
            parsetree.initiate_var(statement[0], importmodule)

        # pyimport alias : pyimport module as id
        elif importtype == "PYIMPORT_ALIAS":
            alias = statement[1]
            importmodule = type_obj("import module",
                                    builtins["ImportModule"],
                                    methods=importtree.env)
            parsetree.initiate_var(alias, importmodule)

        # pyimport bulk : from module pyimport *
        elif importtype == "PYIMPORT_BULK":
            for variable in importtree.env:
                parsetree.initate_var(variable, importtree.env[variable])

        # pyimport discrete : from module pyimport id1, id2, ...
        elif importtype == "PYIMPORT_DISCRETE":
            importids = statement.flatten("IMPORTLIST_SIMPLE")
            for identifier in importids:
                name = identifier[0]
                value = importtree.lookup(name)
                parsetree.initiate_var(name, value)

        else:
            # Should never reach this point
            print >> sys.stderr, "\nCompiler error with imports in " + \
                "cspy_pyimport.py.\nNo import type matched"

    # PROCESS SELF
    generate_environments(parsetree)  # add environments
    det_type(parsetree)  # determine any remaining types
    return parsetree