コード例 #1
0
ファイル: typechecker.py プロジェクト: thurn/cs444-compiler
def method_invocation(element):
    if element[0].tag == "name":
        name = name_to_str(element.find("name"))
        to_file(element)
        declaration_site = element.env.get_declaration_site_for_method_name(
            name,
            argument_list(element))
        element.attrib["type"] = element.env.get_type_for_declaration_site(
            declaration_site)
        element.declaration = declaration_site
    elif element[0].tag == "primary":
        primary_type = element[0].attrib["type"]
        error_if(is_primitive(primary_type),
              "Cannot invoke method on primitive " + primary_type)
        declaration_site = element.env.get_declaration_site_for_class_name(
            primary_type)
        identifier = element.find("tok_identifier").text
        method_declaration = \
            declaration_site.env.get_declaration_site_for_method_name(
            identifier,
            argument_list(element))
        element.attrib["type"] = \
            method_declaration.env.get_type_for_declaration_site(
            method_declaration)
        element.declaration = method_declaration
    else:
        assert False
コード例 #2
0
ファイル: generate.py プロジェクト: thurn/cs444-compiler
def check_and_generate(files):
    init_globals()  # reset global state
    try:
        out = open("output/out.s", "w")

        trees = typechecker.check_files(files)
        initializer_list = []

        mega_vtable_offset = 1
        type_tag = 0
        string_literal_index = 0
        for tree in trees:
            clazz = find_type_decl(tree)
            clazz.type_tag = type_tag
            method_list.class_list += [clazz]
            type_tag += 1
            methods = (
                tree.findall(".//method")
                + tree.findall(".//constructor_declaration")
                + tree.findall(".//abstract_method")
            )
            for method in methods:
                method.mega_vtable_offset = mega_vtable_offset
                mega_vtable_offset += 1
                method_list.method_list += [method]
                if "static" in modifiers(method):
                    slot = -2
                else:
                    slot = -3
                for param in method.findall(".//param"):
                    param.slot = slot
                    slot -= 1

            counters.mega_vtable_members = mega_vtable_offset

            for string_literal in tree.findall(".//string_literal"):
                string_literal.index = string_literal_index
                string_literal_index += 1

        out.write(instanceof_table(trees))

        for tree in trees:
            CurrentFile.name = tree.filename
            CurrentFile.mangled_name = CurrentFile.name.replace(".", "_").replace("$", "_").replace("/", "_")
            CurrentFile.static_slot = 0

            for this in tree.findall(".//tok_this"):
                this.slot = -2

            generate(tree)
            to_file(tree, tree.filename + ".xml")

            out.write("section .data\n")
            for clazz in tree.findall(".//class"):
                out.write(mega_vtable_for_class(clazz))

            out.write("section .text\n")
            initializer_name = "static_init_" + CurrentFile.mangled_name
            out.write(
                """
; global {initializer_name}
{initializer_name}:
push ebp
mov ebp, esp
sub esp, {frame_size}
""".format(
                    initializer_name=initializer_name, frame_size=CurrentFile.static_slot * 4
                )
            )
            initializer_list.append(initializer_name)

            for field in tree.findall(".//field"):
                if "static" in modifiers(field):
                    mangled_name = mangle_field_name(field)
                    out.write(
                        """
; initializing {mangled_name}
{field_assembly}
mov eax, {mangled_name}
mov ebx, {assigned_value}
mov DWORD [eax], ebx
""".format(
                            mangled_name=mangled_name,
                            field_assembly=field.assembly,
                            assigned_value=stack_slot_to_operand(field.slot),
                        )
                    )

            out.write(
                """
leave
ret
; done global static initialization
"""
            )

            for constructor in tree.findall(".//constructor_declaration"):
                out.write(constructor.assembly + "\n")

            for method in tree.findall(".//method"):
                if method.find("block") is not None:
                    out.write(method.assembly + "\n")

            out.write("\nsection .data\n")
            for string_literal in tree.findall(".//string_literal"):
                string_value = string_literal.get("value")
                expanded_value = expand_string_literal(string_value)
                out.write("\n; string literal " + string_value + "\n")
                out.write("__string_literal_" + str(string_literal.index) + ":\n")
                out.write("dd _vtable_java_lang_$Array_ ; vtable pointer\n")
                out.write("dd -3 ; type tag for char\n")
                out.write("dd " + str(len(expanded_value)) + " ; string length\n")
                for character in expanded_value:
                    out.write("dd " + str(hex(ord(character))) + "\n")
                out.write("")

            out.write("\nsection .bss\n")
            for field in tree.findall(".//field"):
                if "static" in modifiers(field):
                    mangled_name = mangle_field_name(field)
                    out.write("""{mangled_name} resb 4""".format(mangled_name=mangled_name) + "\n")

        out.write("section .text\n")
        out.write("; prelude\n")
        out.write("extern __malloc\n")
        out.write("extern __debexit\n")
        out.write("extern __exception\n")
        out.write("extern NATIVEjava.io.OutputStream.nativeWrite\n")
        out.write("global _start\n")
        out.write("_start:\n")
        out.write("call install_segv_handler\n")

        for initializer in initializer_list:
            out.write("call " + initializer + "\n")

        class_name = mangle_class_name(find_type_decl(trees[1]).get("canonical_name"))
        out.write("call " + class_name + "test_\n")
        out.write("mov ebx, eax\n")
        out.write("mov eax, 1\n")
        out.write("int 0x80 ; invoke exit(1)\n")
        out.write("; end prelude\n")
        out.write(
            """
%define __NR_signal 48
%define SIGSEGV     11
global install_segv_handler
install_segv_handler:
  mov eax, __NR_signal
  mov ebx, SIGSEGV
  mov ecx, __exception
  int 0x80
  ret
"""
        )

        return 0
    except JoosSyntaxException, e:
        if Testing.testing:
            return 42
        else:
            out.write("\n" + e.msg + "\n")
            raise