Beispiel #1
0
def check_and_register(local_def, table):
    stypes = dict({
        "p_var_def": "def",
        "p_fpar_def": "arg",
        "p_func_def": "func",
        "p_func_decl": "decl",
    })

    register = dict({
        "p_var_def": table.extend_defs,
        "p_fpar_def": table.extend_args,
        "p_func_def": table.extend_funcs,
        "p_func_decl": table.extend_decls,
    })
    symbols = None

    stype = stypes[local_def.name]
    if stype in ["func", "decl"]:
        symbols = [get_function_symbol(local_def)]

    elif stype in ["def", "arg"]:
        names = map(lambda name: name.value, local_def.find_all("p_name"))
        symbols = [Symbol(name, get_type(local_def)) for name in names]

    # Check for conflicts before registering the new symbols
    for name in map(lambda symbol: symbol.name, symbols):
        table.check_conflicts(local_def.linespan, name, stype)

    register[local_def.name](symbols)
Beispiel #2
0
 def verify_labeled(self, d_stmt, table):
     """Verifies a labeled (cont/break) statement against a symbol table"""
     d_label = d_stmt.find_first("p_name")
     if d_label:
         self.label = d_label.value
         table.check_table(d_stmt.linespan,
                           Symbol(self.label, DanaType("label")))
Beispiel #3
0
def irgen_def(module, function, table):

    # We have a variety of options on how to access variables from
    # upper scopes; the solution we choose is the one of llvm-gcc -
    # pass the needed variables as arguments (llvm-gcc passes a struct,
    # but that is not a big difference)
    extra_args = list(function.table.referenced)
    extra_types = list(function.table[arg] for arg in extra_args)

    # All items from outer scopes are passed by reference
    for extra_type in extra_types:
        if not extra_type.is_array and not extra_type.is_pointer:
            extra_type.is_ref = True

    function.symbol.type.args += extra_types
    function.table.extend_args(
        [Symbol(arg, t) for arg, t in zip(extra_args, extra_types)])

    func = irgen_decl(module, function.symbol, function.mangled, table)

    # Get all upper-scoped variables, turn arrays to pointers
    dtype = function.mangled.type
    argtypes = [function.table[arg] for arg in extra_args]
    dtype.args += argtypes

    # Name the arguments for more readable IR (at least at first)
    for arg, name in zip(func.args, function.args + extra_args):
        arg.name = name

    # Fix the incomplete entry
    mangled = function.mangled.name
    table.funcs[mangled] = irtable.FuncInfo(func, extra_args)
    table.current = mangled

    return func
Beispiel #4
0
def produce_program(main_function):
    global_table = Table()
    global_table.function = Symbol(None, DanaType("void"))
    global_table.extend_funcs(builtins)

    return produce_function(main_function,
                            global_table=global_table,
                            is_main=True)
Beispiel #5
0
    def verify_call(self, d_stmt, table):
        """Verifies a proc call statement against a symbol table"""
        d_exprs = d_stmt.find_all("p_expr")

        proc_name = d_stmt.find_first("p_name").value
        self.value = proc_name

        exprs = [DanaExpr.factory(d_expr, table) for d_expr in d_exprs]
        self.exprs = exprs

        actual = DanaType("void", args=[expr.type for expr in exprs])
        table.check_table(d_stmt.linespan, Symbol(proc_name, actual))
Beispiel #6
0
def get_function_symbol(d_function, is_main=False):
    """Get the name, type, and argument types of a function"""
    d_header = d_function.find_first("p_header")

    # If this is the program and not just a function, set the name accordingly
    name = d_header.find_first("p_name").value
    if is_main:
        name = "main"

    d_type = d_header.find_first("p_maybe_data_type").find_first("p_data_type")
    base = d_type.value if d_type else "void"

    args = []
    fpars = d_header.find_all("p_fpar_def")
    for fpar in fpars:
        ftype = get_type(fpar.find_first("p_fpar_type"))
        args += [ftype] * len(fpar.find_all("p_name"))

    return Symbol(name, DanaType(base, args=args))
Beispiel #7
0
import sys
from copy import copy
from compiler.semantic.type import DanaType
from compiler.semantic.table import Table, Symbol
from compiler.semantic.func import DanaFunction
from compiler.semantic.block import DanaContainer

builtins = [
    Symbol("writeInteger", DanaType("void", args=[DanaType("int")])),
    Symbol("writeByte", DanaType("void", args=[DanaType("byte")])),
    Symbol("writeChar", DanaType("void", args=[DanaType("byte")])),
    Symbol("writeString", DanaType("void", args=[DanaType("byte", pdepth=1)])),
    Symbol("readInteger", DanaType("int", args=[])),
    Symbol("readByte", DanaType("byte", args=[])),
    Symbol("readChar", DanaType("byte", args=[])),
    Symbol(
        "readString",
        DanaType("void", args=[DanaType("int"),
                               DanaType("byte", pdepth=1)])),
    Symbol("strlen", DanaType("int", args=[DanaType("byte", pdepth=1)])),
    Symbol(
        "strcmp",
        DanaType("int",
                 args=[DanaType("byte", pdepth=1),
                       DanaType("byte", pdepth=1)])),
    Symbol(
        "strcat",
        DanaType("byte",
                 pdepth=1,
                 args=[DanaType("byte", pdepth=1),
                       DanaType("byte", pdepth=1)])),
Beispiel #8
0
    def mangled(self):
        name = self.symbol.name
        if self.parent:
            name = self.parent.mangled.name + "$" + self.symbol.name

        return Symbol(name, self.symbol.type)